示例#1
0
class _PhotonSpectrumResultOptionsToolItem(_ResultToolItem):
    def _initUI(self):
        # Widgets
        self._chk_total = QCheckBox("Show total intensity")
        self._chk_total.setChecked(True)

        self._chk_background = QCheckBox("Show background intensity")
        self._chk_background.setChecked(False)

        self._chk_errorbar = QCheckBox("Show error bars")
        self._chk_errorbar.setChecked(True)

        # Layouts
        layout = _ResultToolItem._initUI(self)
        layout.addRow(self._chk_total)
        layout.addRow(self._chk_background)
        layout.addRow(self._chk_errorbar)

        # Signals
        self._chk_total.stateChanged.connect(self.stateChanged)
        self._chk_background.stateChanged.connect(self.stateChanged)
        self._chk_errorbar.stateChanged.connect(self.stateChanged)

        return layout

    def isTotal(self):
        return self._chk_total.isChecked()

    def isBackground(self):
        return self._chk_background.isChecked()

    def isErrorbar(self):
        return self._chk_errorbar.isChecked()
示例#2
0
class CheckinConfirmation(QDialog):
    def __init__(self, parent, venue):
        super(CheckinConfirmation, self).__init__(parent)
        self.setWindowTitle("Checkin")
        self.centralWidget = QWidget()

        #Main Layout
        layout = QGridLayout()
        #layout.setSpacing(0)
        self.setLayout(layout)


        text = "You're checking in @<b>" + venue['name'] + "</b>"
        if 'address' in venue['location']:
            text += ", " + venue['location']['address']
        text += "."
        textLabel = QLabel(text, self)
        textLabel.setWordWrap(True)

        okButton = QPushButton("Ok")
        self.connect(okButton, SIGNAL("clicked()"), self.accept)
        cancelButton = QPushButton("Cancel")
        self.connect(cancelButton, SIGNAL("clicked()"), self.reject)

        # TODO: make this a separate widget
        #----
        self.tw = QCheckBox("Twitter")
        self.fb = QCheckBox("Facebook")

        broadcast = foursquare.config_get("broadcast")
        if broadcast:
            if not ", " in broadcast:
                self.tw.setChecked("twitter" in broadcast)
                self.fb.setChecked("facebook" in broadcast)
        #----

        layout.addWidget(textLabel, 0, 0, 1, 3)
        layout.addWidget(self.tw, 1, 0)
        layout.addWidget(self.fb, 1, 1)
        layout.addWidget(okButton, 1, 2)
        #layout.addWidget(cancelButton, 1, 1)

    def broadcast(self):
        broadcast = "public"
        if self.tw.isChecked():
            broadcast += ",twitter"
        if self.fb.isChecked():
            broadcast += ",facebook"
示例#3
0
class qLabeledCheck(QWidget): 
    def __init__(self, name, arg_dict, pos = "side", max_size = 200):
        QWidget.__init__(self)
        self.setContentsMargins(1, 1, 1, 1)
        if pos == "side":
            self.layout1=QHBoxLayout()
        else:
            self.layout1 = QVBoxLayout()
        self.layout1.setContentsMargins(1, 1, 1, 1)
        self.layout1.setSpacing(1)
        self.setLayout(self.layout1)
        self.cbox = QCheckBox()
        # self.efield.setMaximumWidth(max_size)
        self.cbox.setFont(QFont('SansSerif', 12))
        self.label = QLabel(name)
        # self.label.setAlignment(Qt.AlignLeft)
        self.label.setFont(QFont('SansSerif', 12))
        self.layout1.addWidget(self.label)
        self.layout1.addWidget(self.cbox)
        self.arg_dict = arg_dict
        self.name = name
        self.mytype = type(self.arg_dict[name])
        if self.mytype != bool:
            self.cbox.setChecked(bool(self.arg_dict[name]))
        else:
            self.cbox.setChecked(self.arg_dict[name])
        self.cbox.toggled.connect(self.when_modified)
        self.when_modified()
        
    def when_modified(self):
        self.arg_dict[self.name]  = self.cbox.isChecked()
        
    def hide(self):
        QWidget.hide(self)
示例#4
0
class IncludeRow():
	def __init__(self,result):
		self.result			= result
		self.resultLabel	= QLabel(result)
		self.included		= QCheckBox()
	def isIncluded(self):
		return self.included.isChecked()
示例#5
0
class CreateUser(QDialog):
    def __init__(self, window = None):
        super(CreateUser, self).__init__(window)
        layout = QFormLayout(self)

        self.email = QLineEdit(self)
        fm = self.email.fontMetrics()
        self.email.setMaximumWidth(30 * fm.maxWidth() + 11)
        layout.addRow("&User ID:", self.email)

        self.pwd = QLineEdit(self)
        self.pwd.setEchoMode(QLineEdit.Password)
        fm = self.pwd.fontMetrics()
        self.pwd.setMaximumWidth(30 * fm.width('*') + 11)
        layout.addRow("&Password:"******"Password (&again):", self.pwd_again)

        self.display_name = QLineEdit(self)
        fm = self.display_name.fontMetrics()
        self.display_name.setMaximumWidth(50 * fm.maxWidth() + 11)
        layout.addRow("&Name", self.display_name)

        self.savecreds = QCheckBox("&Save Credentials (unsafe)")
        layout.addRow(self.savecreds)

        self.buttonbox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.buttonbox.accepted.connect(self.create)
        self.buttonbox.rejected.connect(self.reject)
        layout.addRow(self.buttonbox)
        self.setLayout(layout)

    def create(self):
        password = self.pwd.text()
        if password != self.pwd_again.text():
            QMessageBox.critical(self, "Passwords don't match",
                "The passwords entered are different")
            self.reject()
        try:
            QCoreApplication.instance().add_user(self.email.text(),
                                                 password,
                                                 self.display_name.text(),
                                                 self.savecreds.isChecked())
            self.accept()
        except Exception as e:
            logger.exception("Exception creating user")
            QMessageBox.critical(self, "Error", str(e))
            self.reject()
示例#6
0
class EditPreferencesDlg(QDialog):
	
	def __init__(self, parent=None):
		super(EditPreferencesDlg, self).__init__(parent)
		self.setWindowTitle("Preferences")
		# define widgets
		pref_list = QListWidget()
		pref_list.addItem("General")
		pref_list.addItem("Display")
		pref_list.setMaximumWidth(150)
		pref_list.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
		
		button_box = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
		
		general_page = QWidget()
		general_layout = QGridLayout()
		general_layout.setAlignment(Qt.AlignTop)
		general_layout.addWidget(QLabel("<b>General</b>"), 0, 0)
		general_page.setLayout(general_layout)
		
		display_page = QWidget()
		display_layout = QGridLayout()
		display_layout.setAlignment(Qt.AlignTop)
		display_layout.addWidget(QLabel("<b>Display Options</b>"), 0, 0)
		self.multitabs_checkbox = QCheckBox("Limit the display of tabs to one relief device (and the device's scenarios) at a time")
		if parent.limit_tabs is True:
			self.multitabs_checkbox.setChecked(True)
		display_layout.addWidget(self.multitabs_checkbox, 1, 0)
		display_page.setLayout(display_layout)

		stacked_widget = QStackedWidget()
		for page in general_page, display_page:
			stacked_widget.addWidget(page)
		
		main_layout = QVBoxLayout()
		widgets_layout = QHBoxLayout()
		widgets_layout.addWidget(pref_list)
		widgets_layout.addWidget(stacked_widget)
		buttons_layout = QHBoxLayout()
		buttons_layout.addStretch()
		buttons_layout.addWidget(button_box)
		main_layout.addLayout(widgets_layout)
		main_layout.addLayout(buttons_layout)
		self.setLayout(main_layout)
		
		pref_list.currentRowChanged.connect(stacked_widget.setCurrentIndex)
		
		button_box.accepted.connect(self.accept)
		button_box.rejected.connect(self.reject)
		
	def sizeHint(self):
		return QSize(400, 400)
		
	def returnVals(self):
		return self.multitabs_checkbox.isChecked()
示例#7
0
class ColorPickerExt(QWidget):
    """An extended color picker widget.

    This widget provides a color picker, and also a checkbox that allows to
    specify to use object color in lieu of color selected in the picker.
    """
    def __init__(self, color=QColor(127, 127, 127), use_object_color=False):
        """Initialize widget.

        Args:
            color -- RGB color used to initialize the color picker
            use_object_color -- boolean used to initialize the 'use object
                color' checkbox
        """
        super().__init__()
        self.use_object_color = use_object_color
        self.colorpicker = ColorPicker(color)
        self.checkbox = QCheckBox()
        self.checkbox.setText(translate("Render", "Use object color"))
        self.setLayout(QHBoxLayout())
        self.layout().addWidget(self.colorpicker)
        self.layout().addWidget(self.checkbox)
        self.layout().setContentsMargins(0, 0, 0, 0)
        QObject.connect(
            self.checkbox,
            SIGNAL("stateChanged(int)"),
            self.on_object_color_change,
        )
        self.checkbox.setChecked(use_object_color)

    def get_color_text(self):
        """Get color picker value, in text format."""
        return self.colorpicker.get_color_text()

    def get_use_object_color(self):
        """Get 'use object color' checkbox value."""
        return self.checkbox.isChecked()

    def get_value(self):
        """Get widget output value."""
        res = ["Object"] if self.get_use_object_color() else []
        res += [self.get_color_text()]
        return ";".join(res)

    def setToolTip(self, desc):
        """Set widget tooltip."""
        self.colorpicker.setToolTip(desc)

    def on_object_color_change(self, state):
        """Respond to checkbox change event."""
        self.colorpicker.setEnabled(not state)
示例#8
0
class _ChannelsResultOptionsToolItem(_ResultToolItem):
    def _initUI(self):
        # Widgets
        self._chk_errorbar = QCheckBox("Show error bars")
        self._chk_errorbar.setChecked(True)

        # Layouts
        layout = _ResultToolItem._initUI(self)
        layout.addRow(self._chk_errorbar)

        # Signals
        self._chk_errorbar.stateChanged.connect(self.stateChanged)

        return layout

    def showErrorbar(self):
        return self._chk_errorbar.isChecked()
示例#9
0
class XMessageBox(QMessageBox):
    """ A QMessageBox with a QCheckBox
    """
    def __init__(self, parent=None):
        super(XMessageBox, self).__init__(parent)

        self.check_box = QCheckBox()
        self.checked = False

        if QT4:
            # Access the Layout of the MessageBox to add a Checkbox
            layout = self.layout()
            layout.addWidget(self.check_box, 1, 1)
        else:
            self.setCheckBox(self.check_box)

    def exec_(self, *args, **kwargs):
        """ Override the exec_ method so
        you can return the value of the checkbox
        """
        return (QMessageBox.exec_(self, *args,
                                  **kwargs), self.check_box.isChecked())
示例#10
0
class TrajectoryDetectorWidget(_DetectorWidget):

    def __init__(self, parent=None):
        _DetectorWidget.__init__(self, parent)
        self.setAccessibleName("Trajectory")

    def _initUI(self):
        # Widgets
        self._chk_secondary = QCheckBox("Simulation secondary electrons")
        self._chk_secondary.setChecked(True)

        # Layouts
        layout = _DetectorWidget._initUI(self)
        layout.addRow(self._chk_secondary)

        return layout

    def value(self):
        secondary = self._chk_secondary.isChecked()
        return TrajectoryDetector(secondary)

    def setValue(self, value):
        self._chk_secondary.setChecked(value.secondary)
示例#11
0
class NewMarkerDialog(QDialog):
	def __init__(self):
		super(NewMarkerDialog, self).__init__()
		self.setWindowTitle('Add new marker...')
		newMarkerLabel		= QLabel('Marker:')
		self.newMarker		= QLineEdit()
		includeLabel		= QLabel('Include all samples:')
		self.includeAll		= QCheckBox()
		controlsLabel		= QLabel('Control wells:')
		self.controls		= QSpinBox()
		self.controls.setRange(0,8)
		self.controls.setValue(2)
		layout				= QGridLayout()
		layout.addWidget(newMarkerLabel,0,0)
		layout.addWidget(self.newMarker,0,1)
		layout.addWidget(includeLabel,1,0)
		layout.addWidget(self.includeAll,1,1)
		layout.addWidget(controlsLabel,2,0)
		layout.addWidget(self.controls,2,1)
		self.buttons		= QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)	
		self.buttons.accepted.connect(self.accept)
		self.buttons.rejected.connect(self.reject)
		layout.addWidget(self.buttons,100,0,1,2)
		self.setLayout(layout)
	def getMarker(self):		return self.newMarker.text()
	def getIncludeAll(self):	return self.includeAll.isChecked()
	def getControls(self):		return self.controls.value()
 
	@staticmethod
	def run(parent = None):
		dialog				= NewMarkerDialog()
		result				= dialog.exec_()
		newMarker			= dialog.getMarker()
		includeAll			= dialog.getIncludeAll()
		controls			= dialog.getControls()
		return (newMarker,includeAll,controls,result == QDialog.Accepted)
示例#12
0
class SelectUser(QDialog):
    def __init__(self, window = None):
        super(SelectUser, self).__init__(window)
        layout = QFormLayout(self)
        self.email = QLineEdit(self)
        fm = self.email.fontMetrics()
        self.email.setMaximumWidth(30 * fm.maxWidth() + 11)
        layout.addRow("&User ID:", self.email)
        self.pwd = QLineEdit(self)
        self.pwd.setEchoMode(QLineEdit.Password)
        fm = self.pwd.fontMetrics()
        self.pwd.setMaximumWidth(30 * fm.width('*') + 11)
        layout.addRow("&Password:"******"&Save Credentials (unsafe)")
        layout.addRow(self.savecreds)
        self.buttonbox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        self.buttonbox.accepted.connect(self.authenticate)
        self.buttonbox.rejected.connect(self.reject)
        layout.addRow(self.buttonbox)
        self.setLayout(layout)

    def select(self):
        if not QCoreApplication.instance().is_authenticated():
            self.exec_()

    def authenticate(self):
        password = self.pwd.text()
        uid = self.email.text()
        savecreds = self.savecreds.isChecked()
        if QCoreApplication.instance().authenticate(uid, password, savecreds):
            self.accept()
        else:
            QMessageBox.critical(self, "Wrong Password",
                "The user ID and password entered do not match.")
示例#13
0
class ExportOrthoWin(QDialog
                     ):  #новый класс как приложение с интерфейсом и кодом
    def __init__(self, parent):
        #_____________Пременные уровня класса___________
        self.OUT_dir = ''  #выходная дирректория
        self.orthoBounds = []
        # ВЫХОДНАЯ ПРОЕКЦИЯ по умолчанию
        #out_crs='PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        self.out_crs = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        #out_crs=PhotoScan.CoordinateSystem('PROJCS["WGS 84 / UTM zone 38N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",45],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32638"]]')
        self.crsShapes = PhotoScan.CoordinateSystem(
            'PROJCS["WGS 84 / UTM zone 37N",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9102"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32637"]]'
        )
        self.DATA_OK = 0
        #print ('orthoBounds=',len(self.orthoBounds))
        #формат массива:0-имя ортофото, 1-Xmin, 2-Ymin, 3-sizeX, 4-sizeY, 5-ID полигона
        #__________________________________________________

        QDialog.__init__(self, parent)
        self.setWindowTitle("Экспорт Орто по разграфке")  #Заголвок окна
        self.resize(500, 250)  #размер окна
        self.txt_comment = QLabel(
            "	Модуль экспортирует ортофото и DEM из фотоскана по нарезке. \
Нарезка в текстовом файле: название листа, координаты нижнего левого угла, размеры. \n	Проекция нарезки должна совпадать с проекцией выходного ортофотоплана.\
Листы делятся по нарезке, а внутри нарезки по блокам, размеры задаются. ФОРМАТ JPG \n	При импорте SHP должно быть текстовое поле NAME \n \
Адрес сервера: " + ServerIP +
            " меняем в теле программы. Ваша версия фотоскана: " + PH_version +
            " \n")
        self.txt_comment.setWordWrap(True)
        self.now_prj = QLabel(str(self.out_crs))
        self.select_prj = QPushButton("Выберете проекцию")  #(" открыть ")
        self.select_prj.setFixedSize(170, 26)

        self.TXT_dif_pix = QLabel("<B>Размер пикселя: </B>")
        self.TXT_dif_pix.setFixedSize(170, 26)
        self.dif_pix = QLineEdit()
        self.dif_pix.setText('0.1')  # Задает размер пикселя по умолчанию
        self.dif_pix.setFixedSize(100, 26)

        items_bloksize = ('5000', '8192', '10000', '15000', '20000', '25000',
                          '29999', 'Full')  # список с размерами тайлов
        #items_bloksize = {5000:5000, 8192:8192, 10000:10000, 15000:15000, 20000:20000, 25000:25000, 29999:29999}
        self.TXT_block_size = QLabel("<B>Размер блока: </B>", )
        self.TXT_block_size.setFixedSize(170, 26)
        self.block_size = QComboBox()
        self.block_size.setFixedSize(100, 26)
        self.block_size.addItems(items_bloksize)
        self.block_size.setCurrentIndex(
            1)  #Устанавливает по умолчанию второе значение из списка - 8192

        self.TXT_SHPname = QLabel("Файл разграфки SHP (NAME,poligons)")
        self.SHPname = QPushButton(
            "Выберете файл разграфки SHP")  #(" открыть ")
        self.SHPname.setFixedSize(170, 26)

        self.TXT_filename = QLabel(
            "Файл разграфки TXT(имя; X0; Y0; sizeX; SizeY)")
        self.filename = QPushButton("Выберете Файл разграфки")  #(" открыть ")
        self.filename.setFixedSize(170, 26)

        self.TXT_CheckOrthoDem = QLabel("Вид выходной продукции")
        self.TXT_CheckOrthoDem.setFixedSize(170, 26)
        self.CheckOrtho_Radio = QRadioButton("Ортофото")
        self.CheckOrtho_Radio.setChecked(True)
        self.CheckDem_Radio = QRadioButton("ДЕМ")

        self.TXT_OUTFOLDER = QLabel("Выходная дирректория")
        self.OUTFOLDER = QPushButton("Выберете дирректорию")  #(" открыть ")
        self.OUTFOLDER.setFixedSize(170, 26)

        items_format = (
            'JPG', 'TIF'
        )  # список форматов, ПРИ выборе ДЕМ будет выбран второй формат - внимательно при изменении списка!!!
        self.file_format = QComboBox()
        self.file_format.setFixedSize(50, 26)
        self.file_format.addItems(items_format)
        self.file_format.setCurrentIndex(
            0)  #Устанавливает по умолчанию первое значение

        self.TXT_checkExportOrtho = QLabel("Построить ортофото:")  # Ортофото
        self.TXT_checkExportOrtho.setFixedSize(170, 26)
        self.checkExportOrtho = QCheckBox()
        self.checkExportOrtho.setChecked(False)

        self.GoGo = QPushButton("Экспорт локально")  #(" Экспорт локально ")
        self.GoGo.setFixedSize(170, 26)
        self.GoGo.setDisabled(True)

        self.GoGoNet = QPushButton("Экспорт по сети")  #(" Экспорт по сети ")
        self.GoGoNet.setFixedSize(170, 26)
        self.GoGoNet.setDisabled(True)

        hbox0 = QHBoxLayout()
        hbox0.addWidget(self.txt_comment, alignment=0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.select_prj, alignment=0)
        hbox1.addWidget(self.now_prj, alignment=0)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.TXT_block_size, alignment=1)
        hbox2.addWidget(self.block_size, alignment=1)

        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.TXT_dif_pix, alignment=1)
        hbox3.addWidget(self.dif_pix, alignment=1)

        hbox4 = QHBoxLayout()
        #hbox4.addStretch(1)
        hbox4.addWidget(self.SHPname, alignment=0)
        hbox4.addWidget(self.TXT_SHPname, alignment=0)

        hbox5 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox5.addWidget(self.filename, alignment=0)
        hbox5.addWidget(self.TXT_filename, alignment=0)

        hbox51 = QHBoxLayout()
        hbox51.addWidget(self.TXT_CheckOrthoDem, alignment=0)
        hbox51.addWidget(self.CheckOrtho_Radio, alignment=0)
        hbox51.addWidget(self.CheckDem_Radio, alignment=0)

        hbox6 = QHBoxLayout()
        #hbox5.addStretch(1)
        hbox6.addWidget(self.OUTFOLDER, alignment=0)
        hbox6.addWidget(self.TXT_OUTFOLDER, alignment=0)
        hbox6.addWidget(self.file_format, alignment=0)

        hbox7 = QHBoxLayout()  #build ortho
        hbox7.addWidget(self.TXT_checkExportOrtho, alignment=0)
        hbox7.addWidget(self.checkExportOrtho, alignment=0)

        hbox8 = QHBoxLayout()
        hbox8.addWidget(self.GoGo, stretch=0, alignment=0)
        hbox8.addWidget(self.GoGoNet, stretch=0, alignment=0)

        vbox = QVBoxLayout()  #Определяем вбокс и забиваем его Нбоксами
        #vbox.addStretch(1)
        vbox.addLayout(hbox0)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        vbox.addLayout(hbox5)
        vbox.addLayout(hbox51)  #выбор, что строить орто или дем
        vbox.addLayout(hbox6)
        #Функция построения ортофото спрятана, поскольку работает не стабильно и построение ортофото для каждого листа в сумме занимает очень много времени,
        #гораздо больше, чем один раз построить ортофото для всех
        #vbox.addLayout(hbox7) #build ortho
        vbox.addLayout(hbox8)

        self.setLayout(vbox)

        self.select_prj.clicked.connect(self.set_projection)
        self.SHPname.clicked.connect(self.input_razgr_SHPname)
        self.filename.clicked.connect(self.input_razgr_name)
        self.OUTFOLDER.clicked.connect(self.input_out_dir)
        self.GoGo.clicked.connect(self.ortho_local)
        self.GoGoNet.clicked.connect(self.ortho_net)
        #Организация блокировки интерфейса для радио кнопок
        self.CheckOrtho_Radio.clicked.connect(self.CheckOrtho_Radio_DO)
        self.CheckDem_Radio.clicked.connect(self.CheckDem_Radio_DO)
        #____________
        self.checkExportOrtho.clicked.connect(
            self.PrintChkStat)  #Функция для проверки работы чека
        #self.WindowContextHelpButtonHint.clicked.connect(self.prog_hint)
        #self.WindowTitleHint.clicked.connect(self.prog_hint)

        self.exec()
        #____________________________________________________________________________

    def PrintChkStat(
        self
    ):  #Эта функция работает в принте с подстановкой и получение значения чека
        if self.checkExportOrtho.isChecked() == True:
            stat = 'ДА'
        else:
            stat = 'НЕТ'
        print('Строить орто %s здесь' % stat)

    def CheckOrtho_Radio_DO(
            self):  #Если выбран Ортоф - формат Джипег и свободен!!!
        print("Орто")
        self.file_format.setCurrentIndex(0)
        self.file_format.setDisabled(False)

    def CheckDem_Radio_DO(
            self):  #Если выбран ДЕМ - формат тифф и блокируется!!!
        print("DEM")
        self.file_format.setCurrentIndex(1)
        self.file_format.setDisabled(True)

    def ortho_local(self):
        self.export_ortho('local')

    def ortho_net(self):
        self.export_ortho('net')

    def prog_hint(self):
        print("OK")

    def unlock_export(self, sel):
        #Переменная нужна для разблокирования кнопки Экспорт. Два критических параметра:Файл разграфки и выходная дирректория, каждый добавляет по еденице.
        #Sel=5 блокирует кнопки при запуске сетевой обработки
        '''
		DATA_OK логика работы: Для экспорта нужно задать выходную директорию и файл разграфки, текстовый или векторный
		при запуске сетевой обработки кнопки опять блокируются
		DATA_OK меняет только эта процедура!!!
		
		0-ничего не задано экспорт заблокирован
		1-выбран  файл разграфки проверяем выбран ли путь, да, разблокируем 3
		2-выбран путь проверяем выбран ли файл разграфки, да, разблокируем 3
		'''
        if sel == 5 and self.DATA_OK == 1:
            self.DATA_OK = 0
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if sel == 5 and self.DATA_OK == 2:
            self.DATA_OK = 2
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if sel == 5 and self.DATA_OK == 3:
            self.DATA_OK = 2
            self.GoGo.setDisabled(True)
            self.GoGoNet.setDisabled(True)
        if self.DATA_OK == 1 and sel == 2: self.DATA_OK = 3
        if self.DATA_OK == 2 and sel == 1: self.DATA_OK = 3
        if self.DATA_OK == 0 and sel != 5: self.DATA_OK = sel
        if self.DATA_OK == 3 and sel != 5:
            self.GoGo.setDisabled(False)
            self.GoGoNet.setDisabled(False)
            print('unlock')
        print(sel, self.DATA_OK)

    def OrthoBoundCalc(self, Xn, Yn, XS,
                       YS):  # изменить под сетевую обработку с тайлами
        DifPix = float(self.dif_pix.text())
        ''' Округление начала Если надо
		Xnround=floor(Xn/DifPix)*DifPix #
		Ynround=floor(Yn/DifPix)*DifPix
		'''
        '''
		if self.block_size.currentText()=='Full' or CommandStack==5 : #Экспорт целикового фрагмента
			print('границы целиковые')
			Xnround=Xn
			Ynround=Yn-DifPix
			XSround=ceil(XS/DifPix+1)*DifPix #Границы округляем в большую сторону и расширяем на пиксель
			YSround=ceil(YS/DifPix+1)*DifPix
			XSround=Xnround+XSround
			YSround=Ynround+YSround
			
		elif CommandStack==1 and self.block_size.currentText()!='Full': # Экспорт по тайлам
			print("Границы со сдвигом")
			BlockSize=float(self.block_size.currentText())
			Xnround=Xn
			Ynround=Yn #-DifPix
			XSround=ceil(XS/DifPix+1)*DifPix #Границы округляем в большую сторону и расширяем на пиксель
			YSround=ceil(YS/DifPix+1)*DifPix
			YBlockSize=BlockSize*DifPix 
			TileShift=YBlockSize-YSround
			Ynround=Ynround+TileShift
			XSround=Xnround+XSround
			YSround=Ynround+YSround+TileShift
		else:
			Print("Bound version error, OrthoBoundCalc")
			pass
			'''
        Xnround = Xn
        Ynround = Yn - DifPix
        XSround = ceil(
            XS / DifPix + 1
        ) * DifPix  #Границы округляем в большую сторону и расширяем на пиксель
        YSround = ceil(YS / DifPix + 1) * DifPix
        XSround = Xnround + XSround
        YSround = Ynround + YSround
        point = [
        ]  #"Эта конструкция нужна для поиска максимальных координат квадрата при переходе из системы в систему
        print("точки")
        point.append(PhotoScan.Vector((Xnround, Ynround)))
        point.append(PhotoScan.Vector((Xnround, YSround)))
        point.append(PhotoScan.Vector((XSround, YSround)))
        point.append(PhotoScan.Vector((XSround, Ynround)))
        print("точки2")
        point_trans = []
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[0], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[1], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[2], self.crsShapes,
                                                 self.out_crs))
        point_trans.append(
            PhotoScan.CoordinateSystem.transform(point[3], self.crsShapes,
                                                 self.out_crs))
        x = []
        y = []
        for i in range(4):
            print(i)
            x.append(point_trans[i][0])
            y.append(point_trans[i][1])
        xMin = min(x)
        yMin = min(y)
        xMax = max(x)
        yMax = max(y)
        #OrthoBound=(Xnround,Ynround,XSround,YSround)
        OrthoBound = (Xnround, Ynround, XSround, YSround)
        print(OrthoBound)
        OrthoBound = (xMin, yMin, xMax, yMax)
        print(OrthoBound)
        return OrthoBound

    def input_razgr_SHPname(self):
        #global listShapes
        SHPname = ''  #Векторный файл разграфки
        DataDir = os.path.dirname(
            __file__)  # Дирректория по умолчанию - дирректория скрипта!!
        shpfilename = QFileDialog.getOpenFileName(
            self, 'выберете векторный файл разграфки', DataDir,
            filter='*.shp')  #Координаты в выходной проекции
        #проверка  на пустоту
        if not shpfilename[0] == '':
            SHP_name = shpfilename[0]
        else:
            return
        sname = os.path.basename(SHP_name)
        file_sname = os.path.splitext(sname)[0]

        print('Путь до шейпа: ', SHP_name)
        print('Имя шейпа: ', file_sname)
        chunk.importShapes(SHP_name, True)  # Импорт шейпфайла с заменой
        shapes = chunk.shapes
        #Сделать проверку на ИМЯ ПОЛИГОНА
        #shapes=PhotoScan.app.document.chunk.shapes
        listShapes = shapes.items()  #Массив (список) шейпов в проекте
        self.crsShapes = shapes.crs  #Проекция шейпа
        print(self.crsShapes)
        PhotoScan.app.messageBox('Импортированы объекты: ' + str(shapes) +
                                 '\n Старые объекты удалены')

        #Получили список векторных объектов, загруженных в проект, теперь проходим по каждому объекту и определяем его минимум и максимум по коориднатам

        if len(listShapes) != 0:
            poligon_ID = 0
            self.orthoBounds = []
            for shape in listShapes:  # ЗДЕСЬ определяются координаты минимум и максимум в текущей проекции в другой все по другому - Могут быть дыры
                # в OrthoBoundCalc стоит заглушка - имщет максимальные коориднаты углов прямоугольника после перепроецирования - можно но не совсем корректно
                x = []
                y = []
                vertices = shape.vertices
                for vertex in vertices:
                    x.append(vertex[0])
                    y.append(vertex[1])

                # Если есть NAME - это будет имя, если нет - имя шейпа и номер фичи
                if str(shape.label) == '':
                    poligonName = str(file_sname) + '_' + str(poligon_ID)
                else:
                    poligonName = str(shape.label)
                xMin = min(x)
                yMin = min(y)
                xSize = max(x) - min(x)
                ySize = max(y) - min(y)
                element = [poligonName, xMin, yMin, xSize, ySize, poligon_ID]
                self.orthoBounds.append(
                    element)  #ЭТО МАССИВ с ГРАНИЦАМИ ОРТОФОТО
                #формат массива:0-имя ортофото, 1-Xmin, 2-Ymin, 3-sizeX, 4-sizeY
                poligon_ID += 1  #Увеличение на единицу
            print(len(self.orthoBounds), poligon_ID)
            if len(self.orthoBounds) != 0: self.unlock_export(1)
            self.TXT_SHPname.setText(str(sname))
            self.TXT_filename.setText(
                "Файл разграфки TXT(имя; X0; Y0; sizeX; SizeY)")
        else:
            PhotoScan.app.messageBox('Пустой SHP файл')
            self.unlock_export(5)
        print('orthoBounds=', len(self.orthoBounds))
        # Шейп засосали,  минимум максимум нашли, с обрезкой дальше разберемся
        #_____________________________________________________________________________

    def input_razgr_name(self):
        TXT_name = ''  #имя файла с разграфкой
        # КООРДИАНТЫ ДОЛЖНЫ БЫТЬ В ВЫХОДНОЙ ПРОЕКЦИИ!!!!!
        DataDir = os.path.dirname(
            __file__)  # Дирректория по умолчанию - дирректория скрипта!!
        textfilename = QFileDialog.getOpenFileName(
            self, 'выберете  файл разграфки', DataDir,
            filter='*.txt')  #Координаты в выходной проекции
        #проверка текстфайлнайм на пустоту
        if not textfilename[0] == '':
            with open(textfilename[0]) as f:
                for line in f:
                    znach = line.split(";")
                    try:
                        if not (isinstance(znach[0], str)):
                            PhotoScan.app.messageBox('Неверный форматS')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[1]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат1i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[2]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат2i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[3]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат3i')
                            self.unlock_export(5)
                            return
                        if not (isinstance(float(znach[4]), (float, int))):
                            PhotoScan.app.messageBox('Неверный формат4i')
                            self.unlock_export(5)
                            return
                    except:
                        PhotoScan.app.messageBox('Неверный формат_;')
                        self.unlock_export(5)
                        return
        else:
            return
        if not (textfilename[0]
                == ''):  #Если все нормально заполняем orthoBounds
            TXT_name = textfilename
            self.orthoBounds = []
            with open(TXT_name[0]) as f:
                count = 0
                for line in f:
                    znach = line.split(";")
                    element = [
                        znach[0], znach[1], znach[2], znach[3], znach[4], count
                    ]
                    self.orthoBounds.append(
                        element)  #ЭТО МАССИВ с ГРАНИЦАМИ ОРТОФОТО
                    count += 1
            print('orthoBounds=', len(self.orthoBounds))
            self.unlock_export(
                1)  #разблокирует экспорт, если заданы разграфка и дирректория
            self.TXT_filename.setText(str(TXT_name[0]))
            self.TXT_SHPname.setText("Файл разграфки SHP (NAME,poligons)")

    def set_projection(self):
        self.out_crs = PhotoScan.app.getCoordinateSystem(
            'Система координат',
            self.out_crs)  #Специальная форма для задания системы координат
        self.now_prj.setText(str(self.out_crs))

    def input_out_dir(self):
        DataDir = os.path.dirname(__file__)
        outputdir = QFileDialog.getExistingDirectory(self,
                                                     'выберете дирректорию',
                                                     DataDir)
        if not outputdir == '':
            self.OUT_dir = outputdir
            self.TXT_OUTFOLDER.setText(str(self.OUT_dir))
            self.unlock_export(
                2)  #разблокирует экспорт, если заданы разграфка и дирректория
        else:
            return
        print('orthoBounds=', len(self.orthoBounds))

    def export_ortho(
        self, proc_type
    ):  # универсальная процедура экспорта для локлаьной и для сетевой обработки
        #global chunk
        ''' ЭТО ПРОВЕРКА ДЛЯ ПОСТРОЕНИЯ ОРТО ПЕРЕД РАБОТОЙ В ТЕКУЩЕЙ ВЕРСИИ ФУНКЦИЯ ОТКЛЮЧЕНА!!
		if self.checkExportOrtho.isChecked()==True:
			statOrthoBuild=True
		else:
			statOrthoBuild=False
		# 000000 Проверка на наличие ортофото или дем перед работой
		if (doc.chunk.orthomosaic==None and statOrthoBuild==False):
			PhotoScan.app.messageBox('Нет орто!!')
			return
		elif (doc.chunk.elevation==None and statOrthoBuild==True):
			PhotoScan.app.messageBox('Нет ДЕМ!!')
			return
		'''
        #Определение вида экспорта - орто или дем
        if self.CheckOrtho_Radio.isChecked() == True:
            ExportType = 'ORTHO'
        elif self.CheckDem_Radio.isChecked() == True:
            ExportType = 'DEM'
        else:
            AssertionError("Какой процесс экспорта?")

        #ПРОВЕРКИ НАЛИЧИЯ ДЕМ И ОРТО
        if (doc.chunk.orthomosaic == None and ExportType == 'ORTHO'):
            PhotoScan.app.messageBox('Нет орто!!')
            return
        elif (doc.chunk.elevation == None and ExportType == 'DEM'):
            PhotoScan.app.messageBox('Нет ДЕМ!!')
            return

        file_format = self.file_format.currentText()
        print('orthoBounds=', len(self.orthoBounds))
        task = []  #Это СПИСОК тасков
        DifPix = float(self.dif_pix.text())
        if self.block_size.currentText() == 'Full':
            BlockSize = 0
        else:
            BlockSize = int(self.block_size.currentText())

        # Цикл для запуска ортофото локально или для забивания стека на сеть из массива
        try:
            for cu_string in self.orthoBounds:
                OName = cu_string[0]
                XMLeft = float(cu_string[1])
                YMDown = float(cu_string[2])
                sizeXM = float(cu_string[3])
                sizeYM = float(cu_string[4])
                shapeNumber = int(cu_string[5])
                cu_Region = self.OrthoBoundCalc(
                    XMLeft, YMDown, sizeXM, sizeYM
                )  #Функция вычисления границ # изменить под сетевую обработку с тайлами
                if file_format == 'JPG' and ExportType == 'ORTHO':
                    fileoutname = self.OUT_dir + "\\ortho_" + OName + ".jpg"
                elif file_format == 'TIF' and ExportType == 'ORTHO':
                    fileoutname = self.OUT_dir + "\\ortho_" + OName + ".tif"
                elif file_format == 'TIF' and ExportType == 'DEM':
                    fileoutname = self.OUT_dir + "\\dem_" + OName + ".tif"
                else:
                    print("Формат файла?")

                if proc_type == 'local':  #КОММАНДЫ для локальной обработки
                    print('Обработка локально')
                    ''' ПОСТРОЕНИЕ ОРТОФОТО В ЭТОЙ ВЕРСИИ ОТКЛЮЧЕНО
					if statOrthoBuild==True: 
						#chunk.buildOrthomosaic(surface=PhotoScan.ElevationData, blending=PhotoScan.MosaicBlending, color_correction=False, projection=self.out_crs, region=cu_Region,dx=DifPix, dy=DifPix)
						chunk.buildOrthomosaic(surface=PhotoScan.ElevationData, blending=PhotoScan.MosaicBlending, projection=self.out_crs, region=cu_Region,dx=DifPix, dy=DifPix)
					'''

                    if CommandStack == 1 and ExportType == 'ORTHO':
                        if file_format == 'JPG':
                            chunk.exportOrthomosaic(fileoutname,
                                                    format="jpg",
                                                    projection=self.out_crs,
                                                    region=cu_Region,
                                                    dx=DifPix,
                                                    dy=DifPix,
                                                    blockw=BlockSize,
                                                    blockh=BlockSize,
                                                    write_kml=False,
                                                    write_world=True)
                        elif file_format == 'TIF':
                            chunk.exportOrthomosaic(fileoutname,
                                                    format="tif",
                                                    projection=self.out_crs,
                                                    region=cu_Region,
                                                    dx=DifPix,
                                                    dy=DifPix,
                                                    blockw=BlockSize,
                                                    blockh=BlockSize,
                                                    write_kml=False,
                                                    write_world=True,
                                                    tiff_compression="jpeg",
                                                    tiff_big=False)
                            #сжатие LZW
                            #elif file_format=='TIF': chunk.exportOrthomosaic(fileoutname, format="tif", region=cu_Region, projection=self.out_crs,dx=DifPix, dy=DifPix, blockw=BlockSize, blockh=BlockSize, write_kml=False, write_world=True, tiff_compression="lzw", tiff_big=False)
                        else:
                            print("Формат файла?")
                    elif CommandStack == 5 and ExportType == 'ORTHO':
                        if file_format == 'JPG':
                            chunk.exportOrthomosaic(
                                fileoutname,
                                PhotoScan.RasterFormatTiles,
                                PhotoScan.ImageFormatJPEG,
                                region=cu_Region,
                                projection=self.out_crs,
                                dx=DifPix,
                                dy=DifPix,
                                blockw=BlockSize,
                                blockh=BlockSize,
                                write_kml=False,
                                write_world=True)
                        elif file_format == 'TIF':
                            chunk.exportOrthomosaic(
                                fileoutname,
                                PhotoScan.RasterFormatTiles,
                                PhotoScan.ImageFormatTIFF,
                                region=cu_Region,
                                projection=self.out_crs,
                                dx=DifPix,
                                dy=DifPix,
                                blockw=BlockSize,
                                blockh=BlockSize,
                                write_kml=False,
                                write_world=True,
                                tiff_compression=PhotoScan.TiffCompressionJPEG,
                                tiff_big=False)
                            #сжатие LZW
                            #elif file_format=='TIF': chunk.exportOrthomosaic(fileoutname, PhotoScan.RasterFormatTiles,PhotoScan.ImageFormatTIFF, region=cu_Region, projection=self.out_crs,dx=DifPix, dy=DifPix, blockw=BlockSize, blockh=BlockSize, write_kml=False, write_world=True, tiff_compression=PhotoScan.TiffCompressionLZW, tiff_big=False)
                        else:
                            print("Формат файла?")
                    elif CommandStack == 1 and ExportType == 'DEM':
                        print("Экспорт ДЕМ локально")
                        if file_format == 'TIF':
                            chunk.exportDem(fileoutname,
                                            format="tif",
                                            projection=self.out_crs,
                                            region=cu_Region,
                                            dx=DifPix,
                                            dy=DifPix,
                                            blockw=BlockSize,
                                            blockh=BlockSize,
                                            write_kml=False,
                                            write_world=True,
                                            tiff_big=False)
                    elif CommandStack == 5 and ExportType == 'DEM':
                        print("Экспорт ДЕМ локально")
                        if file_format == 'TIF':
                            chunk.exportDem(fileoutname,
                                            PhotoScan.RasterFormatTiles,
                                            PhotoScan.ImageFormatTIFF,
                                            region=cu_Region,
                                            projection=self.out_crs,
                                            dx=DifPix,
                                            dy=DifPix,
                                            blockw=BlockSize,
                                            blockh=BlockSize,
                                            write_kml=False,
                                            write_world=True,
                                            tiff_big=False)

                elif proc_type == 'net':
                    print('Обработка по сети')
                    ''' ПОСТРОЕНИЕ ОРТОФОТО В ЭТОЙ ВЕРСИИ ОТКЛЮЧЕНО
					#Построить ортофото
					if statOrthoBuild==True:
						workBuild = PhotoScan.NetworkTask() # СОздаем ворк и забиваем его параметрами
						#Версионность
						if CommandStack==1:
							workBuild.params['ortho_surface'] = 0
							workBuild.params['resolution_x'] = DifPix
							workBuild.params['resolution_y'] = DifPix
						elif CommandStack==5:
							workBuild.params['ortho_surface'] = 4
							workBuild.params['resolution'] = DifPix
						else:
							return
						workBuild.name = "BuildOrthomosaic"
						workBuild.frames.append((chunk.key,0))
						workBuild.params['network_distribute'] = True
						
						task.append(workBuild) #Добавляем задачу построения в таск
					'''

                    #Экспортировать ортофото
                    workExport = PhotoScan.NetworkTask(
                    )  # СОздаем ворк и забиваем его параметрами
                    #ВЕРСИОННОСТЬ
                    if CommandStack == 1 and ExportType == 'ORTHO':
                        workExport.name = "ExportOrthomosaic"
                        workExport.params['resolution_x'] = DifPix
                        workExport.params['resolution_y'] = DifPix
                        if file_format == 'JPG':
                            workExport.params['raster_format'] = 2
                        elif file_format == 'TIF':
                            workExport.params['raster_format'] = 1
                        else:
                            print("Формат файла?")
                    elif CommandStack == 5 and ExportType == 'ORTHO':
                        workExport.name = "ExportRaster"
                        workExport.params['resolution'] = DifPix
                        if file_format == 'JPG':
                            workExport.params['image_format'] = 1
                        elif file_format == 'TIF':
                            workExport.params[
                                'image_format'] = 2  #Значение на шару!!! ПРОВЕРИТЬ
                        else:
                            print("Формат файла?")
                    elif CommandStack == 1 and ExportType == 'DEM':
                        print("Экспорт ДЕМ по сети")
                        workExport.name = "ExportDem"
                        workExport.params['resolution_x'] = DifPix
                        workExport.params['resolution_y'] = DifPix
                    elif CommandStack == 5 and ExportType == 'DEM':  #НЕ ОТЛАЖЕНО ПАРАМЕТРЫ НА ШАРУ
                        print("Экспорт ДЕМ по сети")
                        workExport.name = "ExportOrthomosaic"
                        workExport.params['resolution'] = DifPix
                        pass
                    else:
                        return

                    workExport.frames.append((chunk.key, 0))
                    workExport.params['write_world'] = 1
                    if self.block_size.currentText(
                    ) == 'Full':  # Условие на запись тайлов
                        workExport.params['write_tiles'] = 0
                    else:
                        workExport.params['write_tiles'] = 1
                    workExport.params['tile_width'] = BlockSize
                    workExport.params['tile_height'] = BlockSize
                    workExport.params[
                        'path'] = fileoutname  #выходная дирректория с именем файла
                    workExport.params['region'] = cu_Region
                    # ВНИМАНИЕ! По сети нельзя экспортировать в пользовательской проекции ИЛИ проекция должна быть НА ВСЕХ НОДАХ
                    workExport.params[
                        'projection'] = self.out_crs.authority  #Из объекта проекция берется только ее номер EPSG::32637
                    #ВНИМАНИЕ ЭКСПОРТ ОТКЛЮЧЕН!!!!
                    task.append(workExport)  #Добавляем задачу в таск
                else:
                    print('Пока не задано')
            PhotoScan.app.messageBox('Обработка закончена')
        except Exception as e:
            print(e)
            PhotoScan.app.messageBox('Что-то пошло не так ((')
            return
            #break
#Запуск сетевого стека, таска в обработку
        if proc_type == 'net':
            print(ProjectLocalPath_auto)
            print(ProjectPath)
            client.connect(ServerIP)
            batch_id = client.createBatch(ProjectPath, task)

            if batch_id == None:  #Проверка наличия проекта в сети
                PhotoScan.app.messageBox(
                    '<B>Этот проект уже запущен в обработку!!!<B>')
                self.unlock_export(5)
            else:
                print('Проект работает под номером ', batch_id)
                client.resumeBatch(batch_id)
                self.unlock_export(5)
                PhotoScan.app.messageBox(
                    'Проект поставлен в очередь сетевой обработки')

            client.disconnect()
            pass
class NetworkPane(BasePane):
    def __init__(self, setting_dict):
        BasePane.__init__( self )

        networkLayout = QFormLayout()

        matchAlgorithmBox = QGroupBox()
        self.ccRadio = QRadioButton('Cross-correlation')
        self.dtwRadio = QRadioButton('DTW')
        self.dctRadio = QRadioButton('DCT')

        hbox = QHBoxLayout()
        hbox.addWidget(self.ccRadio)
        hbox.addWidget(self.dtwRadio)
        hbox.addWidget(self.dctRadio)
        matchAlgorithmBox.setLayout(hbox)

        networkLayout.addRow(QLabel('Similarity algorithm:'),matchAlgorithmBox)

        clusterBox = QGroupBox()
        self.completeRadio = QRadioButton('Complete')
        self.thresholdRadio = QRadioButton('Threshold')
        self.apRadio = QRadioButton('Affinity propagation')
        self.scRadio = QRadioButton('Spectral clustering')

        hbox = QHBoxLayout()
        hbox.addWidget(self.completeRadio)
        hbox.addWidget(self.thresholdRadio)
        hbox.addWidget(self.apRadio)
        hbox.addWidget(self.scRadio)
        clusterBox.setLayout(hbox)

        networkLayout.addRow(QLabel('Cluster algorithm:'),clusterBox)

        self.oneClusterCheck = QCheckBox()
        networkLayout.addRow(QLabel('Enforce single cluster:'),self.oneClusterCheck)

        self.thresholdEdit = QLineEdit()
        networkLayout.addRow(QLabel('Similarity threshold:'),self.thresholdEdit)

        self.setLayout(networkLayout)

        #set up defaults

        matchAlgorithm = setting_dict['dist_func']
        clustAlgorithm = setting_dict['cluster_alg']
        oneCluster = setting_dict['one_cluster']

        if matchAlgorithm == 'xcorr':
            self.ccRadio.setChecked(True)
        elif matchAlgorithm == 'dct':
            self.dctRadio.setChecked(True)
        else:
            self.dtwRadio.setChecked(True)

        if clustAlgorithm == 'complete':
            self.completeRadio.setChecked(True)
        elif clustAlgorithm == 'threshold':
            self.thresholdRadio.setChecked(True)
        elif clustAlgorithm == 'affinity':
            self.apRadio.setChecked(True)
        elif clustAlgorithm == 'spectral':
            self.scRadio.setChecked(True)

        if oneCluster:
            self.oneClusterCheck.setChecked(True)
        self.thresholdEdit.setText(str(setting_dict['threshold']))

        self.prev_state = setting_dict

    def get_current_state(self):
        setting_dict = {}

        if self.ccRadio.isChecked():
            setting_dict['dist_func'] = 'xcorr'
        elif self.dctRadio.isChecked():
            setting_dict['dist_func'] = 'dct'
        elif self.dtwRadio.isChecked():
            setting_dict['dist_func'] = 'dtw'

        if self.completeRadio.isChecked():
            setting_dict['cluster_alg'] = 'complete'
        elif self.thresholdRadio.isChecked():
            setting_dict['cluster_alg'] = 'threshold'
        elif self.apRadio.isChecked():
            setting_dict['cluster_alg'] = 'affinity'
        elif self.scRadio.isChecked():
            setting_dict['cluster_alg'] = 'spectral'

        setting_dict['one_cluster'] = int(self.oneClusterCheck.isChecked())
        setting_dict['threshold'] = float(self.thresholdEdit.text())

        return setting_dict

    def is_changed(self):
        cur_state = self.get_current_state()
        if self.prev_state['dist_func'] != cur_state['dist_func']:
            return True
        return False
        for k in ['dist_func','cluster_alg']:
            if self.prev_state[k] != cur_state[k]:
                return True
        if cur_state['cluster_alg'] == 'threshold':
            if self.prev_state['threshold'] != cur_state['threshold']:
                return True
        elif cur_state['cluster_alg'] in {'affinity','spectral'}:
            if self.prev_state['one_cluster'] != cur_state['one_cluster']:
                return True
        return False
示例#15
0
文件: Recreate.py 项目: ra2003/xindex
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("Recreate Entries — {}".format(
            QApplication.applicationName()))
        self.createWidgets()
        self.layoutWidgets()
        self.populate()
        self.updateUi()
        self.createConnections()
        settings = QSettings()
        self.updateToolTips(
            bool(
                int(
                    settings.value(Gopt.Key.ShowDialogToolTips,
                                   Gopt.Default.ShowDialogToolTips))))

    def createWidgets(self):
        self.listWidget = Widgets.List.HtmlListWidget(self.state)
        self.tooltips.append((self.listWidget, """\
<p><b>Recreatable Entries view</b></p>
<p>The list of this index's recreatable entries.</p>"""))
        self.recreateSubentriesCheckBox = QCheckBox("Recreate &Subentries")
        self.recreateSubentriesCheckBox.setChecked(True)
        self.tooltips.append((self.recreateSubentriesCheckBox, """\
<p><b>Recreate Subentries</b></p>
<p>If checked, when an entry or subentry is recreated, all of its
subentries, and their subentries, and so on (if any), will also be
recrected if possible.</p>"""))
        self.recreateButton = QPushButton(QIcon(":/recreate.svg"), "&Recreate")
        self.recreateButton.setDefault(True)
        self.recreateButton.setAutoDefault(True)
        self.tooltips.append((self.recreateButton, """\
<p><b>Recreate</b></p>
<p>Recreate the current entry or subentry (and its subentries and their
subentries, and so on, if the <b>Recreate Subentries</b> checkbox is
checked), and then close the dialog.</p>
<p>Note that it is possible to get rid of the recreated entries by
clicking <b>Index→Undo</b> immediately after the dialog closes. (Or, at
any later time by simply deleting them.)"""))
        self.deleteButton = QPushButton(QIcon(":/delete.svg"), "&Delete...")
        self.tooltips.append((self.deleteButton, """\
<p><b>Delete</b></p>
<p>Permanently delete the current recreatable entry or subentry from
this index's list of recreatable entries.</p>"""))
        self.helpButton = QPushButton(QIcon(":/help.svg"), "Help")
        self.tooltips.append(
            (self.helpButton, "Help on the Recreate Entries dialog"))
        self.closeButton = QPushButton(QIcon(":/dialog-close.svg"), "&Close")
        self.tooltips.append((self.closeButton, """<p><b>Close</b></p>
<p>Close the dialog.</p>"""))

    def layoutWidgets(self):
        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.recreateButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.deleteButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.closeButton, QDialogButtonBox.AcceptRole)
        buttonBox.addButton(self.helpButton, QDialogButtonBox.HelpRole)
        layout = QVBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addWidget(self.recreateSubentriesCheckBox)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.recreateButton.clicked.connect(self.recreate)
        self.deleteButton.clicked.connect(self.delete)
        self.closeButton.clicked.connect(self.reject)
        self.helpButton.clicked.connect(self.help)

    def help(self):
        self.state.help("xix_ref_dlg_recreate.html")

    def updateUi(self):
        enable = self.listWidget.currentRow() > -1
        self.recreateButton.setEnabled(enable)
        self.deleteButton.setEnabled(enable)

    def populate(self):
        self.listWidget.clear()
        for entry in self.state.model.deletedEntries():
            pages = ""
            if entry.pages:
                pages = ", {}".format(entry.pages)
            top = MAIN_INDICATOR if entry.peid == ROOT else SUB_INDICATOR
            item = QListWidgetItem("{} {}{}".format(
                top, Lib.elidePatchHtml(entry.term, self.state),
                Lib.elidePatchHtml(pages, self.state)))
            item.setData(Qt.UserRole, entry.eid)
            self.listWidget.addItem(item)
        if self.listWidget.count():
            self.listWidget.setCurrentRow(0)

    def recreate(self):  # No need to restore focus widget
        item = self.listWidget.currentItem()
        if item:
            eid = item.data(Qt.UserRole)
            subentries = self.recreateSubentriesCheckBox.isChecked()
            with Lib.DisableUI(self):
                self.state.model.recreateEntry(eid, subentries)
            say("Recreated", SAY_TIMEOUT)
        self.accept()

    def delete(self):
        widget = QApplication.focusWidget()
        item = self.listWidget.currentItem()
        if item:
            eid = item.data(Qt.UserRole)
            if self.state.model.hasDeletedEntry(eid):
                with Lib.Qt.DisableUI(self, forModalDialog=True):
                    reply = QMessageBox.question(
                        self, "Delete Revivable Entry — {}".format(
                            QApplication.applicationName()),
                        "<p>Permanently delete revivable entry<br>“{}”?".
                        format(item.text()), QMessageBox.Yes | QMessageBox.No,
                        QMessageBox.Yes)
                if reply == QMessageBox.Yes:
                    with Lib.DisableUI(self):
                        self.state.model.deleteDeletedEntry(eid)
                        self.populate()
                    self.updateUi()
        Lib.restoreFocus(widget)
示例#16
0
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("New Empty Copy — {}".format(
            QApplication.applicationName()))
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()
        self.updateUi()
        settings = QSettings()
        self.updateToolTips(
            bool(
                int(
                    settings.value(Gopt.Key.ShowDialogToolTips,
                                   Gopt.Default.ShowDialogToolTips))))

    def createWidgets(self):
        self.filenameLabelLabel = QLabel("New Filename")
        self.filenameLabel = QLabel()
        self.filenameLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.filenameButton = QPushButton("C&hoose...")
        self.tooltips.append((self.filenameButton, """\
<p><b>Choose</b></p>
<p>Choose the {} <tt>.xix</tt> file to copy the current index's options,
spelling words, etc., to.</p>""".format(QApplication.applicationName())))
        self.copyGroupBox = QGroupBox("Copy")
        self.configCheckBox = QCheckBox("&Options")
        self.tooltips.append((self.configCheckBox, """\
<p><b>Options</b></p>
<p>If checked, copy all the current index's option and output option
settings (language, sort as and page range rules, display preferences,
fonts, output style, etc.) to the new empty copy.</p>"""))
        self.spellWordsCheckBox = QCheckBox("&Spelling Words")
        self.tooltips.append((self.spellWordsCheckBox, """\
<p><b>Spelling Words</b></p>
<p>If checked, copy all the current index's spelling words to the new
empty copy.</p>"""))
        self.ignoredFirstWordsCheckBox = QCheckBox(
            "&Ignored Subentry Function Words")
        self.tooltips.append((self.ignoredFirstWordsCheckBox, """\
<p><b>Ignored Subentry Function Words</b></p>
<p>If checked, copy all the current index's ignored subentry function
words words to the new empty copy.</p>"""))
        self.customMarkupCheckBox = QCheckBox("Custom &Markup")
        self.tooltips.append((self.customMarkupCheckBox, """\
<p><b>Custom Markup</b></p>
<p>If checked, copy all the current index's custom markup to the new
empty copy.</p>"""))
        self.groupsCheckBox = QCheckBox("&Groups")
        self.tooltips.append((self.groupsCheckBox, """\
<p><b>Groups</b></p>
<p>If checked, copy all the current index's groups to the new empty
copy.</p>"""))
        self.autoReplaceCheckBox = QCheckBox("&Auto Replacements")
        self.tooltips.append((self.autoReplaceCheckBox, """\
<p><b>Auto Replacements</b></p>
<p>If checked, copy all the current index's auto replacements to the new
empty copy.</p>"""))
        for checkbox in (self.configCheckBox, self.spellWordsCheckBox,
                         self.ignoredFirstWordsCheckBox,
                         self.customMarkupCheckBox, self.groupsCheckBox,
                         self.autoReplaceCheckBox):
            checkbox.setChecked(True)
        self.helpButton = QPushButton(QIcon(":/help.svg"), "Help")
        self.tooltips.append(
            (self.helpButton, "Help on the New Empty Copy dialog"))
        self.newCopyButton = QPushButton(QIcon(":/document-new.svg"),
                                         "&New Empty Copy")
        self.tooltips.append((self.newCopyButton, """\
<p><b>New Empty Copy</b></p>
<p>Create a new empty index and copy the options, spelling words,
etc.&mdash;providing they have been checked&mdash;into the new
index.</p>"""))
        self.cancelButton = QPushButton(QIcon(":/dialog-close.svg"), "&Cancel")
        self.tooltips.append((self.cancelButton, """<p><b>Cancel</b></p>
<p>Close the dialog without making a new empty copy.</p>"""))

    def layoutWidgets(self):
        layout = QVBoxLayout()
        hbox = QHBoxLayout()
        hbox.addWidget(self.filenameLabelLabel)
        hbox.addWidget(self.filenameLabel, 1)
        hbox.addWidget(self.filenameButton)
        layout.addLayout(hbox)
        grid = QGridLayout()
        grid.addWidget(self.configCheckBox, 0, 0)
        grid.addWidget(self.autoReplaceCheckBox, 0, 1)
        grid.addWidget(self.spellWordsCheckBox, 1, 0)
        grid.addWidget(self.ignoredFirstWordsCheckBox, 1, 1)
        grid.addWidget(self.groupsCheckBox, 2, 0)
        grid.addWidget(self.customMarkupCheckBox, 2, 1)
        hbox = QHBoxLayout()
        hbox.addLayout(grid)
        hbox.addStretch()
        self.copyGroupBox.setLayout(hbox)
        layout.addWidget(self.copyGroupBox)
        layout.addStretch()
        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.newCopyButton, QDialogButtonBox.AcceptRole)
        buttonBox.addButton(self.cancelButton, QDialogButtonBox.RejectRole)
        buttonBox.addButton(self.helpButton, QDialogButtonBox.HelpRole)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.newCopyButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
        self.helpButton.clicked.connect(self.help)
        self.filenameButton.clicked.connect(self.setFilename)

    def updateUi(self):
        filename = self.filenameLabel.text()
        self.newCopyButton.setEnabled(
            bool(filename)
            and filename != os.path.normpath(self.state.model.filename))

    def setFilename(self):  # No need to restore focus widget
        with Lib.Qt.DisableUI(self, forModalDialog=True):
            filename, _ = QFileDialog.getSaveFileName(
                self,
                "New Empty Index — {}".format(QApplication.applicationName()),
                self.state.indexPath,
                "{} index (*{})".format(QApplication.applicationName(),
                                        EXTENSION))
        if filename and not filename.casefold().endswith(EXTENSION):
            filename += EXTENSION
        if filename:
            self.state.indexPath = os.path.dirname(filename)
            self.filenameLabel.setText(os.path.normpath(filename))
            self.updateUi()

    def help(self):
        self.state.help("xix_ref_dlg_newcopy.html")

    def accept(self):
        settings = QSettings()
        language = LanguageKind(
            settings.value(Gopt.Key.Language, Gopt.Default.Language))
        if self.configCheckBox.isChecked():
            sortasrules = Gopt.Default.SortAsRules
            pagerangerules = Gopt.Default.PageRangeRules
        else:
            sortasrules = self.state.model.sortAsRules()
            pagerangerules = self.state.model.pageRangeRules()
        copyInfo = CopyInfo(self.state.model.filename,
                            self.filenameLabel.text(),
                            self.configCheckBox.isChecked(),
                            self.customMarkupCheckBox.isChecked(),
                            self.spellWordsCheckBox.isChecked(),
                            self.ignoredFirstWordsCheckBox.isChecked(),
                            self.autoReplaceCheckBox.isChecked(),
                            self.groupsCheckBox.isChecked(),
                            self.state.model.username, language, sortasrules,
                            pagerangerules)
        self.state.window.closeXix()
        self.state.model.copyEmpty(copyInfo)
        self.state.window.openXix(copyInfo.newname)
        self.state.entryPanel.clearForm()
        self.state.setMode(ModeKind.VIEW)
        super().accept()
示例#17
0
class LoginView(View):
    """`View` derived class. Defines the log in widget"""

    login = Signal((
        str,
        str,
        str,
        bool,
    ))

    def __init__(self, parent=None):
        """
        Init method. Initializes parent classes
        
        :param parent: Reference to a `QWidget` object to be used as parent 
        """

        super(LoginView, self).__init__(parent)

        self.createWidgets()
        self.createLayouts()
        self.setFixedSize(250, 340)

    def createLayouts(self):
        """Put widgets into layouts, thus creating the widget"""

        mainLayout = QHBoxLayout()
        fieldsLayout = QVBoxLayout()
        ftpInfoLayout = QHBoxLayout()
        buttonLayout = QHBoxLayout()

        mainLayout.addStretch(20)

        fieldsLayout.addStretch(80)
        fieldsLayout.addWidget(self.linkLabel)
        fieldsLayout.addWidget(self.line)
        fieldsLayout.addStretch(20)

        ftpInfoLayout.addWidget(self.hostLabel, 50, Qt.AlignLeft)
        ftpInfoLayout.addStretch(20)
        ftpInfoLayout.addWidget(self.sslLabel, 20, Qt.AlignRight)
        ftpInfoLayout.addWidget(self.sslCheck, 10, Qt.AlignRight)

        fieldsLayout.addLayout(ftpInfoLayout)
        fieldsLayout.addWidget(self.hostEdit)
        fieldsLayout.addWidget(self.usernameLabel)
        fieldsLayout.addWidget(self.usernameEdit)
        fieldsLayout.addWidget(self.passwdLabel)
        fieldsLayout.addWidget(self.passwdEdit)
        fieldsLayout.addStretch(30)

        buttonLayout.addStretch(50)
        buttonLayout.addWidget(self.loginButton, 50, Qt.AlignRight)

        fieldsLayout.addLayout(buttonLayout)
        fieldsLayout.addStretch(20)

        mainLayout.addLayout(fieldsLayout, 30)
        mainLayout.addStretch(20)

        self.setLayout(mainLayout)

    def createWidgets(self):
        """Create children widgets needed by this view"""

        fieldsWidth = 200
        labelsFont = View.labelsFont()
        editsFont = View.editsFont()
        self.setLogo()

        self.hostLabel = QLabel(self)
        self.hostEdit = QLineEdit(self)
        self.sslLabel = QLabel(self)
        self.sslCheck = QCheckBox(self)
        self.hostLabel.setText('FTP Location')
        self.hostLabel.setFont(labelsFont)
        self.hostEdit.setFixedWidth(fieldsWidth)
        self.hostEdit.setFont(editsFont)
        self.sslLabel.setText('SSL')
        self.sslLabel.setFont(labelsFont)

        self.usernameLabel = QLabel(self)
        self.usernameEdit = QLineEdit(self)
        self.usernameLabel.setText('Username')
        self.usernameLabel.setFont(labelsFont)
        self.usernameEdit.setFixedWidth(fieldsWidth)
        self.usernameEdit.setFont(editsFont)

        self.passwdLabel = QLabel(self)
        self.passwdEdit = QLineEdit(self)
        self.passwdLabel.setText('Password')
        self.passwdLabel.setFont(labelsFont)
        self.passwdEdit.setFixedWidth(fieldsWidth)
        self.passwdEdit.setEchoMode(QLineEdit.Password)
        self.passwdEdit.setFont(editsFont)
        self.passwdEdit.returnPressed.connect(self.onLoginClicked)

        self.loginButton = QPushButton(self)
        self.loginButton.setText('Login')
        self.loginButton.setFont(labelsFont)
        self.loginButton.setFixedWidth(fieldsWidth / 2)
        self.loginButton.clicked.connect(self.onLoginClicked)

        # Sets previously stored values into the fields, if any
        settings = get_settings()

        self.hostEdit.setText(settings.value(SettingsKeys['host'], ''))
        self.usernameEdit.setText(settings.value(SettingsKeys['username'], ''))
        self.passwdEdit.setText(
            crypt.decrypt(settings.value(SettingsKeys['passwd'], '')))

        # Unicode to boolean conversion
        ssl = settings.value(SettingsKeys['ssl'], u'true')
        ssl = True if ssl == u'true' else False
        self.sslCheck.setChecked(ssl)

    @Slot()
    def onLoginClicked(self):
        """
        Slot. Called on the user clicks on the `loginButton` button
        """
        # Takes out the user input from the fields
        host = self.hostEdit.text()
        username = self.usernameEdit.text()
        passwd = self.passwdEdit.text()
        ssl = self.sslCheck.isChecked()

        print 'Logging in: %s, %s, %s' % (host, username, '*' * len(passwd))

        if len(host) > 0:
            # If the fields are valid, store them using a `QSettings` object
            # and triggers a log in request
            settings = get_settings()

            settings.setValue(SettingsKeys['host'], host)
            settings.setValue(SettingsKeys['username'], username)
            settings.setValue(SettingsKeys['passwd'], crypt.encrypt(passwd))
            settings.setValue(SettingsKeys['ssl'], ssl)

            self.setEnabled(False)
            self.login.emit(host.strip(), username, passwd, ssl)

    @Slot()
    def onFailedLogIn(self):
        """
        Slot. Called when the log in request fails
        """

        # Enables the fields again for user input
        self.setEnabled(True)
示例#18
0
class RunnerDialog(QDialog):

    options_added = Signal(Options)
    options_running = Signal(Options)
    options_simulated = Signal(Options)
    options_error = Signal(Options, Exception)
    results_saved = Signal(Results, str)
    results_error = Signal(Results, Exception)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)

    def _onDialogProgressProgress(self, progress, status):
        self._dlg_progress.setValue(progress * 100)
        self._dlg_progress.setLabelText(status)

    def _onDialogProgressCancel(self):
        self._dlg_progress.hide()
        if self._options_reader_thread is None:
            return
        self._options_reader_thread.cancel()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()

    def _onDialogProgressException(self, ex):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        messagebox.exception(self, ex)

    def _onRunningTimer(self):
        self._tbl_options.model().reset()

    def _onOpen(self):
        settings = get_settings()
        curdir = getattr(settings.gui, 'opendir', os.getcwd())

        filepath, namefilter = \
            QFileDialog.getOpenFileName(self, "Open", curdir,
                                        'Options [*.xml] (*.xml)')

        if not filepath or not namefilter:
            return
        settings.gui.opendir = os.path.dirname(filepath)

        if not filepath.endswith('.xml'):
            filepath += '.xml'

        self._options_reader_thread = _OptionsReaderWrapperThread(filepath)
        self._dlg_progress.canceled.connect(self._onDialogProgressCancel)
        self._options_reader_thread.resultReady.connect(self._onOpened)
        self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress)
        self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException)
        self._options_reader_thread.start()

        self._dlg_progress.reset()
        self._dlg_progress.show()

    def _onOpened(self, options):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        self._options_reader_thread = None

        try:
            self._lst_available.model().addOptions(options)
        except Exception as ex:
            messagebox.exception(self, ex)

    def _onRemove(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.popOptions(row)

    def _onClear(self):
        self._lst_available.model().clearOptions()

    def _onAddToQueue(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onAddAllToQueue(self):
        model = self._lst_available.model()
        for row in reversed(range(0, model.rowCount())):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onStart(self):
        outputdir = self._txt_outputdir.path()
        if not outputdir:
            QMessageBox.critical(self, 'Start', 'Missing output directory')
            return
        max_workers = self._spn_workers.value()
        overwrite = self._chk_overwrite.isChecked()
        self.start(outputdir, overwrite, max_workers)

    def _onCancel(self):
        self.cancel()

    def _onClose(self):
        if self._runner is not None:
            self._runner.close()
        self._running_timer.stop()
        self.close()

    def _onImport(self):
        list_options = self._lst_available.model().listOptions()
        if not list_options:
            return

        # Select options
        dialog = _OptionsSelector(list_options)
        if not dialog.exec_():
            return
        options = dialog.options()

        # Start importer
        outputdir = self._runner.outputdir
        max_workers = self._runner.max_workers
        importer = LocalImporter(outputdir, max_workers)

        importer.start()
        importer.put(options)

        self._dlg_progress.show()
        try:
            while importer.is_alive():
                if self._dlg_progress.wasCanceled():
                    importer.cancel()
                    break
                self._dlg_progress.setValue(importer.progress * 100)
        finally:
            self._dlg_progress.hide()

    def _onOptionsAdded(self, options):
        logging.debug('runner: optionsAdded')
        self._tbl_options.model().addOptions(options)

    def _onOptionsRunning(self, options):
        logging.debug('runner: optionsRunning')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsSimulated(self, options):
        logging.debug('runner: optionsSimulated')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsError(self, options, ex):
        logging.debug('runner: optionsError')
        self._tbl_options.model().resetOptions(options)

    def _onResultsError(self, results, ex):
        logging.debug('runner: resultsError')
        self._tbl_options.model().reset()

    def closeEvent(self, event):
        if self.is_running():
            message = 'Runner is running. Do you want to continue?'
            answer = QMessageBox.question(self, 'Runner', message,
                                          QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                event.ignore()
                return

        self.cancel()
        self._dlg_progress.close()

        settings = get_settings()
        section = settings.add_section('gui')

        path = self._txt_outputdir.path()
        if path:
            section.outputdir = path
        section.maxworkers = str(self._spn_workers.value())
        section.overwrite = str(self._chk_overwrite.isChecked())

        settings.write()

        event.accept()

    def addAvailableOptions(self, options):
        self._lst_available.model().addOptions(options)

    def removeAvailableOptions(self, options):
        self._lst_available.model().removeOptions(options)

    def clearAvailableOptions(self):
        self._lbl_available.model().clearOptions()

    def start(self, outputdir, overwrite, max_workers):
        self._runner = LocalRunner(outputdir=outputdir,
                                   overwrite=overwrite,
                                   max_workers=max_workers)

        self._tbl_options.setModel(_StateOptionsTableModel(self._runner))

        self._spn_workers.setEnabled(False)
        self._txt_outputdir.setEnabled(False)
        self._chk_overwrite.setEnabled(False)
        self._btn_addtoqueue.setEnabled(True)
        self._btn_addalltoqueue.setEnabled(True)
        self._btn_start.setEnabled(False)
        self._btn_cancel.setEnabled(True)
        self._btn_close.setEnabled(False)
        self._btn_import.setEnabled(True)

        self._runner.options_added.connect(self.options_added.emit)
        self._runner.options_running.connect(self.options_running.emit)
        self._runner.options_simulated.connect(self.options_simulated.emit)
        self._runner.options_error.connect(self.options_error.emit)
        self._runner.results_saved.connect(self.results_saved.emit)
        self._runner.results_error.connect(self.results_error.emit)

        self._running_timer.start()
        self._runner.start()

    def cancel(self):
        if self._runner is None:
            return
        self._runner.cancel()
        self._running_timer.stop()

        self._runner.options_added.disconnect(self.options_added.emit)
        self._runner.options_running.disconnect(self.options_running.emit)
        self._runner.options_simulated.disconnect(self.options_simulated.emit)
        self._runner.options_error.disconnect(self.options_error.emit)
        self._runner.results_saved.disconnect(self.results_saved.emit)
        self._runner.results_error.disconnect(self.results_error.emit)

        self._runner = None

        self._spn_workers.setEnabled(True)
        self._txt_outputdir.setEnabled(True)
        self._chk_overwrite.setEnabled(True)
        self._btn_addtoqueue.setEnabled(False)
        self._btn_addalltoqueue.setEnabled(False)
        self._btn_start.setEnabled(True)
        self._btn_cancel.setEnabled(False)
        self._btn_close.setEnabled(True)
        self._btn_import.setEnabled(False)

    def is_running(self):
        return self._runner is not None and self._runner.is_alive()
class MovementEditor(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(QRect(100, 100, 400, 200))
        self.layout = QtGui.QGridLayout(self)
        #lblAssetType
        self.lblAssetType = QLabel("Asset Type")
        self.layout.addWidget(self.lblAssetType, 0, 0)
        #cmdAssetType
        self.cmdAssetType = QComboBox(self)
        self.cmdAssetType.addItems(DaoAsset().getAssetTypes())
        self.layout.addWidget(self.cmdAssetType, 0, 1)
        #lblAssetName
        self.lblAssetName = QLabel("Asset Name")
        self.layout.addWidget(self.lblAssetName, 1, 0)
        #cmdAssetName
        self.cmdAssetName = QComboBox(self)
        self.layout.addWidget(self.cmdAssetName, 1, 1)
        #lblCustody
        self.lblCustody = QLabel("Custody")
        self.layout.addWidget(self.lblCustody, 2, 0)
        #cmbCustody
        self.cmbCustody = QComboBox(self)
        custodyList = DaoCustody().getCustodyList()
        for (row) in custodyList:
            self.cmbCustody.addItem(row[1], row[0])
        self.layout.addWidget(self.cmbCustody, 2, 1)
        #lblBuySell
        self.lblBuySell = QLabel("Buy Sell")
        self.layout.addWidget(self.lblBuySell, 3, 0)
        #cmdBuySell
        self.cmdBuySell = QComboBox(self)
        self.cmdBuySell.addItem("BUY")
        self.cmdBuySell.addItem("SELL")
        self.layout.addWidget(self.cmdBuySell, 3, 1)
        #lblByAmount
        self.lblByAmount = QLabel("By Amount")
        self.layout.addWidget(self.lblByAmount, 4, 0)
        #chkByAmount
        self.chkByAmount = QCheckBox(self)
        self.layout.addWidget(self.chkByAmount, 4, 1)
        #lblGrossAmount
        self.lblGrossAmount = QLabel("Gross Amount")
        self.layout.addWidget(self.lblGrossAmount, 5, 0)
        #txtGrossAmount
        self.txtGrossAmount = QLineEdit(self)
        self.txtGrossAmount.setValidator(QDoubleValidator(
            0, 99999999, 6, self))
        self.layout.addWidget(self.txtGrossAmount, 5, 1)
        #lblAcquisitionDate
        self.lblAcquisitionDate = QLabel("Acquisition Date")
        self.layout.addWidget(self.lblAcquisitionDate, 6, 0)
        #cmdAcquisitionDate
        self.dateAcquisitionDate = QDateEdit(self)
        self.dateAcquisitionDate.setDisplayFormat("dd-MM-yyyy")
        self.dateAcquisitionDate.setDate(datetime.datetime.now())
        self.layout.addWidget(self.dateAcquisitionDate, 6, 1)
        #lblQuantity
        self.lblQuantity = QLabel("Quantity")
        self.layout.addWidget(self.lblQuantity, 7, 0)
        #txtQuantity
        self.txtQuantity = QLineEdit(self)
        self.txtQuantity.setValidator(QIntValidator(0, 1000000000, self))
        self.layout.addWidget(self.txtQuantity, 7, 1)
        #lblPrice
        self.lblPrice = QLabel("Price")
        self.layout.addWidget(self.lblPrice, 8, 0)
        #txtPrice
        self.txtPrice = QLineEdit(self)
        self.txtPrice.setValidator(QDoubleValidator(0, 99999999, 6, self))
        self.layout.addWidget(self.txtPrice, 8, 1)
        #lblRate
        self.lblRate = QLabel("Rate")
        self.layout.addWidget(self.lblRate, 9, 0)
        #txtRate
        self.txtRate = QLineEdit(self)
        self.txtRate.setValidator(QDoubleValidator(0, 99999999, 4, self))
        self.txtRate.setEnabled(0)
        self.layout.addWidget(self.txtRate, 9, 1)
        #lblNetAmount
        self.lblNetAmount = QLabel("Net Amount")
        self.layout.addWidget(self.lblNetAmount, 10, 0)
        #txtNetAmount
        self.txtNetAmount = QLineEdit(self)
        self.txtNetAmount.setEnabled(0)
        self.txtNetAmount.setValidator(QDoubleValidator(0, 99999999, 6, self))
        self.layout.addWidget(self.txtNetAmount, 10, 1)
        #lblCommissionPercentage
        self.lblCommissionPercentage = QLabel("Commission Percentage")
        self.layout.addWidget(self.lblCommissionPercentage, 11, 0)
        #txtCommissionPercentage
        self.txtCommissionPercentage = QLineEdit(self)
        self.txtCommissionPercentage.setValidator(
            QDoubleValidator(0, 9999999, 6, self))
        self.layout.addWidget(self.txtCommissionPercentage, 11, 1)
        #lblCommissionAmount
        self.lblCommissionAmount = QLabel("Commission Amount")
        self.layout.addWidget(self.lblCommissionAmount, 12, 0)
        #txtCommissionAmmount
        self.txtCommissionAmount = QLineEdit(self)
        self.txtCommissionAmount.setEnabled(0)
        self.txtCommissionAmount.setValidator(
            QDoubleValidator(0, 9999999, 6, self))
        self.layout.addWidget(self.txtCommissionAmount, 12, 1)
        #lblCommissionAmount
        self.lblCommissionVATAmount = QLabel("Commission VAT Amount")
        self.layout.addWidget(self.lblCommissionVATAmount, 13, 0)
        #txtCommissionAmmount
        self.txtCommissionVATAmount = QLineEdit(self)
        self.txtCommissionVATAmount.setEnabled(0)
        self.txtCommissionVATAmount.setValidator(
            QDoubleValidator(0, 9999999, 6, self))
        self.layout.addWidget(self.txtCommissionVATAmount, 13, 1)
        #lblTenor
        self.lblTenor = QLabel("Tenor")
        self.layout.addWidget(self.lblTenor, 14, 0)
        #txtTenor
        self.txtTenor = QLineEdit(self)
        self.txtTenor.setEnabled(0)
        self.txtTenor.setValidator(QDoubleValidator(0, 9999999, 0, self))
        self.layout.addWidget(self.txtTenor, 14, 1)
        #btnAdd
        self.btnAdd = QPushButton("Add", self)
        self.layout.addWidget(self.btnAdd)
        #btnClear
        self.btnClear = QPushButton("Clear", self)
        self.layout.addWidget(self.btnClear)
        #clearEditor
        self.clearEditor()
        self.initListener()

    def initListener(self):
        self.cmdBuySell.connect(
            self.cmdBuySell,
            QtCore.SIGNAL("currentIndexChanged(const QString&)"),
            self.calculateNetAmount)
        self.chkByAmount.connect(self.chkByAmount,
                                 QtCore.SIGNAL("stateChanged(int)"),
                                 self.configEditorByAmount)
        self.txtGrossAmount.connect(self.txtGrossAmount,
                                    SIGNAL("editingFinished()"),
                                    self.calculatePrice)
        self.cmdAssetType.connect(
            self.cmdAssetType,
            QtCore.SIGNAL("currentIndexChanged(const QString&)"),
            self.configEditorByAssetType)
        self.txtQuantity.connect(self.txtQuantity,
                                 SIGNAL("textChanged(QString)"),
                                 self.calculateGrossAmount)
        self.txtQuantity.connect(self.txtQuantity,
                                 SIGNAL("textChanged(QString)"),
                                 self.calculatePrice)
        self.txtPrice.connect(self.txtPrice, SIGNAL("textChanged(QString)"),
                              self.calculateGrossAmount)
        self.cmdAssetName.connect(
            self.cmdAssetName, SIGNAL("currentIndexChanged(const QString&)"),
            self.setDefaultCustody)
        self.txtCommissionPercentage.connect(self.txtCommissionPercentage,
                                             SIGNAL("textChanged(QString)"),
                                             self.calculateCommission)
        self.btnAdd.clicked.connect(self.addMovement)
        self.btnClear.clicked.connect(self.clearEditor)

    def addMovement(self):
        buySell = self.cmdBuySell.currentText()
        assetOID = self.cmdAssetName.itemData(self.cmdAssetName.currentIndex())
        custodyOID = self.cmbCustody.itemData(self.cmbCustody.currentIndex())
        acquisitionDate = self.dateAcquisitionDate.date()
        quantity = self.txtQuantity.text()
        if self.cmdAssetType.currentText() == 'BOND':
            rate = self.txtRate.text()
            if self.txtTenor.text() == '':
                tenor = None
            else:
                tenor = self.txtTenor.text()
            maturityDate = acquisitionDate.toPython() + datetime.timedelta(
                days=int(tenor))
        else:
            rate = None
            maturityDate = None
            tenor = None
        price = self.txtPrice.text()
        grossAmount = self.txtGrossAmount.text()
        netAmount = self.txtNetAmount.text()
        commissionPercentage = self.txtCommissionPercentage.text()
        commissionAmount = self.txtCommissionAmount.text()
        commissionVATAmount = self.txtCommissionVATAmount.text()

        movement = Movement(None)
        movement.setAttr(None, assetOID, buySell, (acquisitionDate).toPython(),
                         quantity, price, rate, grossAmount, netAmount,
                         commissionPercentage, commissionAmount,
                         commissionVATAmount, tenor, custodyOID, maturityDate,
                         None, None)
        DaoMovement.insertMovement(movement)
        self.clearEditor()

    def clearEditor(self):
        #self.cmdAssetType.set
        self.txtQuantity.setText(None)
        self.txtPrice.setText(None)
        self.txtGrossAmount.setText("0")
        self.txtNetAmount.setText("0")
        self.txtRate.setText("0")
        #configDefaultCommission
        if self.cmdAssetType.currentText() == 'EQUITY':
            self.txtCommissionPercentage.setText(
                str(Constant.CONST_DEF_EQUITY_COMMISSION_PERCENTAGE))
        else:
            self.txtCommissionPercentage.setText(
                str(Constant.CONST_DEF_OTHER_COMMISSION_PERCENTAGE))
        self.txtTenor.setText("")
        self.dateAcquisitionDate.setDate(datetime.datetime.now())
        self.configEditorByAmount()
        self.configEditorByAssetType()

    def setDefaultCustody(self):
        defaultCustodyID = DaoCustody().getDefaultCustody(
            self.cmdAssetName.currentText())
        for (row) in defaultCustodyID:
            self.cmbCustody.setCurrentIndex(self.cmbCustody.findData(row[0]))

    def configEditorByAssetType(self):
        self.cmdAssetName.clear()
        #loadAssetNames
        assetNameList = DaoAsset().getAssetNames(
            self.cmdAssetType.currentText())
        for (assetName) in assetNameList:
            self.cmdAssetName.addItem(assetName[1], assetName[0])
        #setPriceOrRate
        if self.cmdAssetType.currentText(
        ) == 'EQUITY' or self.cmdAssetType.currentText() == 'FUND':
            self.txtPrice.setEnabled(1)
            self.txtRate.setEnabled(0)
            self.txtRate.setText("0")
            self.txtTenor.setEnabled(0)
            self.txtTenor.setText(None)
        else:
            self.txtPrice.setEnabled(0)
            self.txtRate.setEnabled(1)
            self.txtPrice.setText("0")
            self.txtTenor.setEnabled(1)
            self.txtTenor.setText(None)
        #configDefaultCommission
        if self.cmdAssetType.currentText() == 'EQUITY':
            self.txtCommissionPercentage.setText(
                str(Constant.CONST_DEF_EQUITY_COMMISSION_PERCENTAGE))
        else:
            self.txtCommissionPercentage.setText(
                str(Constant.CONST_DEF_OTHER_COMMISSION_PERCENTAGE))

    def configEditorByAmount(self):
        if self.chkByAmount.isChecked():
            self.txtPrice.setEnabled(0)
            self.txtGrossAmount.setEnabled(1)
        else:
            self.txtPrice.setEnabled(1)
            self.txtGrossAmount.setEnabled(0)

    def calculateCommission(self):
        commissionPercentage = self.txtCommissionPercentage.text()
        grossAmount = self.txtGrossAmount.text()
        if commissionPercentage >= 0:
            commissionAmount = float(grossAmount) * float(commissionPercentage)
            self.txtCommissionAmount.setText(
                str('{0:.6f}'.format(commissionAmount)))
            commissionVATAmount = commissionAmount * Constant.CONST_IVA_PERCENTAGE
            self.txtCommissionVATAmount.setText(
                str('{0:.6f}'.format(commissionVATAmount)))
            self.calculateNetAmount()

    def calculatePrice(self):
        quantity = self.txtQuantity.text()
        amount = self.txtGrossAmount.text()
        if (quantity is not u"" or None) and (amount is not u"" or None):
            self.txtPrice.setText(
                str('{0:.6f}'.format(float(amount) / float(quantity))))

    def calculateNetAmount(self):
        buySell = self.cmdBuySell.currentText()
        grossAmount = float(self.txtGrossAmount.text())
        commissionAmount = float(self.txtCommissionAmount.text())
        commissionVATAmount = float(self.txtCommissionVATAmount.text())
        if buySell == 'BUY':
            netAmount = grossAmount + commissionVATAmount + commissionAmount
        else:
            netAmount = grossAmount - commissionVATAmount - commissionAmount
        self.txtNetAmount.setText(str(netAmount))

    def calculateGrossAmount(self):
        quantity = self.txtQuantity.text()
        price = self.txtPrice.text()
        if (not self.chkByAmount.isChecked()) and (
                quantity is not u"" or None) and (price is not u"" or None):
            self.txtGrossAmount.setText(
                str('{0:.6f}'.format(float(quantity) * float(price))))
        self.calculateCommission()
示例#20
0
class MassAttribute_UI(QDialog):
    """
    The main UI
    """
    class Applikator(QObject):
        """
        This is the core applier which toggle the display of the corresponding widget and handling events' connections
        """
        def __init__(self, parent=None):
            super(MassAttribute_UI.Applikator, self).__init__()
            self.root = parent

        def widget_event(self, t):
            """
            Return the correct widget's event depending on attribute's type
            :param t: the attribute's type
            :type  t: str
            :return: the event
            :rtype : Signal
            """
            return {
                'float': self.root.W_EDI_float.valueChanged,
                'enum': self.root.W_EDI_enum.currentIndexChanged,
                'int': self.root.W_EDI_int.valueChanged,
                'bool': self.root.W_EDI_bool.stateChanged,
                'str': self.root.W_EDI_str.textChanged,
                'd3': self.root.W_EDI_d3.valuesChanged,
                'd4': self.root.W_EDI_d4.valuesChanged,
                'color': self.root.W_EDI_color.colorChanged
            }[t]

        def unset_editors(self):
            """
            Toggle off all editors and disconnect the current one
            """
            for widget in (self.root.W_EDI_float, self.root.W_EDI_int,
                           self.root.W_EDI_enum, self.root.W_EDI_bool,
                           self.root.W_EDI_str, self.root.W_EDI_d3,
                           self.root.W_EDI_d4, self.root.W_EDI_color):
                widget.setVisible(False)

            # trying to force disconnection
            try:
                self.widget_event(self.root.ctx).disconnect(
                    self.root.apply_value)
            except (KeyError, RuntimeError):
                pass

        def prepare(applier_name):
            """
            A decorator to prepare the attribute depending on type for the corresponding widget and getting the
            attribute's value
            :param applier_name: attribute's type
            :type  applier_name: str
            """
            def sub_wrapper(func):
                def wrapper(self, attr_path):
                    self.unset_editors()
                    self.root.ctx = applier_name
                    self.root.__getattribute__('W_EDI_%s' %
                                               applier_name).setVisible(True)
                    ret = func(self, cmds.getAttr(attr_path), attr_path)
                    return ret

                return wrapper

            return sub_wrapper

        @staticmethod
        def get_bounds(obj, attr, min_default, max_default):
            """
            Try to retrieve the range for the given attribute, if min or max fail it'll set default values
            :param         obj: the object's name
            :type          obj: str
            :param        attr: attribute's name
            :type         attr: str
            :param min_default: minimum default value
            :param max_default: max default value
            :type  min_default: float | int
            :type  max_default: float | int
            :return: minimum, maximum
            :rtype : tuple
            """
            try:
                assert cmds.attributeQuery(attr, n=obj, mxe=True)
                maxi = cmds.attributeQuery(attr, n=obj, max=True)[0]
            except (RuntimeError, AssertionError):
                maxi = max_default
            try:
                assert cmds.attributeQuery(attr, n=obj, mne=True)
                mini = cmds.attributeQuery(attr, n=obj, min=True)[0]
            except (RuntimeError, AssertionError):
                mini = min_default
            return mini, maxi

        @prepare('float')
        def apply_float(self, value, path):
            """
            Float attribute case
            :param value: attribute's value
            :param  path: attribute's path = obj.attr
            """
            obj, attr = path.split('.', 1)
            self.root.W_EDI_float.setRange(
                *self.get_bounds(obj, attr, -100.0, 100.0))
            self.root.W_EDI_float.setValue(value)

        @prepare('enum')
        def apply_enum(self, value, path):
            """Enum case"""
            self.root.W_EDI_enum.clear()
            obj, attr = path.split('.', 1)
            try:
                enums = [
                    enum.split('=')[0] for enum in cmds.attributeQuery(
                        attr, n=obj, listEnum=True)[0].split(':')
                ]
            except RuntimeError:
                self.apply_int(path)
            else:
                self.root.W_EDI_enum.addItems(enums)
                self.root.W_EDI_enum.setCurrentIndex(
                    enums.index(cmds.getAttr(path, asString=True)))

        @prepare('int')
        def apply_int(self, value, path):
            """Integer case"""
            obj, attr = path.split('.', 1)
            self.root.W_EDI_int.setRange(
                *self.get_bounds(obj, attr, -1000, 1000))
            self.root.W_EDI_int.setValue(value)

        @prepare('bool')
        def apply_bool(self, value, path):
            """Boolean case"""
            self.root.W_EDI_bool.setChecked(value)
            self.root.W_EDI_bool.setText(path.split('.', 1)[1])

        @prepare('str')
        def apply_str(self, value, path):
            """String case"""
            self.root.W_EDI_str.setText(value)

        @prepare('d3')
        def apply_d3(self, value, path):
            """3D array case"""
            self.root.W_EDI_d3.setValues(value[0])

        @prepare('d4')
        def apply_d4(self, value, path):
            """4D array case"""
            self.root.W_EDI_d4.setValues(value[0])

        @prepare('color')
        def apply_color(self, value, path):
            """Color case"""
            try:
                colors = value[0]
                self.root.W_EDI_color.setColor([int(c * 255) for c in colors])
            except TypeError:
                self.apply_int(value, path)

    class Attribute(str):
        """
        A custom string attribute class to ship more information into the string variable
        """
        def __new__(cls, path='', super_type=Object):
            obj, attr = path.split('.', 1)

            str_obj = str.__new__(cls, attr)

            str_obj.obj, str_obj.attr = obj, attr
            str_obj.path = path
            str_obj.super_type = super_type
            str_obj.type = None

            return str_obj

    # static variables to pre-load icons and attributes short names
    ctx_icons = {
        'float': QIcon(':render_decomposeMatrix.png'),
        'enum': QIcon(':showLineNumbers.png'),
        'bool': QIcon(':out_decomposeMatrix.png'),
        'time': QIcon(':time.svg'),
        'byte': QIcon(':out_defaultTextureList.png'),
        'angle': QIcon(':angleDim.png'),
        'string': QIcon(':text.png'),
        'float3': QIcon(':animCurveTA.svg'),
        'float4': QIcon(':animCurveTA.svg'),
        'color': QIcon(':clampColors.svg')
    }

    for ctx in ('doubleLinear', 'double', 'long', 'short'):
        ctx_icons[ctx] = ctx_icons['float']

    ctx_icons['double3'] = ctx_icons['float3']
    ctx_icons['double4'] = ctx_icons['float4']

    ctx_wide = {
        'float': ('float', 'doubleLinear', 'double', 'long', 'short'),
        'enum': ('enum', ),
        'bool': ('bool', ),
        'time': ('time', ),
        'byte': ('byte', ),
        'angle': ('doubleAngle', ),
        'string': ('string', ),
        'float3': ('double3', 'float3'),
        'float4': ('double4', 'float4'),
        'color': ('color', )
    }

    def __init__(self, parent=None):
        super(MassAttribute_UI, self).__init__(parent)
        # Abstract
        self.applier = self.Applikator(self)
        self.selection = []
        self.callback = None
        self.ctx = None
        # storing found attributes' types to avoid double check
        self.solved = {}
        self.setLocale(QLocale.C)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setAttribute(Qt.WA_QuitOnClose)

        self.setFixedWidth(300)
        self.setWindowTitle('Massive Attribute Modifier')

        # UI
        L_main = QVBoxLayout()

        self.WV_title = QLabel('')
        self.WV_title.setVisible(False)
        self.WV_title.setFont(QFont('Verdana', 10))
        self.WV_title.setContentsMargins(0, 0, 0, 7)

        self.WB_select = QPushButton('Select')
        self.WB_select.setVisible(False)
        self.WB_select.setFixedWidth(50)
        self.WB_select.clicked.connect(lambda: cmds.select(self.selection))

        self.WB_update = QPushButton('Update')
        self.WB_update.setFixedWidth(50)
        self.WB_update.clicked.connect(
            lambda: self.update_attributes(cmds.ls(sl=True)))

        self.WV_search = Filter()
        self.WV_search.textChanged.connect(self.filter)

        self.WC_cases = QCheckBox('Case sensitive')
        self.WC_cases.stateChanged.connect(self.filter)

        self.WC_types = QCheckBox('Type filtering')

        self.WL_attrtype = QComboBox()
        self.WL_attrtype.setEnabled(False)

        for i, ctx in enumerate(sorted(self.ctx_wide)):
            self.WL_attrtype.addItem(ctx.title())
            self.WL_attrtype.setItemIcon(i, self.ctx_icons[ctx])

        L_attrtype = line(self.WC_types, self.WL_attrtype)

        self.WC_types.stateChanged.connect(
            partial(self.update_attributes, self.selection))
        self.WC_types.stateChanged.connect(self.WL_attrtype.setEnabled)
        self.WL_attrtype.currentIndexChanged.connect(self.filter)

        self.WC_liveu = QCheckBox('Live')
        self.WC_liveu.stateChanged.connect(self.WB_update.setDisabled)
        self.WC_liveu.stateChanged.connect(self.set_callback)

        self.WC_histo = QCheckBox('Load history')
        self.WC_histo.setChecked(True)
        self.WC_histo.stateChanged.connect(
            partial(self.update_attributes, self.selection))

        self.WC_child = QCheckBox('Children')
        self.WC_child.stateChanged.connect(
            partial(self.update_attributes, self.selection))

        options = group(
            'Options', line(self.WC_cases, L_attrtype),
            line(self.WC_child, self.WC_histo, self.WC_liveu, self.WB_update))
        options.layout().setSpacing(2)

        self.WL_attributes = QTreeWidget()
        self.WL_attributes.setStyleSheet(
            'QTreeView {alternate-background-color: #1b1b1b;}')
        self.WL_attributes.setAlternatingRowColors(True)
        self.WL_attributes.setHeaderHidden(True)
        self.WL_attributes.setRootIsDecorated(False)

        self.objs_attr = set()
        self.shps_attr = set()

        self.W_EDI_float = FloatBox()
        self.W_EDI_int = IntBox()
        self.W_EDI_enum = QComboBox()
        self.W_EDI_bool = QCheckBox()
        self.W_EDI_str = QLineEdit()
        self.W_EDI_d3 = Double3()
        self.W_EDI_d4 = Double4()
        self.W_EDI_color = ColorPicker()

        # Final layout
        L_title = line(self.WV_title, self.WB_select)
        L_title.setStretch(0, 1)
        L_main.addLayout(L_title)
        L_main.setAlignment(Qt.AlignLeft)
        L_main.addWidget(self.WV_search)
        L_main.addWidget(options)
        L_main.addWidget(self.WL_attributes)
        L_edits = col(self.W_EDI_bool, self.W_EDI_int, self.W_EDI_float,
                      self.W_EDI_enum, self.W_EDI_str, self.W_EDI_d3,
                      self.W_EDI_d4, self.W_EDI_color)
        L_edits.setContentsMargins(0, 8, 0, 0)
        L_main.addLayout(L_edits)
        L_main.setStretch(3, 1)
        L_main.setSpacing(2)

        self.appliers = {
            'float': self.applier.apply_float,
            'enum': self.applier.apply_enum,
            'bool': self.applier.apply_bool,
            'time': self.applier.apply_float,
            'byte': self.applier.apply_int,
            'angle': self.applier.apply_float,
            'string': self.applier.apply_str,
            'float3': self.applier.apply_d3,
            'float4': self.applier.apply_d4,
            'color': self.applier.apply_color
        }

        self.setLayout(L_main)

        # final settings
        self.WL_attributes.itemSelectionChanged.connect(self.update_setter)
        self.applier.unset_editors()

    def closeEvent(self, *args, **kwargs):
        self.set_callback(False)

    def set_callback(self, state):
        """
        Toggle selection event callback
        :param state: checkbox's state
        :type  state: bool | int
        """
        if state and not self.callback:
            self.callback = MEventMessage.addEventCallback(
                'SelectionChanged', self.update_attributes)
            self.update_attributes(cmds.ls(sl=True))

        elif not state and self.callback:
            MMessage.removeCallback(self.callback)
            self.callback = None

    @staticmethod
    def format_title(nodes):
        """
        Extract the matching characters from a given nodes selection, if begin matches it will return "joint*" with a
        wildcard when names don't match
        :param nodes: objects' list
        :type  nodes: list | tuple
        :return: the formatted name with the corresponding characters
        :rtype : str
        """
        res = None

        if nodes:
            # we get the first node as a reference
            node = nodes[0]
            # and compare with the other nodes
            subs = [w for w in nodes if w != node]

            l = 1
            valid = True
            # will continue until l (length) match the full name's length or until names don't match
            while l < len(node) and valid:
                for sub in subs:
                    if not sub.startswith(node[:l]):
                        valid = False
                        break

                else:
                    l += 1

            # if matching characters isn't long enough we only display the number of nodes selected
            if l <= 3:
                res = '%i objects' % len(nodes)

            # otherwise showing matching pattern
            elif l < len(node) or len(nodes) > 1:
                res = node[:l - 1] + '* (%i objects)' % len(nodes)

            else:
                res = node

        return res

    @staticmethod
    def get_history(node):
        """
        Extract history for the given node
        :rtype: list
        """
        return cmds.listHistory(node, il=2, pdo=True) or []

    @staticmethod
    def get_shapes(node):
        """
        Extract shape(s) for the given node
        :rtype: list
        """
        return cmds.listRelatives(node, s=True, ni=True, f=True)

    def get_attributes_type(self, attrs):
        """
        For a given list of attributes of type Attribute, will loop through and fill the type parameter of the
         attribute with the corresponding type, if type is invalid or not handled, it'll remove it
        :param attrs: attributes' list
        :type  attrs: [MassAttribute_UI.Attribute]
        :return: cleaned and filled attributes' list
        :rtype: [MassAttribute_UI.Attribute]
        """
        attrs = list(attrs)
        # first we sort the attributes' list
        attrs.sort()

        # then we try to extract the attribute's type
        for i, attr in enumerate(attrs):
            try:
                if attr.attr in self.solved:
                    attr.type = self.solved[attr.attr]
                    raise RuntimeError
                tpe = cmds.getAttr(attr.path, typ=True)
                assert tpe
                attr.type = tpe
                self.solved[attr.attr] = tpe
            except (AssertionError, ValueError, RuntimeError):
                pass

        # defining a to-remove list
        rm_list = set()

        layers = {'3': 'XYZ', '4': 'XYZW'}
        for i, attr in enumerate(attrs):
            if i in rm_list:
                continue

            # we handle some special cases here, if ever the attribute list contains RGB and separate R, G and B we
            # assume it's a color, if it's a double3 or float3 and we find the corresponding XYZ, we remove then to
            # avoid duplicates

            if attr.endswith('RGB'):
                if '%sR' % attr[:-3] in attrs:
                    attr.type = 'color'
                    for chan in 'RGB':
                        rm_list.add(attrs.index('%s%s' % (attr[:-3], chan)))

            # if the attribute's type isn't in the list, we remove
            elif attr.type not in MassAttribute_UI.ctx_icons:
                rm_list.add(i)

            elif attr.endswith('R'):
                if '%sG' % attr[:-1] in attrs and attr[:-1] in attrs:
                    attr.type = 'color'
                    for chan in 'RGB':
                        rm_list.add(attrs.index('%s%s' % (attr[:-1], chan)))

            elif attr.type in ('double3', 'double4', 'float3', 'float4'):
                if '%sX' % attr in attrs:
                    for chan in layers[attr.type[-1]]:
                        rm_list.add(attrs.index('%s%s' % (attr, chan)))

        # finally cleaning the list
        for i in sorted(rm_list, reverse=True):
            attrs.pop(i)

        return attrs

    def apply_value(self, value):
        """
        When the value is modified in the UI, we forward the given value and applies to the object's
        :param value: attribute's value, mixed type
        :type  value: mixed
        """
        # We get the only selected object in list and get it's super type (Shape, History or Object) and
        # type (float, int, string)
        item = self.WL_attributes.selectedItems()[0]
        attr = item.attribute
        shape = attr.super_type == Shape
        histo = attr.super_type == History
        tpe = item.attribute.type

        # eq dict for each context
        value = {
            'bool': bool,
            'int': int,
            'float': float,
            'enum': int,
            'str': str,
            'd3': list,
            'd4': list,
            'color': list
        }[self.ctx](value)

        # converting the selection into a set
        cmds.undoInfo(openChunk=True)
        targets = set(self.selection)

        # we propagate to children if 'Children' checkbox is on
        if self.WC_child.isChecked():
            for obj in list(targets):
                targets |= set(cmds.listRelatives(obj, ad=True))

        # if the target attribute is on the history, we add all selection's history to the list
        if histo:
            for obj in list(targets):
                targets.remove(obj)
                targets |= set(self.get_history(obj))

        # then we loop through target objects
        for obj in targets:
            # if the target is on the shape we get object's shape
            if shape and not histo:
                shapes = self.get_shapes(obj)

                if obj in shapes:
                    continue
                else:
                    obj = shapes[0]

            # then we try to apply depending on attribute's type
            try:
                correct_path = attr.path.replace(attr.obj, obj)

                if tpe == 'string':
                    cmds.setAttr(correct_path, value, type='string')

                elif tpe in ('double3', 'double4', 'float3', 'float4',
                             'color'):
                    cmds.setAttr(correct_path,
                                 *value,
                                 type='double%d' % len(value))

                else:
                    cmds.setAttr(correct_path, value)

            except RuntimeError:
                pass

        cmds.undoInfo(closeChunk=True)

    def update_setter(self):
        """
        When the list's selection changes we update the applier widget
        """
        item = self.WL_attributes.selectedItems()
        # abort if no item is selected
        if not len(item):
            return

        # getting attribute's parameter
        attr = item[0].attribute

        if len(self.selection):
            try:
                # looping until we find a context having the current attribute's type
                for applier in self.ctx_wide:
                    if attr.type in self.ctx_wide[applier]:
                        break
                # then we apply for the given path (obj.attribute)
                self.appliers[applier](attr.path)

                # and connecting event to the self.apply_value function
                self.applier.widget_event(self.ctx).connect(self.apply_value)

            # otherwise selection or type is invalid
            except IndexError:
                self.ctx = None

    def update_attributes(self, selection=None, *args):
        """
        Update the attributes for the given selection, looping through objects' attributes, finding attr in common
        between all objects then cleaning the lists, doing the same for shapes and / or histories
        :param selection: object's selection
        """
        # redefining lists as set to intersect union etc
        self.objs_attr = set()
        self.shps_attr = set()

        # pre init
        self.WL_attributes.clear()
        self.applier.unset_editors()

        self.selection = selection or (cmds.ls(
            sl=True) if self.WC_liveu.isChecked() else self.selection)

        self.WV_title.setText(self.format_title(self.selection))
        self.WV_title.setVisible(bool(len(self.selection)))
        self.WB_select.setVisible(bool(len(self.selection)))

        if not len(self.selection):
            return

        def get_usable_attrs(obj, super_type):
            """
            Small internal function to get a compatible attributes' list for the given object and assign the given
            super_type to it (Object, Shape or History)
            :param        obj: object's name
            :type         obj: str
            :param super_type: attribute's main type
            :type  super_type: Object | Shape | History
            :return:
            """
            return set([
                MassAttribute_UI.Attribute('%s.%s' % (obj, attr), super_type)
                for attr in cmds.listAttr(
                    obj, se=True, ro=False, m=True, w=True)
            ])

        if len(self.selection):
            self.objs_attr = get_usable_attrs(self.selection[0], Object)

            # if we also want the object's history we add it to the initial set
            if self.WC_histo.isChecked():
                for histo in self.get_history(self.selection[0]):
                    self.objs_attr |= get_usable_attrs(histo, History)

            # filling the shape's set
            for shape in (self.get_shapes(self.selection[0]) or []):
                self.shps_attr |= get_usable_attrs(shape, Shape)

            # if selection's length bigger than one we compare by intersection with the other sets
            if len(self.selection) > 1:
                for obj in self.selection:
                    sub_attr = get_usable_attrs(obj, Object)

                    if self.WC_histo.isChecked():
                        for histo in self.get_history(obj):
                            sub_attr |= get_usable_attrs(histo, History)

                    self.objs_attr.intersection_update(sub_attr)

                    for shape in (self.get_shapes(self.selection[0]) or []):
                        self.shps_attr.intersection_update(
                            get_usable_attrs(shape, Shape))

            # finally getting all intersecting attributes' types
            self.objs_attr = self.get_attributes_type(self.objs_attr)
            self.shps_attr = self.get_attributes_type(self.shps_attr)

        # and filtering the list
        self.filter()

    def add_set(self, iterable, title=None):
        """
        Adding the given iterable to the list with a first Separator object with given title
        :param iterable: list of item's attributes
        :param    title: Separator's name
        """
        if len(iterable):
            # if title is given we first add a Separator item to indicate coming list title
            if title:
                self.WL_attributes.addTopLevelItem(
                    QTreeWidget_Separator(title))

            items = []
            for attr in sorted(iterable):
                item = QTreeWidgetItem([attr])
                # assigning the attribute itself inside a custom parameter
                item.attribute = attr
                items.append(item)

            # finally adding all the items to the list
            self.WL_attributes.addTopLevelItems(items)

    def filter(self):
        """
        Filter the list with UI's parameters, such as name or type filtering, etc
        """
        # pre cleaning
        self.WL_attributes.clear()

        # using regex compile to avoid re execution over many attributes
        mask = self.WV_search.text()
        case = 0 if self.WC_cases.isChecked() else re.IGNORECASE
        re_start = re.compile(r'^%s.*?' % mask, case)
        re_cont = re.compile(r'.*?%s.*?' % mask, case)

        # getting the four different lists
        obj_start = set([at for at in self.objs_attr if re_start.search(at)])
        shp_start = set([at for at in self.shps_attr if re_start.search(at)])

        # if type filtering is one we only extract the wanted attribute's type
        if self.WC_types.isChecked():
            obj_start = set([
                at for at in obj_start if at.type in self.ctx_wide[
                    self.WL_attrtype.currentText().lower()]
            ])
            shp_start = set([
                at for at in shp_start if at.type in self.ctx_wide[
                    self.WL_attrtype.currentText().lower()]
            ])

        # finally adding the current sets if there is a mask we add the also the containing matches
        if mask:
            # getting contains filtering and type containers filtering
            obj_contains = obj_start.symmetric_difference(
                set([at for at in self.objs_attr if re_cont.search(at)]))
            shp_contains = shp_start.symmetric_difference(
                set([at for at in self.shps_attr if re_cont.search(at)]))
            if self.WC_types.isChecked():
                obj_contains = set([
                    at for at in obj_contains if at.type in self.ctx_wide[
                        self.WL_attrtype.currentText().lower()]
                ])
                shp_contains = set([
                    at for at in shp_contains if at.type in self.ctx_wide[
                        self.WL_attrtype.currentText().lower()]
                ])

            # adding the sets
            self.add_set(obj_start, 'Obj attributes starting with')
            self.add_set(obj_contains, 'Obj attributes containing')
            self.add_set(shp_start, 'Shape attributes starting with')
            self.add_set(shp_contains, 'Shape attributes containing')

        else:
            self.add_set(obj_start, 'Object\'s attributes')
            self.add_set(shp_start, 'Shape\'s attributes')

        # and we select the first one if ever there is something in the list
        if self.WL_attributes.topLevelItemCount():
            self.WL_attributes.setItemSelected(
                self.WL_attributes.topLevelItem(1), True)
示例#21
0
class _SummaryOptionsToolItem(_ResultsToolItem):

    def _initUI(self):
        # Variables
        self._parameter_getters = {}

        def _program_getter(options):
            programs = list(options.programs)
            if len(programs) == 1:
                return programs[0]
            else:
                return list(programs)
        self._parameter_getters['program'] = _program_getter

        options = self.options()
        for name, getter in iter_getters(options):
            values = np.array(getter(options), ndmin=1)
            if len(values) < 2:
                continue
            self._parameter_getters[name] = getter

        # Actions
        act_add_series = QAction(getIcon("list-add"), "Add series", self)
        act_remove_series = QAction(getIcon("list-remove"), "Remove series", self)
        act_clear_series = QAction(getIcon("edit-clear"), "Clear", self)

        # Widgets
        self._cb_result_key = QComboBox()

        self._cb_x_parameter = QComboBox()
        self._cb_x_parameter.addItems(list(self._parameter_getters.keys()))

        self._lst_series = QListView()
        self._lst_series.setModel(_SeriesModel())

        tlb_series = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_series.addWidget(spacer)
        tlb_series.addAction(act_add_series)
        tlb_series.addAction(act_remove_series)
        tlb_series.addAction(act_clear_series)

        self._chk_normalize = QCheckBox('Normalize series')

        # Layouts
        layout = _ResultsToolItem._initUI(self)
        layout.addRow("Result", self._cb_result_key)
        layout.addRow("X parameter", self._cb_x_parameter)
        layout.addRow("Series", self._lst_series)
        layout.addRow(tlb_series)
        layout.addRow(self._chk_normalize)

        # Signals
        act_add_series.triggered.connect(self._onAddSeries)
        act_remove_series.triggered.connect(self._onRemoveSeries)
        act_clear_series.triggered.connect(self._onClearSeries)
        self._lst_series.doubleClicked.connect(self._onSeriesDoubleClicked)
        self._cb_result_key.currentIndexChanged.connect(self._onResultKeyChanged)
        self._chk_normalize.stateChanged.connect(self.stateChanged)

        # Defaults
        keys = set()
        for container in self.results():
            for key, result in container.items():
                if not isinstance(result, _SummarizableResult):
                    continue
                keys.add(key)
        self._cb_result_key.addItems(sorted(keys))

        return layout

    def _onResultKeyChanged(self):
        ndim = self._getResultDimensions()
        self._cb_x_parameter.setEnabled(ndim == 1)

    def _onAddSeries(self):
        # Dialog
        result_key = self._cb_result_key.currentText()

        if self._getResultDimensions() > 1:
            x_parameter_name = None
        else:
            x_parameter_name = self._cb_x_parameter.currentText()

        dialog = _SeriesDialog(self.results(), result_key,
                               self._parameter_getters, x_parameter_name)
        if not dialog.exec_():
            return

        # Create series
        series_name = dialog.name()
        parameter_value = dialog.parameterValue()
        summary_key = dialog.summaryKey()

        conditions = []
        for name, value in parameter_value.items():
            conditions.append((name, self._parameter_getters[name], value))

        model = self._lst_series.model()
        model.addSeries(_Series(series_name, conditions, summary_key))

        # Update widgets
        self._cb_result_key.setEnabled(False)
        self._cb_x_parameter.setEnabled(False)

        self.stateChanged.emit()

    def _onRemoveSeries(self):
        selection = self._lst_series.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Series", "Select a row")
            return

        model = self._lst_series.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.removeSeries(row)

        enabled = model.rowCount() == 0
        self._cb_result_key.setEnabled(enabled)
        self._cb_x_parameter.setEnabled(enabled)

        self.stateChanged.emit()

    def _onClearSeries(self):
        model = self._lst_series.model()
        model.clearSeries()

        self._cb_result_key.setEnabled(True)
        self._cb_x_parameter.setEnabled(True)

        self.stateChanged.emit()

    def _onSeriesDoubleClicked(self, index):
        series = self._lst_series.model().series(index.row())

        # Dialog
        result_key = self._cb_result_key.currentText()

        if self._getResultDimensions() > 1:
            x_parameter_name = None
        else:
            x_parameter_name = self._cb_x_parameter.currentText()

        dialog = _SeriesDialog(self.results(), result_key,
                               self._parameter_getters, x_parameter_name,
                               series)
        if not dialog.exec_():
            return

        # Create series
        series_name = dialog.name()
        parameter_value = dialog.parameterValue()
        summary_key = dialog.summaryKey()

        conditions = []
        for name, value in parameter_value.items():
            conditions.append((name, self._parameter_getters[name], value))

        model = self._lst_series.model()
        model.updateSeries(index.row(),
                           _Series(series_name, conditions, summary_key))

        self.stateChanged.emit()

    def _getResultDimensions(self):
        result_key = self._cb_result_key.currentText()

        for container in self.results():
            try:
                result = container[result_key]
            except KeyError:
                continue
            ndim = result.get_dimensions()

        return ndim

    def resultKey(self):
        return self._cb_result_key.currentText() or None

    def xParameterName(self):
        if self._getResultDimensions() > 1:
            return None
        return self._cb_x_parameter.currentText() or None

    def xParameterGetter(self):
        if self._getResultDimensions() > 1:
            return None
        text = self._cb_x_parameter.currentText()
        return self._parameter_getters.get(text)

    def listSeries(self):
        return self._lst_series.model().listSeries()

    def isNormalize(self):
        return self._chk_normalize.isChecked()
示例#22
0
class SceneTab(QWidget):  # FIXME I'm Ugly.
    """This widget is for changing the Scene propagation policies
       of the module.
    """

    def __init__(self, parent, agent):
        """Construct the SceneTab with the given parent (TabDialog) and
           ModuleAgent.
        """
        super(SceneTab, self).__init__(parent)

        self.agent = agent

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignCenter)

        self.layout.addWidget(self.buildHighlightGroupBox())
        self.layout.addItem(QSpacerItem(5, 5))
        self.layout.addWidget(self.buildModuleGroupBox())
        self.layout.addItem(QSpacerItem(5, 5))
        self.layout.addWidget(self.buildAttributeGroupBox())

        self.setLayout(self.layout)

    def buildHighlightGroupBox(self):
        """Layout/construct the highlight UI for this tab."""
        groupBox = QGroupBox("Highlight Policy")
        layout = QVBoxLayout()

        # agent.propagate_highlights
        self.highlights_propagate = QCheckBox("Propagate highlights to " + "other modules.")
        self.highlights_propagate.setChecked(self.agent.propagate_highlights)
        self.highlights_propagate.stateChanged.connect(self.highlightsPropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_highlights:
            self.highlights_propagate.setDisabled(True)

        # agent.apply_highlights
        self.applyHighlights = QCheckBox("Apply highlights from " + "other modules.")
        self.applyHighlights.setChecked(self.agent.apply_highlights)
        self.applyHighlights.stateChanged.connect(self.applyHighlightsChanged)

        layout.addWidget(self.applyHighlights)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.highlights_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def highlightsPropagateChanged(self):
        """Called when highlight propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_highlights = self.highlights_propagate.isChecked()

    def applyHighlightsChanged(self):
        """Called when highlight application is changed to update the
           Agent.
        """
        self.agent.apply_highlights = self.applyHighlights.isChecked()

    def buildModuleGroupBox(self):
        """Layout/construct the ModuleScene UI for this tab."""
        groupBox = QGroupBox("Module Policy")
        layout = QVBoxLayout()

        # agent.propagate_module_scenes
        self.module_propagate = QCheckBox("Propagate module scene information " + "to other modules.")
        self.module_propagate.setChecked(self.agent.propagate_module_scenes)
        self.module_propagate.stateChanged.connect(self.modulePropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_module_scenes:
            self.module_propagate.setDisabled(True)

        # agent.apply_module_scenes
        self.module_applyScene = QCheckBox("Apply module scene information " + "from other modules.")
        self.module_applyScene.setChecked(self.agent.apply_module_scenes)
        self.module_applyScene.stateChanged.connect(self.moduleApplyChanged)

        layout.addWidget(self.module_applyScene)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.module_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def modulePropagateChanged(self):
        """Called when ModuleScene propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_module_scenes = self.module_propagate.isChecked()

    def moduleApplyChanged(self):
        """Called when ModuleScene application is changed to update the
           Agent.
        """
        self.agent.apply_module_scenes = self.module_applyScene.isChecked()

    def buildAttributeGroupBox(self):
        """Layout/construct the AttributeScene UI for this tab."""
        groupBox = QGroupBox("Attribute Policy (Colors)")
        layout = QVBoxLayout()

        # agent.propagate_attribute_scenes
        self.attr_propagate = QCheckBox(
            "Propagate attribute scene " + "information (e.g. color maps) to other modules."
        )
        self.attr_propagate.setChecked(self.agent.propagate_attribute_scenes)
        self.attr_propagate.stateChanged.connect(self.attrPropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_attribute_scenes:
            self.attr_propagate.setDisabled(True)

        # agent.apply_attribute_scenes
        self.attr_applyScene = QCheckBox("Apply attribute scene information " + "from other modules.")
        self.attr_applyScene.setChecked(self.agent.apply_attribute_scenes)
        self.attr_applyScene.stateChanged.connect(self.attrApplyChanged)

        layout.addWidget(self.attr_applyScene)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.attr_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def attrPropagateChanged(self):
        """Called when AttributeScene propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_attribute_scenes = self.attr_propagate.isChecked()

    def attrApplyChanged(self):
        """Called when AttributeScene application is changed to update the
           Agent.
        """
        self.agent.apply_attribute_scenes = self.attr_applyScene.isChecked()
示例#23
0
class RobocompDslGui(QMainWindow):
    def __init__(self, parent=None):
        super(RobocompDslGui, self).__init__(parent)
        self.setWindowTitle("Create new component")
        # self._idsl_paths = []
        self._communications = {
            "implements": [],
            "requires": [],
            "subscribesTo": [],
            "publishes": []
        }
        self._interfaces = {}
        self._cdsl_doc = CDSLDocument()
        self._command_process = QProcess()

        self._main_widget = QWidget()
        self._main_layout = QVBoxLayout()
        self.setCentralWidget(self._main_widget)

        self._name_layout = QHBoxLayout()
        self._name_line_edit = QLineEdit()
        self._name_line_edit.textEdited.connect(self.update_component_name)
        self._name_line_edit.setPlaceholderText("New component name")
        self._name_layout.addWidget(self._name_line_edit)
        self._name_layout.addStretch()

        # DIRECTORY SELECTION
        self._dir_line_edit = QLineEdit()
        # self._dir_line_edit.textEdited.connect(self.update_completer)
        self._dir_completer = QCompleter()
        self._dir_completer_model = QFileSystemModel()
        if os.path.isdir(ROBOCOMP_COMP_DIR):
            self._dir_line_edit.setText(ROBOCOMP_COMP_DIR)
            self._dir_completer_model.setRootPath(ROBOCOMP_COMP_DIR)
        self._dir_completer.setModel(self._dir_completer_model)
        self._dir_line_edit.setCompleter(self._dir_completer)

        self._dir_button = QPushButton("Select directory")
        self._dir_button.clicked.connect(self.set_output_directory)
        self._dir_layout = QHBoxLayout()
        self._dir_layout.addWidget(self._dir_line_edit)
        self._dir_layout.addWidget(self._dir_button)

        # LIST OF ROBOCOMP INTERFACES
        self._interface_list = QListWidget()
        self._interface_list.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self._interface_list.itemSelectionChanged.connect(
            self.set_comunication)

        # LIST OF CONNECTION TyPES
        self._type_combo_box = QComboBox()
        self._type_combo_box.addItems(
            ["publishes", "implements", "subscribesTo", "requires"])
        self._type_combo_box.currentIndexChanged.connect(
            self.reselect_existing)

        # BUTTON TO ADD A NEW CONNECTION
        # self._add_connection_button = QPushButton("Add")
        # self._add_connection_button.clicked.connect(self.add_new_comunication)
        self._add_connection_layout = QHBoxLayout()
        # self._add_connection_layout.addWidget(self._add_connection_button)
        self._language_combo_box = QComboBox()
        self._language_combo_box.addItems(["Python", "Cpp", "Cpp11"])
        self._language_combo_box.currentIndexChanged.connect(
            self.update_language)
        self._add_connection_layout.addWidget(self._language_combo_box)
        self._add_connection_layout.addStretch()
        self._gui_check_box = QCheckBox()
        self._gui_check_box.stateChanged.connect(self.update_gui_selection)
        self._gui_label = QLabel("Use Qt GUI")
        self._add_connection_layout.addWidget(self._gui_label)
        self._add_connection_layout.addWidget(self._gui_check_box)

        # WIDGET CONTAINING INTERFACES AND TYPES
        self._selection_layout = QVBoxLayout()
        self._selection_layout.addWidget(self._type_combo_box)
        self._selection_layout.addWidget(self._interface_list)
        self._selection_layout.addLayout(self._add_connection_layout)
        self._selection_widget = QWidget()
        self._selection_widget.setLayout(self._selection_layout)

        # TEXT EDITOR WITH THE RESULTING CDSL CODE
        self._editor = QTextEdit(self)
        self._editor.setHtml("")

        self._document = self._editor.document()
        self._component_directory = None

        # SPLITTER WITH THE SELECTION AND THE CODE
        self._body_splitter = QSplitter(Qt.Horizontal)
        self._body_splitter.addWidget(self._selection_widget)
        self._body_splitter.addWidget(self._editor)
        self._body_splitter.setStretchFactor(0, 2)
        self._body_splitter.setStretchFactor(1, 9)

        # CREATION BUTTONS
        self._create_button = QPushButton("Create .cdsl")
        self._create_button.clicked.connect(self.write_cdsl_file)
        self._creation_layout = QHBoxLayout()
        self._creation_layout.addStretch()
        self._creation_layout.addWidget(self._create_button)

        self._console = QConsole()
        self._command_process.readyReadStandardOutput.connect(
            self._console.standard_output)
        self._command_process.readyReadStandardError.connect(
            self._console.error_output)

        # ADDING WIDGETS TO MAIN LAYOUT
        self._main_widget.setLayout(self._main_layout)
        self._main_layout.addLayout(self._name_layout)
        self._main_layout.addLayout(self._dir_layout)
        self._main_layout.addWidget(self._body_splitter)
        self._main_layout.addLayout(self._creation_layout)
        self._main_layout.addWidget(self._console)
        self.setMinimumSize(800, 500)
        self._editor.setText(self._cdsl_doc.generate_doc())

    # self.editor->show();

    # def update_completer(self, path):
    # 	print "update_completer %s"%path
    # 	info = QFileInfo(path)
    # 	if info.exists() and info.isDir():
    # 			if not path.endswith(os.path.pathsep):
    # 				new_path = os.path.join(path, os.sep)
    # 				# self._dir_line_edit.setText(new_path)
    # 			all_dirs_output = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path, dI))]
    # 			print all_dirs_output
    # 			self._dir_completer.complete()

    def load_idsl_files(self, fullpath=None):
        if fullpath is None:
            fullpath = ROBOCOMP_INTERFACES
        idsls_dir = os.path.join(ROBOCOMP_INTERFACES, "IDSLs")
        if os.path.isdir(idsls_dir):
            for full_filename in os.listdir(idsls_dir):
                file_name, file_extension = os.path.splitext(full_filename)
                if "idsl" in file_extension.lower():
                    full_idsl_path = os.path.join(idsls_dir, full_filename)
                    # self._idsl_paths.append(os.path.join(idsls_dir,full_filename))
                    self.parse_idsl_file(full_idsl_path)
        self._interface_list.addItems(self._interfaces.keys())

    def parse_idsl_file(self, fullpath):

        with open(fullpath, 'r') as fin:
            interface_name = None
            for line in fin:
                result = re.findall(r'^\s*interface\s+(\w+)\s*\{?\s*$',
                                    line,
                                    flags=re.MULTILINE)
                if len(result) > 0:
                    interface_name = result[0]
            print("%s for idsl %s" % (interface_name, fullpath))
            if interface_name is not None:
                self._interfaces[interface_name] = fullpath

    def add_new_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            idsl_full_path = self._interfaces[iface_name]
            idsl_full_filename = os.path.basename(idsl_full_path)
            self._cdsl_doc.add_comunication(com_type, iface_name)
            self._cdsl_doc.add_import(idsl_full_filename)
        self.update_editor()

    def set_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        self._communications[com_type] = []
        self._cdsl_doc.clear_comunication(com_type)
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            self._cdsl_doc.add_comunication(com_type, iface_name)
        self.update_imports()
        self.update_editor()

    def update_imports(self):
        self._cdsl_doc.clear_imports()
        for com_type in self._communications:
            for iface_name in self._communications[com_type]:
                idsl_full_path = self._interfaces[iface_name]
                idsl_full_filename = os.path.basename(idsl_full_path)
                self._cdsl_doc.add_import(idsl_full_filename)

    def update_language(self):
        language = self._language_combo_box.currentText()
        self._cdsl_doc.set_language(str(language))
        self.update_editor()

    def update_gui_selection(self):
        checked = self._gui_check_box.isChecked()
        if checked:
            self._cdsl_doc.set_qui(True)
        else:
            self._cdsl_doc.set_qui(False)
        self.update_editor()

    def update_component_name(self, name):
        self._cdsl_doc.set_name(name)
        self.update_editor()

    def update_editor(self):
        self._editor.setText(self._cdsl_doc.generate_doc())

    def set_output_directory(self):
        dir_set = False
        while not dir_set:
            dir = QFileDialog.getExistingDirectory(
                self, "Select Directory", ROBOCOMP_COMP_DIR,
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
            if self.check_dir_is_empty(str(dir)):
                self._dir_line_edit.setText(dir)
                dir_set = True

    def write_cdsl_file(self):
        component_dir = str(self._dir_line_edit.text())
        text = self._cdsl_doc.generate_doc()
        if not self._name_line_edit.text():
            component_name, ok = QInputDialog.getText(self,
                                                      'No component name set',
                                                      'Enter component name:')
            if ok:
                self.update_component_name(component_name)
                self._name_line_edit.setText(component_name)
            else:
                return False

        if not os.path.exists(component_dir):
            if QMessageBox.Yes == QMessageBox.question(
                    self, "Directory doesn't exist.",
                    "Do you want create the directory %s?" % component_dir,
                    QMessageBox.Yes | QMessageBox.No):
                os.makedirs(component_dir)
            else:
                QMessageBox.question(
                    self, "Directory not exist",
                    "Can't create a component witout a valid directory")
                return False

        file_path = os.path.join(component_dir,
                                 str(self._name_line_edit.text()) + ".cdsl")
        if os.path.exists(file_path):
            if QMessageBox.No == QMessageBox.question(
                    self, "File already exists", "Do you want to overwrite?",
                    QMessageBox.Yes | QMessageBox.No):
                return False

        with open(file_path, 'w') as the_file:
            the_file.write(text)
        self.execute_robocomp_cdsl()
        return True

    def execute_robocomp_cdsl(self):
        cdsl_file_path = os.path.join(
            str(self._dir_line_edit.text()),
            str(self._name_line_edit.text()) + ".cdsl")
        command = "python -u %s/robocompdsl.py %s %s" % (
            ROBOCOMPDSL_DIR, cdsl_file_path,
            os.path.join(str(self._dir_line_edit.text())))
        self._console.append_custom_text("%s\n" % command)
        self._command_process.start(command,
                                    QProcess.Unbuffered | QProcess.ReadWrite)

    def reselect_existing(self):
        com_type = self._type_combo_box.currentText()
        selected = self._communications[com_type]
        self._interface_list.clearSelection()
        for iface in selected:
            items = self._interface_list.findItems(iface,
                                                   Qt.MatchFlag.MatchExactly)
            if len(items) > 0:
                item = items[0]
                item.setSelected(True)

    def check_dir_is_empty(self, dir_path):
        if len(os.listdir(dir_path)) > 0:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Directory not empty")
            msgBox.setText(
                "The selected directory is not empty.\n"
                "For a new Component you usually want a new directory.\n"
                "Do you want to use this directory anyway?")
            msgBox.setStandardButtons(QMessageBox.Yes)
            msgBox.addButton(QMessageBox.No)
            msgBox.setDefaultButton(QMessageBox.No)
            if msgBox.exec_() == QMessageBox.Yes:
                return True
            else:
                return False
        else:
            return True
示例#24
0
class HotkeyDialogView(QDialog):
    HOTKEY_DIALOG_OK = "HOTKEY_DIALOG_OK"
    HOTKEY_DIALOG_CANCEL = "HOTKEY_DIALOG_CANCEL"

    def __init__(self, *args, **kwargs):
        super(HotkeyDialogView, self).__init__(*args, **kwargs)
        self.setWindowTitle("Set Hotkey")
        self.edit_line = QLineEdit()
        self.edit_line.setEnabled(False)
        self.installEventFilter(self)

        self.ok_btn = QPushButton("&Ok")
        # noinspection PyUnresolvedReferences
        self.ok_btn.clicked.connect(self.accept)

        self.control_check = QCheckBox()
        self.control_label = QLabel("CTRL")
        self.shift_check = QCheckBox()
        self.shift_label = QLabel("SHIFT")
        self.alt_check = QCheckBox()
        self.alt_label = QLabel("ALT")

        self.cancel_btn = QPushButton("&Cancel")
        # noinspection PyUnresolvedReferences
        self.cancel_btn.clicked.connect(self.reject)

        self.h_keys_layout = QHBoxLayout()
        self.h_btn_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()

        self.h_btn_layout.addStretch(0)
        self.h_btn_layout.addWidget(self.ok_btn)
        self.h_btn_layout.addWidget(self.cancel_btn)

        self.h_keys_layout.addWidget(self.control_check)
        self.h_keys_layout.addWidget(self.control_label)
        self.h_keys_layout.addWidget(self.shift_check)
        self.h_keys_layout.addWidget(self.shift_label)
        self.h_keys_layout.addWidget(self.alt_check)
        self.h_keys_layout.addWidget(self.alt_label)
        self.h_keys_layout.addWidget(self.edit_line)
        self.v_layout.addLayout(self.h_keys_layout)
        self.v_layout.addLayout(self.h_btn_layout)
        self.setLayout(self.v_layout)

        # noinspection PyUnresolvedReferences
        self.accepted.connect(self.on_accept)
        # noinspection PyUnresolvedReferences
        self.rejected.connect(self.on_reject)

        self.__key = None

    def eventFilter(self, source, event):
        """
        @type event: QEvent.QEvent
        @return:
        """
        if event.type() == QEvent.KeyPress:
            event = event
            """:type :QKeyEvent"""
            self.__key = event.key
            key_str = QKeySequence(event.key()).toString()
            if key_str == "Esc":
                self.edit_line.setText("")
                return True
            self.edit_line.setText(key_str)
            return True
        return QDialog.eventFilter(self, source, event)

    def on_accept(self):
        hotkey_str = ""
        key = self.edit_line.text()
        if key:
            if self.control_check.isChecked():
                hotkey_str += "Ctrl+"
            if self.alt_check.isChecked():
                hotkey_str += "Alt+"
            if self.shift_check.isChecked():
                hotkey_str += "Shift+"
            hotkey_str += key
        if key == "":
            hotkey_str = ""
        Facade.getInstance().sendNotification(
            HotkeyDialogView.HOTKEY_DIALOG_OK, {"key_sequence": hotkey_str})

    def on_reject(self):
        Facade.getInstance().sendNotification(
            HotkeyDialogView.HOTKEY_DIALOG_CANCEL, )
示例#25
0
class PushupForm(QDialog):
    '''
    classdocs
    '''
    pushupCreated = Signal(Pushup_Model)
    
    def __init__(self, athlete):
        '''
        Constructor
        '''
        QDialog.__init__(self)
        
        self.setWindowTitle("Pushup form")
        self.athlete = athlete
        self.pushupForm = QFormLayout()
        self.createGUI()
        
    def createGUI(self):
        self.series = QSpinBox()
        self.series.setMinimum(1)
        
        self.repetitions = QSpinBox()
        self.repetitions.setMaximum(512)
        
        self.avgHeartRateToggle = QCheckBox()
        self.avgHeartRateToggle.toggled.connect(self._toggleHeartRateSpinBox)
        
        self.avgHeartRate = QSpinBox()
        self.avgHeartRate.setMinimum(30)
        self.avgHeartRate.setMaximum(250)
        self.avgHeartRate.setValue(120)
        self.avgHeartRate.setDisabled(True)
        
        self.dateSelector_widget = QCalendarWidget()
        self.dateSelector_widget.setMaximumDate(QDate.currentDate())
        
        self.addButton = QPushButton("Add pushup")
        self.addButton.setMaximumWidth(90)
        self.addButton.clicked.connect(self._createPushup)
        
        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.setMaximumWidth(90)
        self.cancelButton.clicked.connect(self.reject)
        
        self.pushupForm.addRow("Series", self.series)
        self.pushupForm.addRow("Repetitions", self.repetitions)
        self.pushupForm.addRow("Store average heart rate ? ", self.avgHeartRateToggle)
        self.pushupForm.addRow("Average Heart Rate", self.avgHeartRate)
        self.pushupForm.addRow("Exercise Date", self.dateSelector_widget)
        
        btnsLayout = QVBoxLayout()
        btnsLayout.addWidget(self.addButton)
        btnsLayout.addWidget(self.cancelButton)        
        btnsLayout.setAlignment(Qt.AlignRight)
        
        layoutWrapper = QVBoxLayout()
        layoutWrapper.addLayout(self.pushupForm)
        layoutWrapper.addLayout(btnsLayout)
        
        self.setLayout(layoutWrapper)        
        
    def _createPushup(self):        
        exerciseDate = self.dateSelector_widget.selectedDate()
        exerciseDate = self.qDate_to_date(exerciseDate)
        
        if self.avgHeartRateToggle.isChecked():
            heartRate = self.avgHeartRate.value()
        else:
            heartRate = None
            
        pushup = Pushup_Model(self.athlete._name, 
                              exerciseDate, 
                              heartRate, 
                              self.series.value(),
                              self.repetitions.value())

        self.pushupCreated.emit(pushup)
        self.accept()       
    
    def _toggleHeartRateSpinBox(self):
        if self.avgHeartRateToggle.isChecked():
            self.avgHeartRate.setDisabled(False)
        else:
            self.avgHeartRate.setDisabled(True)
        
    def qDate_to_date(self, qDate):        
        return date(qDate.year(), qDate.month(),qDate.day())
        
示例#26
0
文件: QtUI.py 项目: beerhof/waski
class UI(gobject.GObject):
	__gsignals__ = {
		'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
	}
	
	def __init__(self,args,continuous):
		self.continuous = continuous
		gobject.GObject.__init__(self)
		#start by making our app
		self.app = QApplication(args)
		#make a window
		self.window = QMainWindow()
		#give the window a name
		self.window.setWindowTitle("BlatherQt")
		self.window.setMaximumSize(400,200)
		center = QWidget()
		self.window.setCentralWidget(center)
		
		layout = QVBoxLayout()
		center.setLayout(layout)
		#make a listen/stop button
		self.lsbutton = QPushButton("Listen")
		layout.addWidget(self.lsbutton)
		#make a continuous button
		self.ccheckbox = QCheckBox("Continuous Listen")
		layout.addWidget(self.ccheckbox)
		
		#connect the buttonsc
		self.lsbutton.clicked.connect(self.lsbutton_clicked)
		self.ccheckbox.clicked.connect(self.ccheckbox_clicked)
		
		#add a label to the UI to display the last command
		self.label = QLabel()
		layout.addWidget(self.label)
	
	def ccheckbox_clicked(self):
		checked = self.ccheckbox.isChecked()
		if checked:
			#disable lsbutton
			self.lsbutton.setEnabled(False)
			self.lsbutton_stopped()
			self.emit('command', "continuous_listen")
		else:
			self.lsbutton.setEnabled(True)
			self.emit('command', "continuous_stop")
	
	def lsbutton_stopped(self):
		self.lsbutton.setText("Listen")
		
	def lsbutton_clicked(self):
		val = self.lsbutton.text()
		if val == "Listen":
			self.emit("command", "listen")
			self.lsbutton.setText("Stop")
			#clear the label
			self.label.setText("")
		else:
			self.lsbutton_stopped()
			self.emit("command", "stop")
			
	def run(self):
		self.window.show()
		if self.continuous:
			self.ccheckbox.setCheckState(Qt.Checked)
			self.ccheckbox_clicked()
		self.app.exec_()
		self.emit("command", "quit")
	
	def quit(self):
		pass
		
	def finished(self, text):
		print text
		#if the continuous isn't pressed
		if not self.ccheckbox.isChecked():
			self.lsbutton_stopped()
		self.label.setText(text)
		
	def quit(self):
		#sys.exit()
		pass
示例#27
0
class UsbResetter(QWidget):
    def __init__(self):
        super(UsbResetter, self).__init__()
        self.P = UR_thread()
        self.thr_counter = 0
        self.Looping = None
        self.Hidden = None
        self.Fhidden = None
        self.s_error = "QStatusBar{color:red;font-weight:1000;}"
        self.s_loop = "QStatusBar{color:black;font-weight:1000;}"
        self.s_norm = "QStatusBar{color:blue;font-style:italic;"
        self.s_norm += "font-weight:500;}"
        favicon = r_path("images/favicon.png")
        logo = r_path("images/logo.png")
        if name == 'nt':
            favicon = r_path("images\\favicon.png")
            logo = r_path("images\\logo.png")
        self.favicon = QIcon(favicon)
        self.plogo = logo
        self.logo = QIcon(logo)
        self.setStyle()
        mlayout = QVBoxLayout()
        self.setAbout(mlayout)
        self.setUlist(mlayout)
        self.setCboxs(mlayout)
        self.setReset(mlayout)
        self.setLoop(mlayout)
        self.setSb(mlayout)
        # functionalities
        self.set_list()
        self.rootWarn()
        # initiation
        self.activateWindow()
        self.setLayout(mlayout)
        self.show()

    def setSb(self, m):
        self.statusbar = QStatusBar()
        m.addWidget(self.statusbar)

    def setStyle(self):
        self.setMaximumWidth(350)
        self.setMinimumWidth(350)
        self.setMaximumHeight(340)
        self.setMinimumHeight(340)
        self.setWindowTitle("usb-resetter 1.0")
        self.setWindowIcon(self.favicon)
        self.show()

    def setAbout(self, m):
        self.pushButton = QPushButton()
        self.icon1 = QIcon()
        self.icon1.addPixmap(QPixmap(self.plogo),
                             QIcon.Normal, QIcon.Off)
        self.pushButton.setIcon(self.icon1)
        self.pushButton.setIconSize(QSize(300, 100))
        self.pushButton.clicked.connect(self.show_about)
        m.addWidget(self.pushButton)

    def setUlist(self, m):
        self.comboBox = QComboBox()
        m.addWidget(self.comboBox)

    def setCboxs(self, m):
        ml = QVBoxLayout()
        fl = QHBoxLayout()
        self.checkBox_2 = QCheckBox("Audio")
        self.checkBox_3 = QCheckBox("Mass storage")
        self.checkBox_2.setToolTip("Filter by audio devices")
        self.checkBox_3.setToolTip("Filter by mass storage devices")
        fl.addWidget(self.checkBox_2)
        fl.addWidget(self.checkBox_3)
        ml.addLayout(fl)
        sl = QHBoxLayout()
        self.checkBox_4 = QCheckBox("Network")
        self.checkBox_4.setToolTip("Filter by network devices")
        self.checkBox_5 = QCheckBox("Human interface")
        self.checkBox_5.setToolTip("Filter by Keyboard, mouse, joystick ..etc")
        sl.addWidget(self.checkBox_4)
        sl.addWidget(self.checkBox_5)
        ml.addLayout(sl)
        self.checkBox_2.clicked.connect(self.set_list)
        self.checkBox_3.clicked.connect(self.set_list)
        self.checkBox_4.clicked.connect(self.set_list)
        self.checkBox_5.clicked.connect(self.set_list)
        m.addLayout(ml)

    def setReset(self, m):
        self.pushButton_2 = QPushButton("Reset it")
        font = QFont()
        font.setPointSize(17)
        font.setWeight(75)
        font.setBold(True)
        self.pushButton_2.setFont(font)
        self.pushButton_2.clicked.connect(self.setbut_reset)
        m.addWidget(self.pushButton_2)

    def setLoop(self, m):
        ml = QHBoxLayout()
        self.checkBox = QCheckBox("Looping")
        self.checkBox.setToolTip("To repeat resetting for specified duration")
        self.lineEdit = QLineEdit()
        self.lineEdit.setToolTip("Duration in-which the resetting is done")
        self.pushButton_3 = QPushButton("Stop")
        self.pushButton_3.setToolTip("Stop looping")
        ml.addWidget(self.checkBox)
        ml.addWidget(self.lineEdit)
        ml.addWidget(self.pushButton_3)
        self.pushButton_3.setEnabled(False)
        self.lineEdit.setEnabled(False)
        self.lineEdit.setPlaceholderText("duration in seconds")
        self.checkBox.clicked.connect(self.loop_status)
        self.pushButton_3.clicked.connect(self.in_loop)
        m.addLayout(ml)

    # Functionalities

    def show_about(self):
        Amsg = "<center>All credit reserved to the author of "
        Amsg += "usb-resetter version 1.0"
        Amsg += ", This work is a free, open-source project licensed "
        Amsg += " under Mozilla Public License version 2.0 . <br><br>"
        Amsg += " visit us for more infos and how-tos :<br> "
        Amsg += "<b><a href='https://usb-resetter.github.io/'> "
        Amsg += "https://usb-resetter.github.io/ </a> </b></center>"
        Amsgb = "About usb-resetter"
        v = QMessageBox.about(self, Amsgb, Amsg)
        v = str(v)
        return v

    def closeEvent(self, event=None):
        if self.Hidden is None:
            response = QMessageBox.question(
                self,
                "Hide or close",
                "Do you want to hide the application ?",
                QMessageBox.Yes, QMessageBox.No)
            if response == QMessageBox.Yes:
                if event is not None:
                    event.ignore()
                self.Hidden = True
                self.hide()
            elif response == QMessageBox.No:
                if event is not None:
                    event.accept()
                return self.exitEvent()
            else:
                return False
        else:
            return self.exitEvent()

    def exitEvent(self):
        if self.P.isRunning():
            response = QMessageBox.question(
                self,
                "Making sure",
                "Sure, you want to exit while looping ?",
                QMessageBox.Yes, QMessageBox.No)
            if response == QMessageBox.Yes:
                self.P.stop()
                exit(0)
            else:
                return False
        else:
            exit(0)

    def get_list(self):
        ol = []
        if self.checkBox_2.isChecked():
            ol.append(1)
        if self.checkBox_3.isChecked():
            ol.append(8)
        if self.checkBox_4.isChecked():
            ol.append(2)
        if self.checkBox_5.isChecked():
            ol.append(3)
        if len(ol) >= 1:
            return listd(ol, True)
        else:
            return listd(None, True)

    def set_list(self):
        self.comboBox.clear()
        its = self.get_list()
        if len(its) >= 1:
            self.comboBox.addItems(its)
            self.pushButton_2.setEnabled(True)
            self.checkBox.setEnabled(True)
        else:
            self.pushButton_2.setEnabled(False)
            self.checkBox.setEnabled(False)
            self.lineEdit.setEnabled(False)
            self.pushButton_3.setEnabled(False)

    def setbut_reset(self):
        t = self.comboBox.currentText()
        if self.Looping is None:
            if resetit(t):
                self.statusbar.setStyleSheet(self.s_norm)
                self.statusbar.showMessage(
                    "# Done: usb device got reset")
                return True
            self.statusbar.setStyleSheet(self.s_error)
            if name != 'nt':
                self.statusbar.showMessage(
                    "# Error: maybe you need sudo permissions")
            else:
                self.statusbar.showMessage(
                    "# Error: maybe you need to add device to libusb")
            return False
        else:
            tl = self.lineEdit.text()
            self.statusbar.setStyleSheet(self.s_error)
            if len(tl) == 0:
                self.statusbar.showMessage(
                    "# Error: you must enter duration for looping")
                return False
            try:
                self.thr_counter += 1
                tl = int(tl)
                if tl < 2:
                    self.statusbar.showMessage(
                        "# Error: the least allowed value is 2")
                    return False
                self.P = UR_thread(t, tl, self.thr_counter)
                self.P.start()
                self.P.somesignal.connect(self.handleStatusMessage)
                self.P.setTerminationEnabled(True)
                self.in_loop(False)
            except:
                self.statusbar.showMessage(
                    "# Error: only valid integers allowed")
                return False

    def loop_status(self):
        if self.Looping:
            self.Looping = None
            self.lineEdit.setEnabled(False)
            self.pushButton_3.setEnabled(False)
        else:
            self.Looping = True
            self.lineEdit.setEnabled(True)
        return True

    def in_loop(self, stop=True):
        if stop:
            if self.P.isRunning():
                self.P.stop()
            self.pushButton_3.setEnabled(False)
            self.pushButton_2.setEnabled(True)
            self.checkBox.setEnabled(True)
            if self.checkBox.isChecked():
                self.lineEdit.setEnabled(True)
            self.checkBox_2.setEnabled(True)
            self.checkBox_3.setEnabled(True)
            self.checkBox_4.setEnabled(True)
            self.checkBox_5.setEnabled(True)
            self.comboBox.setEnabled(True)
        else:
            self.pushButton_3.setEnabled(True)
            self.pushButton_2.setEnabled(False)
            self.checkBox.setEnabled(False)
            self.lineEdit.setEnabled(False)
            self.checkBox_2.setEnabled(False)
            self.checkBox_3.setEnabled(False)
            self.checkBox_4.setEnabled(False)
            self.checkBox_5.setEnabled(False)
            self.comboBox.setEnabled(False)
        return True

    def rootWarn(self):
        if platform[:len(platform) - 1] == "linux":
            from os import getuid
            if getuid() != 0:
                self.statusbar.setStyleSheet(self.s_error)
                self.statusbar.showMessage(
                    "# Error: you must use sudo on Linux")

    @Slot(object)
    def handleStatusMessage(self, message):
        self.statusbar.setStyleSheet(self.s_loop)
        if message[:7] == '# Error':
            self.in_loop()
            self.statusbar.setStyleSheet(self.s_error)
        self.statusbar.showMessage(message)
示例#28
0
class EditConfigurationDialog(QDialog):
    def __init__(self, parent):
        global configuration
        super(EditConfigurationDialog, self).__init__(parent)

        title = _("Preferences")
        self.setWindowTitle(title)
        self.title_widget = TitleWidget(title, self)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.addButton(QDialogButtonBox.Cancel)

        self.font_select = QCheckBox()
        self.server_address = QLineEdit()

        form_layout = QFormLayout()
        form_layout.addRow(_("Fonts"), self.font_select)
        form_layout.addRow(_("Server's IP address"), self.server_address)

        top_layout = QVBoxLayout()
        top_layout.addWidget(self.title_widget)
        top_layout.addLayout(form_layout)
        top_layout.addWidget(self.buttons)

        self.setLayout(top_layout)  # QWidget takes ownership of the layout
        self.buttons.accepted.connect(self.save_and_accept)
        self.buttons.rejected.connect(self.cancel)

        self._load_configuration(configuration)

    def _load_configuration(self, config):

        host_or_ip = ""
        if config:
            if config.get("DownloadSite", "base_url"):
                r = re.compile('https?://([^:]+):.*')
                host_or_ip = r.match(config.get("DownloadSite",
                                                "base_url")).groups()[0]

            elif config.database_url:
                r = re.compile('.*@([^:]+):.*')
                host_or_ip = r.match(config.database_url).groups()[0]

        self.server_address.setText(host_or_ip)
        self.font_select.setChecked(config.font_select)

    @Slot()
    def cancel(self):
        return super(EditConfigurationDialog, self).reject()

    @Slot()
    def save_and_accept(self):
        super(EditConfigurationDialog, self).accept()

        configuration.font_select = self.font_select.isChecked()
        configuration.set_server_network_address(
            self.server_address.text().strip(), overwrite=True)
        configuration.save()

        showWarningBox(
            _("Restart needed"),
            _("The modifications you have requested needs a restart of the application to be applied. They will take effect when you restart the application."
              ))

        self.deleteLater()
示例#29
0
class UI(gobject.GObject):
	__gsignals__ = {
		'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
	}

	def __init__(self,args,continuous):
		self.continuous = continuous
		gobject.GObject.__init__(self)
		#start by making our app
		self.app = QApplication(args)
		#make a window
		self.window = QMainWindow()
		#give the window a name
		self.window.setWindowTitle("BlatherQt")
		self.window.setMaximumSize(400,200)
		center = QWidget()
		self.window.setCentralWidget(center)

		layout = QVBoxLayout()
		center.setLayout(layout)
		#make a listen/stop button
		self.lsbutton = QPushButton("Listen")
		layout.addWidget(self.lsbutton)
		#make a continuous button
		self.ccheckbox = QCheckBox("Continuous Listen")
		layout.addWidget(self.ccheckbox)

		#connect the buttons
		self.lsbutton.clicked.connect(self.lsbutton_clicked)
		self.ccheckbox.clicked.connect(self.ccheckbox_clicked)

		#add a label to the UI to display the last command
		self.label = QLabel()
		layout.addWidget(self.label)

		#add the actions for quiting
		quit_action = QAction(self.window)
		quit_action.setShortcut('Ctrl+Q')
		quit_action.triggered.connect(self.accel_quit)
		self.window.addAction(quit_action)

	def accel_quit(self):
		#emit the quit
		self.emit("command", "quit")
	
	#function for managing the continuou listening check box being clicked. When it is clicked it 
	#emits an event for blather to let blather know that the state of things has changed. This is
	#caught by blather's process_command function.
	def ccheckbox_clicked(self):
		checked = self.ccheckbox.isChecked()
		if checked:
			#disable lsbutton
			self.lsbutton.setEnabled(False)
			self.lsbutton_stopped()
			self.emit('command', "continuous_listen")
			self.set_icon_active()
		else:
			self.lsbutton.setEnabled(True)
			self.emit('command', "continuous_stop")
			self.set_icon_inactive()


	#functions related to the listen button. lsbutton_stopped is a quasi place holder for if I
	#want to expand the end of listening to do other things as well.
	def lsbutton_stopped(self):
		self.lsbutton.setText("Listen")

	def lsbutton_clicked(self):
		val = self.lsbutton.text()
		if val == "Listen":
			self.emit("command", "listen")
			self.lsbutton.setText("Stop")
			#clear the label
			self.label.setText("")
			self.set_icon_active()
		else:
			self.lsbutton_stopped()
			self.emit("command", "stop")
			self.set_icon_inactive()

	#called by blather right before the main loop is started. Mainloop is handled by gst. 
	def run(self):
		self.set_icon_inactive()
		self.window.show()
		if self.continuous:
			self.set_icon_active()
			self.ccheckbox.setCheckState(Qt.Checked)
			self.ccheckbox_clicked()
		self.app.exec_()
		self.emit("command", "quit")

	#This function is called when it hears a pause in the audio. 
	#This is called after the command has been sent of to the commander.
	def finished(self, text):
		#if the continuous isn't pressed
		if not self.ccheckbox.isChecked():
			self.lsbutton_stopped()
		self.label.setText(text)


	#functions dealing with the icon
	def set_icon(self, icon):
		self.window.setWindowIcon(QIcon(icon))

	def set_icon_active_asset(self, i):
		self.icon_active = i

	def set_icon_inactive_asset(self, i):
		self.icon_inactive = i

	def set_icon_active(self):
		self.window.setWindowIcon(QIcon(self.icon_active))

	def set_icon_inactive(self):
		self.window.setWindowIcon(QIcon(self.icon_inactive))
示例#30
0
class HotkeyDialogView(QDialog):
    HOTKEY_DIALOG_OK = "HOTKEY_DIALOG_OK"
    HOTKEY_DIALOG_CANCEL = "HOTKEY_DIALOG_CANCEL"

    def __init__(self, *args, **kwargs):
        super(HotkeyDialogView, self).__init__(*args, **kwargs)
        self.setWindowTitle("Set Hotkey")
        self.edit_line = QLineEdit()
        self.edit_line.setEnabled(False)
        self.installEventFilter(self)

        self.ok_btn = QPushButton("&Ok")
        # noinspection PyUnresolvedReferences
        self.ok_btn.clicked.connect(self.accept)

        self.control_check = QCheckBox()
        self.control_label = QLabel("CTRL")
        self.shift_check = QCheckBox()
        self.shift_label = QLabel("SHIFT")
        self.alt_check = QCheckBox()
        self.alt_label = QLabel("ALT")


        self.cancel_btn = QPushButton("&Cancel")
        # noinspection PyUnresolvedReferences
        self.cancel_btn.clicked.connect(self.reject)

        self.h_keys_layout = QHBoxLayout()
        self.h_btn_layout = QHBoxLayout()
        self.v_layout = QVBoxLayout()

        self.h_btn_layout.addStretch(0)
        self.h_btn_layout.addWidget(self.ok_btn)
        self.h_btn_layout.addWidget(self.cancel_btn)

        self.h_keys_layout.addWidget(self.control_check)
        self.h_keys_layout.addWidget(self.control_label)
        self.h_keys_layout.addWidget(self.shift_check)
        self.h_keys_layout.addWidget(self.shift_label)
        self.h_keys_layout.addWidget(self.alt_check)
        self.h_keys_layout.addWidget(self.alt_label)
        self.h_keys_layout.addWidget(self.edit_line)
        self.v_layout.addLayout(self.h_keys_layout)
        self.v_layout.addLayout(self.h_btn_layout)
        self.setLayout(self.v_layout)

        # noinspection PyUnresolvedReferences
        self.accepted.connect(self.on_accept)
        # noinspection PyUnresolvedReferences
        self.rejected.connect(self.on_reject)

        self.__key = None

    def eventFilter(self, source, event):
        """
        @type event: QEvent.QEvent
        @return:
        """
        if event.type() == QEvent.KeyPress:
            event = event
            """:type :QKeyEvent"""
            self.__key = event.key
            key_str = QKeySequence(event.key()).toString()
            if key_str == "Esc":
                self.edit_line.setText("")
                return True
            self.edit_line.setText(key_str)
            return True
        return QDialog.eventFilter(self, source, event)


    def on_accept(self):
        hotkey_str = ""
        key = self.edit_line.text()
        if key:
            if self.control_check.isChecked():
                hotkey_str += "Ctrl+"
            if self.alt_check.isChecked():
                hotkey_str += "Alt+"
            if self.shift_check.isChecked():
                hotkey_str += "Shift+"
            hotkey_str += key
        if key == "":
            hotkey_str = ""
        Facade.getInstance().sendNotification(
            HotkeyDialogView.HOTKEY_DIALOG_OK,
            {"key_sequence": hotkey_str}
        )

    def on_reject(self):
        Facade.getInstance().sendNotification(
            HotkeyDialogView.HOTKEY_DIALOG_CANCEL,
        )
示例#31
0
class ExchangeView(QGroupBox):
    '''The box containing the rate value'''

    def __init__(self, title = 'Peak Exchange Matrix', parent = None):
        '''Initialize'''
        super(ExchangeView, self).__init__(parent)
        self.setTitle(title)
        self._createWidgets()

    def _createWidgets(self):
        '''Create the widgets contained in this box'''
        # Peak number chooser
        self.numpeaks = [QRadioButton("2"),
                         QRadioButton("3"),
                         QRadioButton("4")]
        
        self.numpeaks[0].setToolTip(ttt('Model the exchange of 2 peaks'))
        self.numpeaks[1].setToolTip(ttt('Model the exchange of 3 peaks'))
        self.numpeaks[2].setToolTip(ttt('Model the exchange of 4 peaks'))
        # Make 4x4 matrix of QLabels
        self.exview = [[QLabel(self) for i in xrange(4)] for j in xrange(4)]
        for i in xrange(4):
            for e in self.exview[i]:
                e.setToolTip(ttt('The current exchange matrix'))
        # Enforce symmetry button
        self.symmetry = QCheckBox("Enforce Symmetry", self)
        self.symmetry.setToolTip(ttt('If symmetry is on then you only need to '
                                     'manually set the upper triangle of the '
                                     'exchange matrix.  Thse values are '
                                     'mirrored '
                                     'in the lower triangle and the diagonals '
                                     'are automatically set so that each row '
                                     'sums to 1. '
                                     'Otherwise you must set every element'))
        # Exchange picker
        self.exchooser = QComboBox(self)
        self.exchooser.setToolTip(ttt('Choose between which two peaks to set '
                                  'the exchange (relative) rate'))
        # Exchange value
        self.exvalue = QLineEdit(self)
        self.exvalue.setToolTip(ttt('The exchange (relative) rate'))
        self.exvalue.setValidator(QDoubleValidator(0.0, 1.0, 3, self.exvalue))

    def makeConnections(self):
        '''Connect the widgets together'''
        # When the table has been resized, tidy it up
        self.matrix.matrixChanged.connect(self.resetMatrix)
        # If the check state changed, change the data model
        self.symmetry.stateChanged.connect(self.changeDataModel)
        self.numpeaks[0].clicked.connect(self.changeDataModel)
        self.numpeaks[1].clicked.connect(self.changeDataModel)
        self.numpeaks[2].clicked.connect(self.changeDataModel)
        # Attach the chooser to an exchange rate
        self.exchooser.currentIndexChanged.connect(self.attachExchange)
        # If the exchange rate is changed, update the matrix
        self.exvalue.editingFinished.connect(self.newExchange)

    def initUI(self):
        '''Lays out the widgets'''
        nums = QHBoxLayout()
        nums.addWidget(QLabel("Number of Peaks: "))
        nums.addWidget(self.numpeaks[0])
        nums.addWidget(self.numpeaks[1])
        nums.addWidget(self.numpeaks[2])
        val = QHBoxLayout()
        val.addWidget(QLabel("Exchange: "))
        val.addStretch()
        val.addWidget(self.exchooser)
        self.exvalue.setMaximumWidth(50)
        val.addWidget(self.exvalue)
        ex = QGridLayout()
        for i in xrange(4):
            for j in xrange(4):
                ex.addWidget(self.exview[i][j], i+1, j+1)
        lo = QVBoxLayout()
        lo.addLayout(nums)
        lo.addWidget(self.symmetry)
        lo.addLayout(val)
        lo.addLayout(ex)
        self.setLayout(lo)

    def setModel(self, model, npmodel):
        '''Attaches models to the views.'''
        self.matrix = model
        self.npmodel = npmodel

    def setNumPeaks(self, npeaks):
        '''Manually set the number of peaks'''
        if npeaks == 2:
            self.numpeaks[0].click()
        elif npeaks == 3:
            self.numpeaks[1].click()
        elif npeaks == 4:
            self.numpeaks[2].click()
        else:
            error.showMessage('Only valid number of peaks is 2, 3, or 4')

    def setMatrixSymmetry(self, sym):
        '''Manually set the matrix symmetry'''
        self.symmetry.setChecked(sym)

    def setMatrix(self, Z):
        '''Manually set the matrix elements with a numpy matrix'''
        npeaks = self.npmodel.getNumPeaks()
        self.matrix.matrix = Z[0:npeaks,0:npeaks]
        self.matrix.updateInternalModel(npeaks)
        self.resetMatrix()

    #######
    # SLOTS
    #######

    def newExchange(self):
        '''Prepares an exchange value to be broadcasted'''
        try:
            value = round(float(self.exvalue.text()), 3)
        except ValueError:
            value = 0.0
        indx = self.exchooser.currentIndex()
        if self.numpeaks[0].isChecked():
            npeaks = 2
        elif self.numpeaks[1].isChecked():
            npeaks = 3
        elif self.numpeaks[2].isChecked():
            npeaks = 4
        self.matrix.updateExchange(value, indx, npeaks)

    def resetMatrix(self):
        '''Reset the matrix values'''

        # Iterate over the matrix and fill the values
        for index, num in ndenumerate(self.matrix.matrix):
            self.exview[index[0]][index[1]].setText('{0:.3f}'.format(num))

        # Set all other values to two dashes
        if len(self.matrix.matrix) == 2:
            for i in xrange(4):
                for j in xrange(4):
                    if not (i < 2 and j < 2):
                        self.exview[i][j].setText('--')
        elif len(self.matrix.matrix) == 3:
            for i in xrange(4):
                for j in xrange(4):
                    if not (i < 3 and j < 3):
                        self.exview[i][j].setText('--')

    def changeDataModel(self):
        '''Change the matrix from symmetric to not or vice versa'''

        # Change the model for the combo box
        if self.numpeaks[0].isChecked():
            npeaks = 2
        elif self.numpeaks[1].isChecked():
            npeaks = 3
        elif self.numpeaks[2].isChecked():
            npeaks = 4
        self.npmodel.setNumPeaks(npeaks)
        self.matrix.sym = self.symmetry.isChecked()
        if self.matrix.sym:
            self.exchooser.setModel(self.matrix.symex[npeaks])
        else:
            self.exchooser.setModel(self.matrix.unsymex[npeaks])

        # Reset the matrix
        self.matrix.setMatrix(npeaks)

    def attachExchange(self, indx):
        '''Attach a new exchange rate to the chooser'''
        r = self.matrix.symrate if self.matrix.sym else self.matrix.unsymrate
        self.exvalue.setText('{0:.3f}'.format(r[self.npmodel.numPeaks][indx]))
示例#32
0
class RangeWidget(QWidget):
    """Interface for changing Range information. It shows the current
       range and range policy.
       This widget was designed for use with the tab dialog. It can be used by
       itself or it can be used as part of a bigger color tab.

       Changes to this widget are emitted via a changeSignal as a boolean
       on policy, range tuple and this widget's tag.
    """

    changeSignal = Signal(bool, float, float, str)

    def __init__(self, parent, use_max, current_range, max_range, tag):
        """Creates a ColorMap widget.

           parent
               The Qt parent of this widget.

           use_max
               Whether the policy is to use max possible or set range.

           current_range
               The min and max range on creation.

           tag
               A name for this widget, will be emitted on change.
        """
        super(RangeWidget, self).__init__(parent)
        self.edit_range = (current_range[0], current_range[1])
        self.max_range = max_range
        self.use_max = use_max
        self.tag = tag

        layout = QVBoxLayout()

        self.range_check = QCheckBox("Use maximum range across applicable " +
                                     "modules.")
        layout.addWidget(self.range_check)
        if self.use_max:
            self.range_check.setChecked(True)
        else:
            self.range_check.setChecked(False)
        self.range_check.stateChanged.connect(self.checkChanged)
        layout.addItem(QSpacerItem(3, 3))

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel("Set range: "))
        self.range_min = QLineEdit(str(current_range[0]), self)
        self.range_min.editingFinished.connect(self.rangeChanged)
        hlayout.addWidget(self.range_min)
        hlayout.addWidget(QLabel(" to "))
        self.range_max = QLineEdit(str(current_range[1]), self)
        self.range_max.editingFinished.connect(self.rangeChanged)
        hlayout.addWidget(self.range_max)
        layout.addLayout(hlayout)

        self.setStates()
        self.setLayout(layout)

    def setStates(self):
        if self.use_max:
            self.range_min.setDisabled(True)
            self.range_max.setDisabled(True)
        else:
            self.range_min.setDisabled(False)
            self.range_max.setDisabled(False)

    @Slot()
    def checkChanged(self):
        """Handles check/uncheck of use max."""
        self.use_max = self.range_check.isChecked()
        self.setStates()

        if self.use_max:
            self.changeSignal.emit(self.use_max, self.max_range[0],
                                   self.max_range[1], self.tag)
        else:
            self.changeSignal.emit(self.use_max, self.edit_range[0],
                                   self.edit_range[1], self.tag)

    @Slot()
    def rangeChanged(self):
        self.edit_range = (float(self.range_min.text()),
                           float(self.range_max.text()))

        self.changeSignal.emit(self.use_max, self.edit_range[0],
                               self.edit_range[1], self.tag)
示例#33
0
class Panel(QWidget):
    def __init__(self, state, config, parent):
        super().__init__(parent)
        self.state = state
        self.config = config
        self.form = parent
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()

    def createWidgets(self):
        settings = QSettings()
        self.sortRulesGroupBox = QGroupBox("Calculate &Sort As Rules")
        defaultSortAsRules = settings.value(Gconf.Key.SortAsRules,
                                            Gopt.Default.SortAsRules)
        self.thisSortAsRules = self.config.get(Gopt.Key.SortAsRules,
                                               defaultSortAsRules)
        self.defaultSortAsRulesBox = QComboBox()
        self.form.tooltips.append((self.defaultSortAsRulesBox, """\
<p><b>Calculate Sort As Rules, Default</b></p>
<p>The default setting for the <b>Calculate Sort As Rules, For This
Index</b> combobox for new indexes.</p>"""))
        self.thisSortAsRulesBox = QComboBox()
        self.form.tooltips.append((self.thisSortAsRulesBox, """\
<p><b>Calculate Sort As Rules, For This Index</b></p>
<p>The rules to use for calculating each entry's sort as text for this
index.</p>
<p>If the rules are changed, when the dialog is closed, the new rules
will be applied to every entry in the index.</p>"""))
        self.populateSortAsRulesBox(self.defaultSortAsRulesBox,
                                    defaultSortAsRules)
        self.populateSortAsRulesBox(self.thisSortAsRulesBox,
                                    self.thisSortAsRules)

        self.pageRangeRulesBox = QGroupBox("&Page Range Rules")
        defaultPageRangeRules = settings.value(Gconf.Key.PageRangeRules,
                                               Gopt.Default.PageRangeRules)
        self.thisPageRangeRules = self.config.get(Gopt.Key.PageRangeRules,
                                                  defaultPageRangeRules)
        self.defaultPageRangeRulesBox = QComboBox()
        self.form.tooltips.append((self.defaultPageRangeRulesBox, """\
<p><b>Page Range Rules, Default</b></p>
<p>The default setting for the <b>Page Range Rules, For This Index</b>
combobox for new indexes.</p>"""))
        self.thisPageRangeRulesBox = QComboBox()
        self.form.tooltips.append((self.thisPageRangeRulesBox, """\
<p><b>Page Range Rules, For This Index</b></p>
<p>The rules to use for handling page ranges, e.g., whether in full such
as 120&ndash;124, or somehow compressed, e.g., 120&ndash;4, for this
index.</p>
<p>If the rules are changed, when the dialog is closed, the new rules
will be applied to every entry in the index.</p>"""))
        self.populatePageRangeRulesBox(self.defaultPageRangeRulesBox,
                                       defaultPageRangeRules)
        self.populatePageRangeRulesBox(self.thisPageRangeRulesBox,
                                       self.thisPageRangeRules)
        self.padDigitsGroupBox = QGroupBox("Pad &Digits")
        defaultPadDigits = int(
            settings.value(Gconf.Key.PadDigits, Gopt.Default.PadDigits))
        self.thisPadDigits = int(
            self.config.get(Gopt.Key.PadDigits, defaultPadDigits))
        self.thisPadDigitsLabel = QLabel("For This Index")
        self.thisPadDigitsSpinBox = QSpinBox()
        self.thisPadDigitsSpinBox.setAlignment(Qt.AlignRight)
        self.thisPadDigitsSpinBox.setRange(0, 12)
        self.thisPadDigitsSpinBox.setValue(self.thisPadDigits)
        self.form.tooltips.append((self.thisPadDigitsSpinBox, """\
<p><b>Pad Digits, For This Index</b></p>
<p>Sort as texts are compared textually, so if a term contains a number
(or text which is converted to a number), the number must be padded by
leading zeros to ensure correct ordering. This is the number of digits
to pad for, for this index. For example, if set to 4, the numbers 1, 23,
and 400 would be set to 0001, 0023, and 0400, in the sort as text.</p>"""))
        self.defaultPadDigitsLabel = QLabel("Default")
        self.defaultPadDigitsSpinBox = QSpinBox()
        self.defaultPadDigitsSpinBox.setAlignment(Qt.AlignRight)
        self.defaultPadDigitsSpinBox.setRange(0, 12)
        self.defaultPadDigitsSpinBox.setValue(defaultPadDigits)
        self.form.tooltips.append((self.defaultPadDigitsSpinBox, """\
<p><b>Pad Digits, Default</b></p>
<p>The default setting for the <b>Pad Digits, For This Index</b> spinbox
for new indexes.</p>"""))
        self.ignoreSubFirstsGroupBox = QGroupBox(
            "&Ignore Subentry Function Words")
        defaultIgnoreSubFirsts = bool(
            int(
                settings.value(Gconf.Key.IgnoreSubFirsts,
                               Gopt.Default.IgnoreSubFirsts)))
        thisIgnoreSubFirsts = bool(
            int(
                self.config.get(Gopt.Key.IgnoreSubFirsts,
                                defaultIgnoreSubFirsts)))
        self.thisIgnoreSubFirstsCheckBox = QCheckBox("For This Index")
        self.thisIgnoreSubFirstsCheckBox.setChecked(thisIgnoreSubFirsts)
        self.form.tooltips.append((self.thisIgnoreSubFirstsCheckBox, """\
<p><b>Ignore Subentry Function Words, For This Index</b></p>
<p>This setting applies to this index.</p>
<p>If checked, words listed in the <b>Index→Ignore Subentry Function
Words</b> list are ignored for sorting purposes when the first word of a
subentry, i.e., ignored when the first word of an entry's sort as
text.</p> <p>This should normally be checked for Chicago Manual of Style
Sort As Rules, and unchecked for NISO Rules.</p>"""))
        self.defaultIgnoreSubFirstsCheckBox = QCheckBox("Default")
        self.defaultIgnoreSubFirstsCheckBox.setChecked(defaultIgnoreSubFirsts)
        self.form.tooltips.append((self.defaultIgnoreSubFirstsCheckBox, """\
<p><b>Ignore Subentry Function Words, Default</b></p>
<p>The default setting for the <b>Ignore Subentry Function Words, For
This Index</b> checkbox for new indexes</p>"""))
        self.suggestSpelledGroupBox = QGroupBox(
            "&Suggest Spelled Out Numbers when Appropriate")
        defaultSuggestSpelled = bool(
            int(
                settings.value(Gconf.Key.SuggestSpelled,
                               Gopt.Default.SuggestSpelled)))
        thisSuggestSpelled = bool(
            int(self.config.get(Gopt.Key.SuggestSpelled,
                                defaultSuggestSpelled)))
        self.thisSuggestSpelledCheckBox = QCheckBox("For This Index")
        self.thisSuggestSpelledCheckBox.setChecked(thisSuggestSpelled)
        self.form.tooltips.append((self.thisSuggestSpelledCheckBox, """\
<p><b>Suggest Spelled Out Numbers when Appropriate, For This Index</b></p>
<p>When checked (and providing the Sort As rules in force are not NISO
rules), when adding or editing a term when the <b>Automatically
Calculate Sort As</b> checkbox is checked, and when the term contains a
number, the choice of sort as texts will include the number spelled
out.</p>"""))
        self.defaultSuggestSpelledCheckBox = QCheckBox("Default")
        self.defaultSuggestSpelledCheckBox.setChecked(defaultSuggestSpelled)
        self.form.tooltips.append((self.defaultSuggestSpelledCheckBox, """\
<p><b>Suggest Spelled Out Numbers when Appropriate, Default</b></p>
<p>The default setting for the <b>Suggest Spelled Out Numbers when
Appropriate, For This Index</b> checkbox for new indexes.</p>"""))

    def layoutWidgets(self):
        layout = QVBoxLayout()

        form = QFormLayout()
        form.addRow("For This Index", self.thisSortAsRulesBox)
        form.addRow("Default", self.defaultSortAsRulesBox)
        self.sortRulesGroupBox.setLayout(form)
        layout.addWidget(self.sortRulesGroupBox)

        form = QFormLayout()
        form.addRow("For This Index", self.thisPageRangeRulesBox)
        form.addRow("Default", self.defaultPageRangeRulesBox)
        self.pageRangeRulesBox.setLayout(form)
        layout.addWidget(self.pageRangeRulesBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisPadDigitsLabel)
        hbox.addWidget(self.thisPadDigitsSpinBox)
        hbox.addStretch(1)
        hbox.addWidget(self.defaultPadDigitsLabel)
        hbox.addWidget(self.defaultPadDigitsSpinBox)
        hbox.addStretch(3)
        self.padDigitsGroupBox.setLayout(hbox)
        layout.addWidget(self.padDigitsGroupBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisIgnoreSubFirstsCheckBox)
        hbox.addWidget(self.defaultIgnoreSubFirstsCheckBox)
        hbox.addStretch()
        self.ignoreSubFirstsGroupBox.setLayout(hbox)
        layout.addWidget(self.ignoreSubFirstsGroupBox)

        hbox = QHBoxLayout()
        hbox.addWidget(self.thisSuggestSpelledCheckBox)
        hbox.addWidget(self.defaultSuggestSpelledCheckBox)
        hbox.addStretch()
        self.suggestSpelledGroupBox.setLayout(hbox)
        layout.addWidget(self.suggestSpelledGroupBox)

        layout.addStretch()
        self.setLayout(layout)

    def createConnections(self):
        self.defaultSortAsRulesBox.currentIndexChanged.connect(
            self.setDefaultSortAsRules)
        self.defaultPageRangeRulesBox.currentIndexChanged.connect(
            self.setDefaultPageRangeRules)
        self.defaultPadDigitsSpinBox.valueChanged.connect(
            self.setDefaultPadDigits)
        self.defaultIgnoreSubFirstsCheckBox.toggled.connect(
            self.setDefaultIgnoreSubFirsts)
        self.defaultSuggestSpelledCheckBox.toggled.connect(
            self.setDefaultSuggestSpelled)

    def populateSortAsRulesBox(self, combobox, rules):
        index = -1
        for i, name in enumerate(SortAs.RulesForName):
            displayName = SortAs.RulesForName[name].name
            combobox.addItem(displayName, name)
            if name == rules:
                index = i
        combobox.setCurrentIndex(index)

    def setDefaultSortAsRules(self, index):
        index = self.defaultSortAsRulesBox.currentIndex()
        name = self.defaultSortAsRulesBox.itemData(index)
        settings = QSettings()
        settings.setValue(Gopt.Key.SortAsRules, name)

    def populatePageRangeRulesBox(self, combobox, rules):
        index = -1
        for i, name in enumerate(Pages.RulesForName):
            displayName = Pages.RulesForName[name].name
            combobox.addItem(displayName, name)
            if name == rules:
                index = i
        combobox.setCurrentIndex(index)

    def setDefaultPageRangeRules(self, index):
        index = self.defaultPageRangeRulesBox.currentIndex()
        name = self.defaultPageRangeRulesBox.itemData(index)
        settings = QSettings()
        settings.setValue(Gopt.Key.PageRangeRules, name)

    def setDefaultPadDigits(self):
        value = self.defaultPadDigitsSpinBox.value()
        settings = QSettings()
        settings.setValue(Gopt.Key.PadDigits, value)

    def setDefaultIgnoreSubFirsts(self):
        value = int(self.defaultIgnoreSubFirstsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.IgnoreSubFirsts, value)

    def setDefaultSuggestSpelled(self):
        value = int(self.defaultSuggestSpelledCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.SuggestSpelled, value)
示例#34
0
class ScaleView(QGroupBox):
    '''The box containing the rate value'''

    def __init__(self, title = 'Window Limits', parent = None):
        '''Initialize'''
        super(ScaleView, self).__init__(parent)
        self.setTitle(title)
        self._createWidgets()

    def _createWidgets(self):
        '''Create the widgets contained in this box'''

        # The three choosers
        self.xmin = QLineEdit(self)
        self.xmin.setToolTip(ttt('The lower limit of the plot, in '
                                 'wavenumbers'))
        self.xmax = QLineEdit(self)
        self.xmax.setToolTip(ttt('The upper limit of the plot, in '
                                 'wavenumbers'))
        self.reverse = QCheckBox("Reverse Limits", self)
        self.reverse.setToolTip(ttt('Display plot with higher frequencies on '
                                    'the left, not the right'))

        # Set validators for limits
        self.xmin.setValidator(QIntValidator(300, 3000, self.xmin))
        self.xmax.setValidator(QIntValidator(300, 3000, self.xmax))

        # The wavelength selection
        self.wavenum = QLineEdit('      ')
        self.wavenum.setReadOnly(True)
        self.intense = QLineEdit('     ')
        self.intense.setReadOnly(True)

    def initUI(self):
        '''Lays out the widgets'''
        total = QHBoxLayout()
        total.addWidget(QLabel("Wavenum: "))
        total.addWidget(self.wavenum)
        total.addWidget(QLabel("Intens.: "))
        total.addWidget(self.intense)
        total.addWidget(QLabel("Lower Limit"))
        total.addWidget(self.xmin)
        total.addStretch()
        total.addWidget(self.reverse)
        total.addStretch()
        total.addWidget(QLabel("Upper Limit"))
        total.addWidget(self.xmax)
        self.setLayout(total)

    def makeConnections(self):
        '''Connect the widgets together'''

        # If any changes happen, reset the scale
        self.xmin.editingFinished.connect(self.resetScale)
        self.xmax.editingFinished.connect(self.resetScale)
        self.reverse.clicked.connect(self.resetScale)

    def setModel(self, model):
        '''Attaches models to the views'''
        self.model = model

    def setValue(self, xmin, xmax, reversed):
        '''Manually sets the values that are viewed'''
        self.xmin.setText(str(xmin))
        self.xmax.setText(str(xmax))
        self.reverse.setChecked(reversed)
        self.reverse.clicked.emit()

    #######
    # SLOTS
    #######

    def resetScale(self):
        '''Checks that the given scale is valid, then resets if so'''
        try:
            xmin = int(self.xmin.text())
        except ValueError:
            return
        try:
            xmax = int(self.xmax.text())
        except ValueError:
            return
        reverse = self.reverse.isChecked()
        if xmin > xmax:
            err = "Lower limit cannot be greater than upper limit"
            error.showMessage(err)
            return
        self.model.setScale(xmin, xmax, reverse)

    def setSelection(self, x, y):
        '''Displays the current selection'''
        x = max(min(x, float(self.xmax.text())),
                float(self.xmin.text()))
        y = max(min(y, 1.0), 0.0)
        self.wavenum.setText('{0:.1f}'.format(x))
        self.intense.setText('{0:.3f}'.format(y))
示例#35
0
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("Copy Entry — {}".format(
            QApplication.applicationName()))
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()
        self.updateUi()
        settings = QSettings()
        self.updateToolTips(
            bool(
                int(
                    settings.value(Gopt.Key.ShowDialogToolTips,
                                   Gopt.Default.ShowDialogToolTips))))

    def createWidgets(self):
        selectedEid = self.state.viewAllPanel.view.selectedEid
        self.selectedEntry = self.state.model.entry(selectedEid)
        self.entryLabel = QLabel("Copy ")
        termText = Lib.elidePatchHtml(self.selectedEntry.term, self.state)
        self.termLabel = Widgets.Label.HtmlLabel("“{}”".format(termText))

        self.eidGroup = QGroupBox()

        self.copyToTopRadioButton = QRadioButton("to be a &Main Entry")
        self.tooltips.append((self.copyToTopRadioButton, """\
<p><b>to be a Main Entry</b></p>
<p>Copy the original entry to be a Main Entry (even if it is
already).</p>"""))
        self.subentryRadioButton = QRadioButton("to be a &Subentry of itself")
        self.tooltips.append((self.subentryRadioButton, """\
<p><b>to be a Subentry of itself</b></p>
<p>Copy the original entry to be a subentry of the original entry.</p>"""))
        self.siblingRadioButton = QRadioButton("to be a Si&bling of itself")
        self.tooltips.append((self.subentryRadioButton, """\
<p><b>to be a Sibling of itself</b></p>
<p>Copy the original entry to be a sibling of itself, i.e., to be a
subentry of the original entry's parent.</p>"""))

        self.filteredEntry = self.circledEntry = None
        filteredEid = self.state.viewFilteredPanel.view.selectedEid
        if filteredEid is not None:
            self.filteredEntry = self.state.model.entry(filteredEid)
        circledEid = self.state.viewAllPanel.view.circledEid
        if circledEid is not None:
            self.circledEntry = self.state.model.entry(circledEid)

        self.filteredRadioButton = QRadioButton("under &Filtered")
        self.circledRadioButton = QRadioButton("under C&ircled")
        self.recentRadioButton = QRadioButton("under &Recent")
        self.tooltips.append(
            (self.recentRadioButton, """<p><b>under Recent</b></p>
<p>Copy the current entry under a recently visited entry.</p>"""))

        self.filteredLabel = Widgets.Label.HtmlLabel()
        self.circledLabel = Widgets.Label.HtmlLabel()

        self.copyToTopRadioButton.setChecked(True)
        seen = {selectedEid}
        self.buttons = (self.copyToTopRadioButton, self.subentryRadioButton,
                        self.filteredRadioButton, self.circledRadioButton,
                        self.recentRadioButton)
        Forms.Util.setUpRadioButton(
            self, self.filteredEntry, self.filteredRadioButton,
            self.filteredLabel, self.buttons, seen,
            """<p><b>under Filtered</b></p>
<p>Copy the current entry under the filtered entry “{}”.</p>""")
        Forms.Util.setUpRadioButton(
            self, self.circledEntry, self.circledRadioButton,
            self.circledLabel, self.buttons, seen,
            """<p><b>under Circled</b></p>
<p>Copy the current entry under the circled entry “{}”.</p>""")
        self.recentComboBox = Forms.Util.createTermsComboBox(
            self.state, self.state.gotoEids, ignore=seen, maximum=MAX_RECENT)

        self.optionsGroup = QGroupBox()
        self.copyAllCheckBox = QCheckBox("Copy &All:")
        self.tooltips.append((self.copyAllCheckBox, """\
<p><b>Copy All</b></p>
<p>If you check this checkbox, the other Copy checkboxes are checked in
one go.</p>"""))
        self.copyXrefsCheckBox = QCheckBox("Cross-r&eferences")
        self.tooltips.append((self.copyXrefsCheckBox, """\
<p><b>Cross-references</b></p>
<p>Copy cross-references from the original entry(ies) to the copied
entry(ies).</p>"""))
        self.copyGroupsCheckBox = QCheckBox("&Groups")
        self.tooltips.append((self.copyGroupsCheckBox, """\
<p><b>Groups</b></p>
<p>Copy groups from the original entry(ies) to the copied
entry(ies).</p>
<p>If you check the <b>Link Pages...</b> checkbox, this checkbox will be
both checked and disabled, since linking is achieved by copying a linked
group (creating one if necessary).</p>"""))
        self.copySubentriesCheckBox = QCheckBox("S&ubentries")
        self.tooltips.append((self.copySubentriesCheckBox, """\
<p><b>Subentries</b></p>
<p>Copy the copied entry's subentries, subsubentries, and so on.</p>"""))
        self.linkPagesCheckBox = QCheckBox("&Link Pages between")
        self.linkLabel = Widgets.Label.HtmlLabel(
            "“{}” and its copy".format(termText))
        self.tooltips.append((self.linkPagesCheckBox, """\
<p><b>Link Pages</b></p>
<p>If the original entry belongs to a linked group, its copy is added to
that linked group. If the original doesn't belong to a linked group, a
new linked group is created with the name of the original's term, and
both the original and its copy are added to this new linked group.</p>
<p>If you check the this checkbox, the <b>Copy Groups</b> checkbox will be
both checked and disabled, since linking is achieved by copying a linked
group (creating one if necessary).</p>"""))
        self.withSeeCheckBox = QCheckBox("A&dd a")
        self.withSeeLabel1 = Widgets.Label.HtmlLabel(
            "<i>see</i> cross-reference from the copy to “{}”".format(
                termText))
        self.withSeeLabel2 = Widgets.Label.HtmlLabel(
            "and <i>don't</i> copy the pages")
        self.withSeeLabel2.setIndent(self.fontMetrics().width("WW"))

        self.buttonBox = QDialogButtonBox()
        self.copyButton = QPushButton(QIcon(":/copy.svg"), "C&opy")
        self.tooltips.append((self.copyButton, """<p><b>Copy</b></p>
<p>Copy the “{}” entry.</p>""".format(self.termLabel.text())))
        self.buttonBox.addButton(self.copyButton, QDialogButtonBox.AcceptRole)
        self.closeButton = QPushButton(QIcon(":/dialog-close.svg"), "&Cancel")
        self.tooltips.append((self.closeButton, """<p><b>Cancel</b></p>
<p>Close the dialog without making any changes to the index.</p>"""))
        self.buttonBox.addButton(self.closeButton, QDialogButtonBox.RejectRole)
        self.helpButton = QPushButton(QIcon(":/help.svg"), "Help")
        self.tooltips.append(
            (self.helpButton, "Help on the Copy Entry dialog"))
        self.buttonBox.addButton(self.helpButton, QDialogButtonBox.HelpRole)

    def layoutWidgets(self):
        layout = QVBoxLayout()
        entryLayout = QHBoxLayout()
        entryLayout.setSpacing(0)
        entryLayout.addWidget(self.entryLabel)
        entryLayout.addWidget(self.termLabel)
        entryLayout.addStretch()
        layout.addLayout(entryLayout)
        eidLayout = QVBoxLayout()
        eidLayout.addWidget(self.copyToTopRadioButton)
        eidLayout.addWidget(self.subentryRadioButton)
        eidLayout.addWidget(self.siblingRadioButton)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.filteredRadioButton)
        hbox.addWidget(self.filteredLabel, 1)
        eidLayout.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.circledRadioButton)
        hbox.addWidget(self.circledLabel, 1)
        eidLayout.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.recentRadioButton)
        hbox.addWidget(self.recentComboBox, 1)
        eidLayout.addLayout(hbox)
        eidLayout.addStretch()
        self.eidGroup.setLayout(eidLayout)
        layout.addWidget(self.eidGroup)
        vbox = QVBoxLayout()
        hbox = QHBoxLayout()
        hbox.addWidget(self.copyAllCheckBox)
        hbox.addWidget(self.copyXrefsCheckBox)
        hbox.addWidget(self.copyGroupsCheckBox)
        hbox.addWidget(self.copySubentriesCheckBox)
        hbox.addStretch()
        vbox.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.linkPagesCheckBox)
        hbox.addWidget(self.linkLabel)
        hbox.addStretch()
        vbox.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.withSeeCheckBox)
        hbox.addWidget(self.withSeeLabel1)
        hbox.addStretch()
        vbox.addLayout(hbox)
        vbox.addWidget(self.withSeeLabel2)
        self.optionsGroup.setLayout(vbox)
        layout.addWidget(self.optionsGroup)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.buttonBox.accepted.connect(self.copy)
        self.buttonBox.rejected.connect(self.reject)
        self.helpButton.clicked.connect(self.help)
        self.copyXrefsCheckBox.toggled.connect(self.updateUi)
        self.copyGroupsCheckBox.toggled.connect(self.updateUi)
        self.copySubentriesCheckBox.toggled.connect(self.updateUi)
        self.linkPagesCheckBox.toggled.connect(self.updateUi)
        self.withSeeCheckBox.toggled.connect(self.updateUi)
        self.copyAllCheckBox.toggled.connect(self.copyAll)
        self.recentRadioButton.toggled.connect(self.moveFocus)
        self.recentComboBox.currentIndexChanged[int].connect(
            self.recentChanged)

    def recentChanged(self):
        self.recentRadioButton.setChecked(True)
        self.updateUi()

    def moveFocus(self):
        if self.recentRadioButton.isChecked():
            self.recentComboBox.setFocus()

    def updateUi(self):
        self.recentRadioButton.setEnabled(self.recentComboBox.count())
        self.recentComboBox.setEnabled(self.recentComboBox.count())
        enable = not self.withSeeCheckBox.isChecked()
        for widget in (self.copyAllCheckBox, self.copyXrefsCheckBox,
                       self.copyGroupsCheckBox, self.copySubentriesCheckBox,
                       self.linkPagesCheckBox):
            if not enable:
                widget.setChecked(False)
            widget.setEnabled(enable)
        self.linkLabel.setEnabled(enable)
        if enable:
            if self.linkPagesCheckBox.isChecked():
                self.copyGroupsCheckBox.setChecked(True)
                self.copyGroupsCheckBox.setEnabled(False)
            else:
                self.copyGroupsCheckBox.setEnabled(True)
            self.copyAllCheckBox.setChecked(
                all(widget.isChecked()
                    for widget in (self.copyXrefsCheckBox,
                                   self.copyGroupsCheckBox,
                                   self.copySubentriesCheckBox)))

    def copyAll(self, checked):
        if checked:
            for widget in (self.copyXrefsCheckBox, self.copyGroupsCheckBox,
                           self.copySubentriesCheckBox):
                widget.setChecked(True)

    def help(self):
        self.state.help("xix_ref_dlg_copy.html")

    def copy(self):
        self.state.maybeSave()
        eid = self.selectedEntry.eid
        peid = None
        if self.copyToTopRadioButton.isChecked():
            peid = ROOT
            description = "copy “{}” to be main entry"
        elif self.subentryRadioButton.isChecked():
            peid = eid
            description = "copy “{}” to be subentry of itself"
        elif self.siblingRadioButton.isChecked():
            peid = self.selectedEntry.peid
            description = "copy “{}” to be sibling of itself"
        elif self.filteredRadioButton.isChecked():
            peid = self.filteredEntry.eid
            description = "copy “{}” under filtered"
        elif self.circledRadioButton.isChecked():
            peid = self.circledEntry.eid
            description = "copy “{}” under circled"
        elif self.recentRadioButton.isChecked():
            peid = self.recentComboBox.itemData(
                self.recentComboBox.currentIndex())
            description = "copy “{}” under recently visited"
        if peid is not None:  # Should always be True
            description = description.format(
                Lib.elidePatchHtml(self.selectedEntry.term, self.state))
            self.state.model.copyEntry(
                Lib.CopyInfo(eid, peid, self.copyXrefsCheckBox.isChecked(),
                             self.copyGroupsCheckBox.isChecked(),
                             self.copySubentriesCheckBox.isChecked(),
                             self.linkPagesCheckBox.isChecked(),
                             self.withSeeCheckBox.isChecked(), description))
            say(re.sub(r"^copy", "Copied", Lib.htmlToPlainText(description)),
                SAY_TIMEOUT)
        self.accept()
示例#36
0
class LoginView(View):
    """`View` derived class. Defines the log in widget"""
    
    login = Signal((str, str, str, bool,))
    
    def __init__(self, parent=None):
        """
        Init method. Initializes parent classes
        
        :param parent: Reference to a `QWidget` object to be used as parent 
        """
        
        super(LoginView, self).__init__(parent)
        
        self.createWidgets()
        self.createLayouts()
        self.setFixedSize(250, 340)
        
    def createLayouts(self):
        """Put widgets into layouts, thus creating the widget"""
        
        mainLayout = QHBoxLayout()
        fieldsLayout = QVBoxLayout()
        ftpInfoLayout = QHBoxLayout()
        buttonLayout = QHBoxLayout()
        
        mainLayout.addStretch(20)
        
        fieldsLayout.addStretch(80)
        fieldsLayout.addWidget(self.linkLabel)
        fieldsLayout.addWidget(self.line)
        fieldsLayout.addStretch(20)
        
        ftpInfoLayout.addWidget(self.hostLabel, 50, Qt.AlignLeft)
        ftpInfoLayout.addStretch(20)
        ftpInfoLayout.addWidget(self.sslLabel, 20, Qt.AlignRight)
        ftpInfoLayout.addWidget(self.sslCheck, 10, Qt.AlignRight)
        
        fieldsLayout.addLayout(ftpInfoLayout)
        fieldsLayout.addWidget(self.hostEdit)
        fieldsLayout.addWidget(self.usernameLabel)
        fieldsLayout.addWidget(self.usernameEdit)
        fieldsLayout.addWidget(self.passwdLabel)
        fieldsLayout.addWidget(self.passwdEdit)
        fieldsLayout.addStretch(30)
        
        buttonLayout.addStretch(50)
        buttonLayout.addWidget(self.loginButton, 50, Qt.AlignRight)
        
        fieldsLayout.addLayout(buttonLayout)
        fieldsLayout.addStretch(20)
        
        mainLayout.addLayout(fieldsLayout, 30)
        mainLayout.addStretch(20)
        
        self.setLayout(mainLayout)
        
    def createWidgets(self):
        """Create children widgets needed by this view"""

        fieldsWidth = 200
        labelsFont = View.labelsFont()
        editsFont = View.editsFont()
        self.setLogo()
        
        self.hostLabel = QLabel(self)
        self.hostEdit = QLineEdit(self)
        self.sslLabel = QLabel(self)
        self.sslCheck = QCheckBox(self)     
        self.hostLabel.setText('FTP Location')
        self.hostLabel.setFont(labelsFont)
        self.hostEdit.setFixedWidth(fieldsWidth)
        self.hostEdit.setFont(editsFont)
        self.sslLabel.setText('SSL')
        self.sslLabel.setFont(labelsFont)
        
        self.usernameLabel = QLabel(self)
        self.usernameEdit = QLineEdit(self)
        self.usernameLabel.setText('Username')
        self.usernameLabel.setFont(labelsFont)
        self.usernameEdit.setFixedWidth(fieldsWidth)
        self.usernameEdit.setFont(editsFont)
        
        self.passwdLabel = QLabel(self)
        self.passwdEdit = QLineEdit(self)
        self.passwdLabel.setText('Password')
        self.passwdLabel.setFont(labelsFont)
        self.passwdEdit.setFixedWidth(fieldsWidth)
        self.passwdEdit.setEchoMode(QLineEdit.Password)
        self.passwdEdit.setFont(editsFont)
        self.passwdEdit.returnPressed.connect(self.onLoginClicked)
        
        self.loginButton = QPushButton(self)
        self.loginButton.setText('Login')
        self.loginButton.setFont(labelsFont)
        self.loginButton.setFixedWidth(fieldsWidth / 2)
        self.loginButton.clicked.connect(self.onLoginClicked)
        
        # Sets previously stored values into the fields, if any
        settings = get_settings()
        
        self.hostEdit.setText(settings.value(SettingsKeys['host'], ''))
        self.usernameEdit.setText(settings.value(SettingsKeys['username'], ''))
        self.passwdEdit.setText(crypt.decrypt(settings.value(SettingsKeys['passwd'], '')))
        
        # Unicode to boolean conversion
        ssl = settings.value(SettingsKeys['ssl'], u'true') 
        ssl = True if ssl == u'true' else False
        self.sslCheck.setChecked(ssl)
        
    @Slot() 
    def onLoginClicked(self):
        """
        Slot. Called on the user clicks on the `loginButton` button
        """
        # Takes out the user input from the fields
        host = self.hostEdit.text()
        username = self.usernameEdit.text()
        passwd = self.passwdEdit.text()
        ssl = self.sslCheck.isChecked()
        
        print 'Logging in: %s, %s, %s' % (host, username, '*' * len(passwd))
        
        if len(host) > 0:
            # If the fields are valid, store them using a `QSettings` object
            # and triggers a log in request
            settings = get_settings()
            
            settings.setValue(SettingsKeys['host'], host)
            settings.setValue(SettingsKeys['username'], username)
            settings.setValue(SettingsKeys['passwd'], crypt.encrypt(passwd))
            settings.setValue(SettingsKeys['ssl'], ssl)
            
            self.setEnabled(False)
            self.login.emit(host.strip(), username, passwd, ssl)
            
    @Slot()
    def onFailedLogIn(self):
        """
        Slot. Called when the log in request fails
        """
        
        # Enables the fields again for user input
        self.setEnabled(True)
示例#37
0
class MainWindow(QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Cobaya input generator for Cosmology")
        self.setGeometry(0, 0, 1500, 1000)
        self.move(
            QApplication.desktop().screen().rect().center() - self.rect().center())
        self.show()
        # Main layout
        self.layout = QHBoxLayout()
        self.setLayout(self.layout)
        self.layout_left = QVBoxLayout()
        self.layout.addLayout(self.layout_left)
        self.layout_output = QVBoxLayout()
        self.layout.addLayout(self.layout_output)
        # LEFT: Options
        self.options = QWidget()
        self.layout_options = QVBoxLayout()
        self.options.setLayout(self.layout_options)
        self.options_scroll = QScrollArea()
        self.options_scroll.setWidget(self.options)
        self.options_scroll.setWidgetResizable(True)
        self.layout_left.addWidget(self.options_scroll)
        self.atoms = odict()
        titles = odict([
            ["preset", "Presets"],
            ["theory", "Theory code"],
            ["primordial", "Primordial perturbations"],
            ["geometry", "Geometry"],
            ["hubble", "Constaint on hubble parameter"],
            ["baryons", "Baryon sector"],
            ["dark_matter", "Dark matter"],
            ["dark_energy", "Lambda / Dark energy"],
            ["neutrinos", "Neutrinos and other extra matter"],
            ["bbn", "BBN"],
            ["reionization", "Reionization history"],
            ["cmb_lensing", "CMB lensing"],
            ["cmb", "CMB experiments"],
            ["sampler", "Samplers"]])
        for a in titles:
            self.atoms[a] = {
                "group": QGroupBox(titles[a]),
                "combo": QComboBox()}
            self.layout_options.addWidget(self.atoms[a]["group"])
            self.atoms[a]["layout"] = QVBoxLayout(self.atoms[a]["group"])
            self.atoms[a]["layout"].addWidget(self.atoms[a]["combo"])
            self.atoms[a]["combo"].addItems(
                [text(k,v) for k,v in getattr(input_database, a).items()])
        # Connect to refreshers -- needs to be after adding all elements
        for a in self.atoms:
            if a == "preset":
                self.atoms["preset"]["combo"].currentIndexChanged.connect(
                    self.refresh_preset)
                continue
            self.atoms[a]["combo"].currentIndexChanged.connect(self.refresh)
        # Add Planck-naming checkbox and connect to refresher too
        self.planck_names = QCheckBox("Keep common names")
        self.atoms["theory"]["layout"].addWidget(self.planck_names)
        self.planck_names.stateChanged.connect(self.refresh)
        # RIGHT: Output + buttons
        self.display_tabs = QTabWidget()
        self.display = {}
        for k in ["yaml", "python"]:
            self.display[k] = QTextEdit()
            self.display[k].setLineWrapMode(QTextEdit.NoWrap)
            self.display[k].setFontFamily("mono")
            self.display[k].setCursorWidth(0)
            self.display[k].setReadOnly(True)
            self.display_tabs.addTab(self.display[k], k)
        self.layout_output.addWidget(self.display_tabs)
        # Buttons
        self.buttons = QHBoxLayout()
        self.save_button = QPushButton('Save', self)
        self.copy_button = QPushButton('Copy to clipboard', self)
        self.buttons.addWidget(self.save_button)
        self.buttons.addWidget(self.copy_button)
        self.save_button.released.connect(self.save_file)
        self.copy_button.released.connect(self.copy_clipb)
        self.layout_output.addLayout(self.buttons)
        self.save_dialog = QFileDialog()
        self.save_dialog.setFileMode(QFileDialog.AnyFile)
        self.save_dialog.setAcceptMode(QFileDialog.AcceptSave)
        # Select first preset, by default
#        print(self.atoms["preset"]["combo"].itemText(0))

    @Slot()
    def refresh(self):
        info = create_input(planck_names=self.planck_names.isChecked(), **{
            k:str(self.atoms[k]["combo"].currentText().split(_separator)[0])
            for k in self.atoms if k is not "preset"})
        self.refresh_display(info)

    @Slot()
    def refresh_preset(self):
        preset = self.atoms["preset"]["combo"].currentText().split(_separator)[0]
        info = create_input(preset=preset)
        self.refresh_display(info)
        # Update combo boxes to reflect the preset values, without triggering update
        for k,v in input_database.preset[preset].items():
            if k in [input_database._desc, "derived"]:
                continue
            self.atoms[k]["combo"].blockSignals(True)
            self.atoms[k]["combo"].setCurrentIndex(
                self.atoms[k]["combo"].findText(
                    text(v,getattr(input_database, k).get(v))))
            self.atoms[k]["combo"].blockSignals(False)

    def refresh_display(self, info):
        self.display["python"].setText(
            "from collections import OrderedDict\n\ninfo = " + pformat(info))
        self.display["yaml"].setText(yaml_dump(info))

    @Slot()
    def save_file(self):
        ftype = next(k for k,w in self.display.items()
                     if w is self.display_tabs.currentWidget())
        ffilter = {"yaml": "Yaml files (*.yaml *.yml)", "python": "(*.py)"}[ftype]
        fsuffix = {"yaml": ".yaml", "python": ".py"}[ftype]
        fname, path = self.save_dialog.getSaveFileName(
            self.save_dialog, "Save input file", fsuffix, ffilter, os.getcwd())
        if not fname.endswith(fsuffix):
            fname += fsuffix
        with open(fname, "w+") as f:
            f.write(self.display_tabs.currentWidget().toPlainText())

    @Slot()
    def copy_clipb(self):
        self.clipboard.setText(self.display_tabs.currentWidget().toPlainText())
class RepresentationPane(BasePane):
    def __init__(self, setting_dict):
        BasePane.__init__( self )

        repLayout = QVBoxLayout()

        genLayout = QFormLayout()
        self.winLenEdit = QLineEdit()
        genLayout.addRow(QLabel('Window length (s):'),self.winLenEdit)
        self.timeStepEdit = QLineEdit()
        genLayout.addRow(QLabel('Time step (s):'),self.timeStepEdit)
        self.minFreqEdit = QLineEdit()
        genLayout.addRow(QLabel('Minimum frequency (Hz):'),self.minFreqEdit)
        self.maxFreqEdit = QLineEdit()
        genLayout.addRow(QLabel('Maximum frequency (Hz):'),self.maxFreqEdit)
        self.numCoresEdit = QLineEdit()
        genLayout.addRow(QLabel('Number of cores (multiprocessing):'),self.numCoresEdit)

        repBox = QGroupBox()
        self.envelopeRadio = QRadioButton('Amplitude envelopes')
        self.mfccRadio = QRadioButton('MFCCs')
        self.mhecRadio = QRadioButton('MHECs')
        self.prosodyRadio = QRadioButton('Prosody')
        self.formantRadio = QRadioButton('Formants')
        hbox = QHBoxLayout()
        hbox.addWidget(self.envelopeRadio)
        hbox.addWidget(self.mfccRadio)
        #hbox.addWidget(self.mhecRadio)
        #hbox.addWidget(self.prosodyRadio)
        #hbox.addWidget(self.formantRadio)
        repBox.setLayout(hbox)

        genLayout.addRow(QLabel('Token representation:'),repBox)

        genWidget = QGroupBox('General')
        genWidget.setLayout(genLayout)
        repLayout.addWidget(genWidget)

        envLayout = QFormLayout()
        self.bandEdit = QLineEdit()
        envLayout.addRow(QLabel('Number of bands:'),self.bandEdit)
        self.gammatoneCheck = QCheckBox()
        envLayout.addRow(QLabel('Gammatone:'),self.gammatoneCheck)
        self.windowCheck = QCheckBox()
        envLayout.addRow(QLabel('Windowed:'),self.windowCheck)


        envWidget = QGroupBox('Amplitude envelopes')
        envWidget.setLayout(envLayout)
        repLayout.addWidget(envWidget)

        mfccLayout = QFormLayout()
        self.numCCEdit = QLineEdit()
        mfccLayout.addRow(QLabel('Number of coefficents:'),self.numCCEdit)
        self.numFiltersEdit = QLineEdit()
        mfccLayout.addRow(QLabel('Number of filters:'),self.numFiltersEdit)
        self.powerCheck = QCheckBox()
        mfccLayout.addRow(QLabel('Use power (first coefficient):'),self.powerCheck)

        mfccWidget = QGroupBox('MFCC')
        mfccWidget.setLayout(mfccLayout)

        repLayout.addWidget(mfccWidget)

        self.setLayout(repLayout)

        self.winLenEdit.setText(str(setting_dict['win_len']))
        self.timeStepEdit.setText(str(setting_dict['time_step']))
        freq_lims = setting_dict['freq_lims']
        self.minFreqEdit.setText(str(freq_lims[0]))
        self.maxFreqEdit.setText(str(freq_lims[1]))
        self.numCoresEdit.setText(str(setting_dict['num_cores']))

        rep = setting_dict['rep']
        if rep == 'mfcc':
            self.mfccRadio.setChecked(True)
        elif rep == 'mhec':
            self.mhecRadio.setChecked(True)
        elif rep == 'prosody':
            self.prosodyRadio.setChecked(True)
        elif rep == 'formant':
            self.formantRadio.setChecked(True)
        elif rep == 'envelopes':
            self.envelopeRadio.setChecked(True)

        self.bandEdit.setText(str(setting_dict['envelope_bands']))

        if setting_dict['use_gammatone']:
            self.gammatoneCheck.setChecked(True)
        if setting_dict['use_window']:
            self.windowCheck.setChecked(True)

        self.numFiltersEdit.setText(str(setting_dict['mfcc_filters']))
        self.numCCEdit.setText(str(setting_dict['num_coeffs']))
        if setting_dict['use_power']:
            self.powerCheck.setChecked(True)

        self.prev_state = setting_dict

    def get_current_state(self):
        setting_dict = {}

        if self.mfccRadio.isChecked():
            setting_dict['rep'] = 'mfcc'
        elif self.mhecRadio.isChecked():
            setting_dict['rep'] = 'mhec'
        elif self.prosodyRadio.isChecked():
            setting_dict['rep'] = 'prosody'
        elif self.formantRadio.isChecked():
            setting_dict['rep'] = 'formant'
        elif self.envelopeRadio.isChecked():
            setting_dict['rep'] = 'envelopes'

        setting_dict['win_len'] = float(self.winLenEdit.text())
        setting_dict['time_step'] = float(self.timeStepEdit.text())
        setting_dict['freq_lims'] = (int(self.minFreqEdit.text()),
                                    int(self.maxFreqEdit.text()))
        setting_dict['num_cores'] = int(self.numCoresEdit.text())

        setting_dict['envelope_bands'] = int(self.bandEdit.text())
        setting_dict['use_gammatone'] = int(self.gammatoneCheck.isChecked())
        setting_dict['use_window'] = int(self.windowCheck.isChecked())

        setting_dict['num_coeffs'] = int(self.numCCEdit.text())
        setting_dict['mfcc_filters'] = int(self.numFiltersEdit.text())
        setting_dict['use_power'] = int(self.powerCheck.isChecked())

        return setting_dict

    def is_changed(self):
        cur_state = self.get_current_state()
        if self.prev_state['rep'] != cur_state['rep']:
            return True
        if cur_state['rep'] == 'mfcc':
            for k in ['win_len','time_step','freq_lims',
                    'num_coeffs','mfcc_filters','use_power']:
                if cur_state[k] != self.prev_state[k]:
                    return True
        elif cur_state['rep'] == 'envelopes':
            for k in ['freq_lims','envelope_bands',
                        'use_gammatone', 'use_window']:
                if cur_state[k] != self.prev_state[k]:
                    return True
            if cur_state['use_window']:
                for k in ['win_len','time_step']:
                    if cur_state[k] != self.prev_state[k]:
                        return True
        return False
示例#39
0
class MainWindow(QWidget):
    # noinspection PyUnresolvedReferences
    def __init__(self, clipboard):
        super().__init__()
        self.clipboard = clipboard
        self.setWindowIcon(QIcon('Logo_rendered_edited.png'))
        self.layout = QBoxLayout(QBoxLayout.TopToBottom, self)
        self.generator = CtSesam()
        self.iterations = 4096
        # Master password
        self.master_password_label = QLabel("&Master-Passwort:")
        self.maser_password_edit = QLineEdit()
        self.maser_password_edit.setEchoMode(QLineEdit.EchoMode.Password)
        self.maser_password_edit.textChanged.connect(self.reset_iterations)
        self.maser_password_edit.returnPressed.connect(self.move_focus)
        self.maser_password_edit.setMaximumHeight(28)
        self.master_password_label.setBuddy(self.maser_password_edit)
        self.layout.addWidget(self.master_password_label)
        self.layout.addWidget(self.maser_password_edit)
        # Domain
        self.domain_label = QLabel("&Domain:")
        self.domain_edit = QLineEdit()
        self.domain_edit.textChanged.connect(self.reset_iterations)
        self.domain_edit.returnPressed.connect(self.move_focus)
        self.domain_edit.setMaximumHeight(28)
        self.domain_label.setBuddy(self.domain_edit)
        self.layout.addWidget(self.domain_label)
        self.layout.addWidget(self.domain_edit)
        # Username
        self.username_label = QLabel("&Username:"******"Sonderzeichen")
        self.special_characters_checkbox.setChecked(True)
        self.special_characters_checkbox.stateChanged.connect(self.reset_iterations)
        self.layout.addWidget(self.special_characters_checkbox)
        self.letters_checkbox = QCheckBox("Buchstaben")
        self.letters_checkbox.setChecked(True)
        self.letters_checkbox.stateChanged.connect(self.reset_iterations)
        self.layout.addWidget(self.letters_checkbox)
        self.digits_checkbox = QCheckBox("Zahlen")
        self.digits_checkbox.setChecked(True)
        self.digits_checkbox.stateChanged.connect(self.reset_iterations)
        self.layout.addWidget(self.digits_checkbox)
        # Length slider
        self.length_label = QLabel("&Länge:")
        self.length_display = QLabel()
        self.length_label_layout = QBoxLayout(QBoxLayout.LeftToRight)
        self.length_label_layout.addWidget(self.length_label)
        self.length_label_layout.addWidget(self.length_display)
        self.length_label_layout.addStretch()
        self.length_slider = QSlider(Qt.Horizontal)
        self.length_slider.setMinimum(4)
        self.length_slider.setMaximum(20)
        self.length_slider.setPageStep(1)
        self.length_slider.setValue(10)
        self.length_display.setText(str(self.length_slider.sliderPosition()))
        self.length_slider.valueChanged.connect(self.length_slider_changed)
        self.length_label.setBuddy(self.length_slider)
        self.layout.addLayout(self.length_label_layout)
        self.layout.addWidget(self.length_slider)
        # Button
        self.generate_button = QPushButton("Erzeugen")
        self.generate_button.clicked.connect(self.generate_password)
        self.generate_button.setAutoDefault(True)
        self.layout.addWidget(self.generate_button)
        # Password
        self.password_label = QLabel("&Passwort:")
        self.password = QLabel()
        self.password.setTextFormat(Qt.PlainText)
        self.password.setAlignment(Qt.AlignCenter)
        self.password.setFont(QFont("Helvetica", 18, QFont.Bold))
        self.password_label.setBuddy(self.password)
        self.layout.addWidget(self.password_label)
        self.layout.addWidget(self.password)
        # Iteration display
        self.message_label = QLabel()
        self.message_label.setTextFormat(Qt.RichText)
        self.message_label.setVisible(False)
        self.layout.addWidget(self.message_label)
        # Window layout
        self.layout.addStretch()
        self.setGeometry(0, 30, 300, 400)
        self.setWindowTitle("c't SESAM")
        self.maser_password_edit.setFocus()
        self.show()

    def length_slider_changed(self):
        self.length_display.setText(str(self.length_slider.sliderPosition()))
        self.reset_iterations()

    def reset_iterations(self):
        self.iterations = 4096
        self.message_label.setVisible(False)
        self.password.setText('')
        self.clipboard.setText('')

    def move_focus(self):
        line_edits = [self.maser_password_edit, self.domain_edit, self.username_edit]
        for i, edit in enumerate(line_edits):
            if edit.hasFocus() and i + 1 < len(line_edits):
                line_edits[i + 1].setFocus()
                return True
        self.generate_button.setFocus()

    def generate_password(self):
        if len(self.domain_edit.text()) <= 0:
            self.reset_iterations()
            self.message_label.setText(
                '<span style="font-size: 10px; color: #aa0000;">Bitte geben Sie eine Domain an.</span>')
            self.message_label.setVisible(True)
            return False
        if self.letters_checkbox.isChecked() or \
           self.digits_checkbox.isChecked() or \
           self.special_characters_checkbox.isChecked():
            self.generator.set_password_characters(
                use_letters=self.letters_checkbox.isChecked(),
                use_digits=self.digits_checkbox.isChecked(),
                use_special_characters=self.special_characters_checkbox.isChecked())
        else:
            self.reset_iterations()
            self.message_label.setText(
                '<span style="font-size: 10px; color: #aa0000;">Bei den aktuellen Einstellungen ' +
                'kann kein Passwort berechnet werden.</span>')
            self.message_label.setVisible(True)
            return False
        password = self.generator.generate(
            master_password=self.maser_password_edit.text(),
            domain=self.domain_edit.text(),
            username=self.username_edit.text(),
            length=self.length_slider.sliderPosition(),
            iterations=self.iterations
        )
        self.password.setText(password)
        self.password.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
        self.clipboard.setText(password)
        self.message_label.setText(
            '<span style="font-size: 10px; color: #888888;">Das Passwort wurde ' + str(self.iterations) +
            ' mal gehasht <br />und in die Zwischenablage kopiert.</span>')
        self.message_label.setVisible(True)
        self.iterations += 1
示例#40
0
class beso_gui(QDialog):
    def __init__(self):
        super().__init__()
        self.title = 'BESO Topology Optimization (experimental)'
        self.left = 250
        self.top = 30
        self.width = 550
        self.height = 730

        beso_gui.inp_file = ""
        beso_gui.beso_dir = os.path.dirname(__file__)

        self.initUI()

    # def closeEvent(self, event):
    #     self.close()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Select analysis file button
        button = QPushButton('Select analysis file', self)
        button.setToolTip('*.inp CalculiX analysis file.')
        button.move(10, 10)
        button.clicked.connect(self.on_click)

        # Text box - file path and name
        self.textbox_file_name = QLineEdit(self)
        self.textbox_file_name.move(120, 15)
        self.textbox_file_name.resize(420, 20)
        self.textbox_file_name.setText("None analysis file selected")
        self.textbox_file_name.setToolTip('Analysis file.')

        # Update button
        button1 = QPushButton('Update domains', self)
        button1.setToolTip(
            'Update naming inputs and material data from FreeCAD.')
        button1.move(10, 50)
        button1.clicked.connect(self.on_click1)

        # Domains definition

        # Label above domains definition
        label21 = QLabel('Domain 0', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(120, 50)

        label21 = QLabel('Domain 1', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(260, 50)

        label21 = QLabel('Domain 2', self)
        label21.setStyleSheet("font-weight: bold")
        label21.move(400, 50)

        label24 = QLabel('Material object', self)
        label24.move(20, 80)

        label25 = QLabel('Thickness object', self)
        label25.move(20, 110)

        label26 = QLabel('As design domain', self)
        label26.move(20, 140)

        label27 = QLabel('Stress limit [MPa]', self)
        label27.move(20, 170)

        # Combo box - select domain by material object
        self.combo = QComboBox(self)
        self.combo.setToolTip('Material object to define the domain.')
        self.combo.move(120, 80)
        self.combo.resize(140, 30)
        self.combo.currentIndexChanged.connect(self.on_change)

        self.combo1 = QComboBox(self)
        self.combo1.setToolTip('Material object to define the domain.')
        self.combo1.move(260, 80)
        self.combo1.resize(140, 30)
        self.combo1.currentIndexChanged.connect(self.on_change1)

        self.combo2 = QComboBox(self)
        self.combo2.setToolTip('Material object to define the domain.')
        self.combo2.move(400, 80)
        self.combo2.resize(140, 30)
        self.combo2.currentIndexChanged.connect(self.on_change2)

        # Combo box - select thickness object
        self.combo0t = QComboBox(self)
        self.combo0t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo0t.move(120, 110)
        self.combo0t.resize(140, 30)

        self.combo1t = QComboBox(self)
        self.combo1t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo1t.move(260, 110)
        self.combo1t.resize(140, 30)

        self.combo2t = QComboBox(self)
        self.combo2t.setToolTip(
            'Thickness object to specify if domain is for shells.')
        self.combo2t.move(400, 110)
        self.combo2t.resize(140, 30)

        self.textbox3 = QLineEdit(self)
        self.textbox3.move(120, 170)
        self.textbox3.resize(40, 20)
        # self.textbox3.setText("")
        self.textbox3.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        self.textbox4 = QLineEdit(self)
        self.textbox4.move(260, 170)
        self.textbox4.resize(40, 20)
        # self.textbox4.setText("")
        self.textbox4.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        self.textbox5 = QLineEdit(self)
        self.textbox5.move(400, 170)
        self.textbox5.resize(40, 20)
        # self.textbox5.setText("")
        self.textbox5.setToolTip(
            'Thickness [mm] of shell elements in the domain.\n'
            'This value overwrites thickness defined in FreeCAD')

        # Check box - design or nondesign
        self.checkbox = QCheckBox('', self)
        self.checkbox.setChecked(True)
        self.checkbox.setToolTip('Check to be the design domain.')
        self.checkbox.move(120, 140)

        self.checkbox1 = QCheckBox('', self)
        self.checkbox1.setChecked(True)
        self.checkbox1.setToolTip('Check to be the design domain.')
        self.checkbox1.move(260, 140)

        self.checkbox2 = QCheckBox('', self)
        self.checkbox2.setChecked(True)
        self.checkbox2.setToolTip('Check to be the design domain.')
        self.checkbox2.move(400, 140)

        # Text box - stress limit
        self.textbox = QLineEdit(self)
        self.textbox.move(120, 170)
        self.textbox.resize(40, 20)
        # self.textbox.setText("")
        self.textbox.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        self.textbox1 = QLineEdit(self)
        self.textbox1.move(260, 170)
        self.textbox1.resize(40, 20)
        # self.textbox1.setText("")
        self.textbox1.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        self.textbox2 = QLineEdit(self)
        self.textbox2.move(400, 170)
        self.textbox2.resize(40, 20)
        # self.textbox2.setText("")
        self.textbox2.setToolTip(
            'Von Mises stress [MPa] limit, when reached, material removing will stop.'
        )

        # Filters

        # Label above filter definition
        label31 = QLabel('Filter 0', self)
        label31.setStyleSheet("font-weight: bold")
        label31.move(120, 210)

        label32 = QLabel('Filter 1', self)
        label32.setStyleSheet("font-weight: bold")
        label32.move(260, 210)

        label33 = QLabel('Filter 2', self)
        label33.setStyleSheet("font-weight: bold")
        label33.move(400, 210)

        label34 = QLabel('Type', self)
        label34.move(20, 240)

        label35 = QLabel('Range [mm]', self)
        label35.move(20, 270)

        label36 = QLabel('Direction vector', self)
        label36.move(20, 300)

        label37 = QLabel('Apply to', self)
        label37.move(20, 330)

        # Combo box - select filter type
        self.combo6 = QComboBox(self)
        self.combo6.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo6.addItem("None")
        self.combo6.addItem("simple")
        self.combo6.addItem("casting")
        self.combo6.setCurrentIndex(1)
        self.combo6.move(120, 240)
        self.combo6.currentIndexChanged.connect(self.on_change6)

        self.combo7 = QComboBox(self)
        self.combo7.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo7.addItem("None")
        self.combo7.addItem("simple")
        self.combo7.addItem("casting")
        self.combo7.move(260, 240)
        self.combo7.currentIndexChanged.connect(self.on_change7)

        self.combo8 = QComboBox(self)
        self.combo8.setToolTip(
            'Filters:\n'
            '"simple" to suppress checkerboard effect,\n'
            '"casting" to prescribe casting direction (opposite to milling direction)\n'
            'Recommendation: for casting use as first "casting" and as second "simple"'
        )
        self.combo8.addItem("None")
        self.combo8.addItem("simple")
        self.combo8.addItem("casting")
        self.combo8.move(400, 240)
        self.combo8.currentIndexChanged.connect(self.on_change8)

        # Text box - filter range
        self.textbox6 = QLineEdit(self)
        self.textbox6.move(120, 270)
        self.textbox6.resize(50, 20)
        # self.textbox6.setText("")
        self.textbox6.setToolTip(
            'Filter range [mm], recommended two times mesh size.')

        self.textbox7 = QLineEdit(self)
        self.textbox7.move(260, 270)
        self.textbox7.resize(50, 20)
        # self.textbox7.setText("")
        self.textbox7.setToolTip(
            'Filter range [mm], recommended two times mesh size.')
        self.textbox7.setEnabled(False)

        self.textbox8 = QLineEdit(self)
        self.textbox8.move(400, 270)
        self.textbox8.resize(50, 20)
        # self.textbox8.setText("")
        self.textbox8.setToolTip(
            'Filter range [mm], recommended two times mesh size.')
        self.textbox8.setEnabled(False)

        # Text box - casting direction
        self.textbox9 = QLineEdit(self)
        self.textbox9.move(120, 300)
        self.textbox9.resize(80, 20)
        self.textbox9.setText("0, 0, 1")
        self.textbox9.setEnabled(False)
        self.textbox9.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        self.textbox10 = QLineEdit(self)
        self.textbox10.move(260, 300)
        self.textbox10.resize(80, 20)
        self.textbox10.resize(80, 20)
        self.textbox10.setText("0, 0, 1")
        self.textbox10.setEnabled(False)
        self.textbox10.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        self.textbox11 = QLineEdit(self)
        self.textbox11.move(400, 300)
        self.textbox11.resize(80, 20)
        self.textbox11.setText("0, 0, 1")
        self.textbox11.setEnabled(False)
        self.textbox11.setToolTip(
            'Casting direction vector, e.g. direction in z axis:\n'
            '0, 0, 1\n\n'
            'solid              void\n'
            'XXXXXX.................\n'
            'XXX........................\n'
            'XX...........................          --> z axis\n'
            'XXXXX....................\n'
            'XXXXXXXXXXX......')

        # list widget - select domains
        self.widget = QListWidget(self)
        self.widget.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget.move(120, 330)
        self.widget.resize(140, 120)
        self.widget.setSelectionMode(QAbstractItemView.MultiSelection)

        self.widget1 = QListWidget(self)
        self.widget1.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget1.move(260, 330)
        self.widget1.resize(140, 120)
        self.widget1.setSelectionMode(QAbstractItemView.MultiSelection)
        self.widget1.setEnabled(False)

        self.widget2 = QListWidget(self)
        self.widget2.setToolTip(
            'Domains affected by the filter.\n'
            'Select only from domains which you defined above.')
        self.widget2.move(400, 330)
        self.widget2.resize(140, 120)
        self.widget2.setSelectionMode(QAbstractItemView.MultiSelection)
        self.widget2.setEnabled(False)

        # Other settings
        label40 = QLabel('Other settings', self)
        label40.setStyleSheet("font-weight: bold")
        label40.move(10, 470)

        # AR, RR slider
        label41 = QLabel('Change per iteration:   low', self)
        label41.setFixedWidth(150)
        label41.move(10, 500)
        label42 = QLabel('high', self)
        label42.move(240, 500)

        self.slider = QSlider(Qt.Horizontal, self)
        self.slider.setRange(1, 3)
        self.slider.setSingleStep(1)
        self.slider.setValue(2)
        self.slider.move(150, 500)
        self.slider.resize(80, 30)
        self.slider.setToolTip(
            'Sets mass change per iteration, which is controlled as\n'
            'slow:   mass_addition_ratio=0.01,  mass_removal_ratio=0.02\n'
            'middle: mass_addition_ratio=0.015, mass_removal_ratio=0.03\n'
            'fast:   mass_addition_ratio=0.03,  mass_removal_ratio=0.06')

        # optimization base combobox
        label51 = QLabel('Optimization base', self)
        label51.move(10, 530)
        self.combo51 = QComboBox(self)
        self.combo51.setToolTip(
            'Basic principle to determine if element should remain or be removed:\n'
            '"stiffness" to maximize stiffness (minimize compliance),\n'
            '"heat" to maximize heat flow.')
        self.combo51.addItem("stiffness")
        self.combo51.addItem("heat")
        self.combo51.move(120, 530)

        # mass goal ratio
        label52 = QLabel('Mass goal ratio', self)
        label52.move(10, 560)
        self.textbox52 = QLineEdit(self)
        self.textbox52.move(120, 560)
        self.textbox52.resize(50, 20)
        self.textbox52.setText("0.4")
        self.textbox52.setToolTip(
            'Fraction of all design domains masses to be achieved;\n'
            'between 0 and 1.')

        # generate conf. file button
        button21 = QPushButton('Generate conf. file', self)
        button21.setToolTip(
            'Writes configuration file with optimization parameters.')
        button21.move(10, 600)
        button21.clicked.connect(self.on_click21)

        # edit conf. file button
        button22 = QPushButton('Edit conf. file', self)
        button22.setToolTip('Opens configuration file for hand modifications.')
        button22.move(10, 630)
        button22.clicked.connect(self.on_click22)

        # run optimization button
        button23 = QPushButton('Run optimization', self)
        button23.setToolTip('Writes configuration file and runs optimization.')
        button23.move(10, 660)
        button23.clicked.connect(self.on_click23)

        # generate conf file and run optimization button
        button24 = QPushButton('Generate conf.\nfile and run\noptimization',
                               self)
        button24.setToolTip('Writes configuration file and runs optimization.')
        button24.move(120, 600)
        button24.resize(100, 90)
        button24.clicked.connect(self.on_click24)

        # help buttons
        label41 = QLabel('Help', self)
        label41.move(440, 560)

        button31 = QPushButton('Example', self)
        button31.setToolTip(
            'https://github.com/fandaL/beso/wiki/Example-4:-GUI-in-FreeCAD')
        button31.move(440, 590)
        # button31.resize(80, 50)
        button31.clicked.connect(self.on_click31)

        button32 = QPushButton('Conf. comments', self)
        button32.setToolTip(
            'https://github.com/fandaL/beso/blob/master/beso_conf.py')
        button32.move(440, 620)
        # button32.resize(80, 50)
        button32.clicked.connect(self.on_click32)

        button33 = QPushButton('Close', self)
        button33.move(440, 690)
        # button33.resize(80, 50)
        button33.clicked.connect(self.on_click33)

        # open log file
        button40 = QPushButton('Open log file', self)
        button40.setToolTip('Opens log file in your text editor.\n'
                            '(Does not refresh automatically.)')
        button40.move(10, 690)
        button40.clicked.connect(self.on_click40)

        self.on_click1()  # first update
        self.show()

    # @pyqtSlot()
    def on_click(self):
        ex2 = SelectFile()
        self.show()
        self.textbox_file_name.setText(self.inp_file)

    def on_click1(self):
        # get material objects
        self.materials = []
        self.thicknesses = []
        for obj in App.ActiveDocument.Objects:
            if obj.Name[:23] in ["MechanicalSolidMaterial", "SolidMaterial"]:
                self.materials.append(obj)
            elif obj.Name[:17] == "ElementGeometry2D":
                self.thicknesses.append(obj)
        # update materials combo boxes
        self.combo.clear()
        self.combo.addItem("None")
        self.combo1.clear()
        self.combo1.addItem("None")
        self.combo2.clear()
        self.combo2.addItem("None")
        self.combo0t.clear()
        self.combo0t.addItem("None")
        self.combo1t.clear()
        self.combo1t.addItem("None")
        self.combo2t.clear()
        self.combo2t.addItem("None")
        self.widget.clear()
        self.widget.addItem("All defined")
        self.widget.addItem("Domain 0")
        self.widget.addItem("Domain 1")
        self.widget.addItem("Domain 2")
        self.widget.setCurrentItem(self.widget.item(0))
        self.widget1.clear()
        self.widget1.addItem("All defined")
        self.widget1.addItem("Domain 0")
        self.widget1.addItem("Domain 1")
        self.widget1.addItem("Domain 2")
        self.widget1.setCurrentItem(self.widget1.item(0))
        self.widget2.clear()
        self.widget2.addItem("All defined")
        self.widget2.addItem("Domain 0")
        self.widget2.addItem("Domain 1")
        self.widget2.addItem("Domain 2")
        self.widget2.setCurrentItem(self.widget2.item(0))
        for mat in self.materials:
            self.combo.addItem(mat.Label)
            self.combo1.addItem(mat.Label)
            self.combo2.addItem(mat.Label)
        if self.materials:
            self.combo.setCurrentIndex(1)
        for th in self.thicknesses:
            self.combo0t.addItem(th.Label)
            self.combo1t.addItem(th.Label)
            self.combo2t.addItem(th.Label)

    def on_click21(self):
        """Overwrite beso_conf.py file in the macro directory"""

        file_name = os.path.split(self.textbox_file_name.text())[1]
        path = os.path.split(self.textbox_file_name.text())[0]

        fea = ccxtools.FemToolsCcx()
        fea.setup_ccx()
        path_calculix = fea.ccx_binary

        optimization_base = self.combo51.currentText()

        elset_id = self.combo.currentIndex() - 1
        thickness_id = self.combo0t.currentIndex() - 1
        if elset_id != -1:
            if thickness_id != -1:
                elset = self.materials[elset_id].Name + self.thicknesses[
                    thickness_id].Name
            else:  # 0 means None thickness selected
                elset = self.materials[elset_id].Name + "Solid"
            modulus = float(
                self.materials[elset_id].Material["YoungsModulus"].split()
                [0])  # MPa
            if self.materials[elset_id].Material["YoungsModulus"].split(
            )[1] != "MPa":
                raise Exception(" units not recognised in " +
                                self.materials[elset_id].Name)
            poisson = float(
                self.materials[elset_id].Material["PoissonRatio"].split()[0])
            try:
                density = float(self.materials[elset_id].Material["Density"].
                                split()[0]) * 1e-12  # kg/m3 -> t/mm3
                if self.materials[elset_id].Material["Density"].split(
                )[1] not in ["kg/m^3", "kg/m3"]:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id].Name)
            except KeyError:
                density = 0.
            try:
                conductivity = float(
                    self.materials[elset_id].Material["ThermalConductivity"].
                    split()[0])  # W/m/K
                if self.materials[elset_id].Material[
                        "ThermalConductivity"].split()[1] != "W/m/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id].Name)
            except KeyError:
                conductivity = 0.
            try:
                if self.materials[elset_id].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "um/m/K":
                    expansion = float(self.materials[elset_id].
                                      Material["ThermalExpansionCoefficient"].
                                      split()[0]) * 1e-6  # um/m/K -> mm/mm/K
                elif self.materials[elset_id].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "m/m/K":
                    expansion = float(
                        self.materials[elset_id].
                        Material["ThermalExpansionCoefficient"].split()
                        [0])  # m/m/K -> mm/mm/K
                else:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id].Name)
            except KeyError:
                expansion = 0.
            try:
                specific_heat = float(
                    self.materials[elset_id].Material["SpecificHeat"].split()
                    [0]) * 1e6  #  J/kg/K -> mm^2/s^2/K
                if self.materials[elset_id].Material["SpecificHeat"].split(
                )[1] != "J/kg/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id].Name)
            except KeyError:
                specific_heat = 0.
            if thickness_id != -1:
                thickness = str(
                    self.thicknesses[thickness_id].Thickness).split()[0]  # mm
                if str(self.thicknesses[thickness_id].Thickness).split(
                )[1] != "mm":
                    raise Exception(" units not recognised in " +
                                    self.thicknesses[thickness_id].Name)
            else:
                thickness = 0.
            optimized = self.checkbox.isChecked()
            if self.textbox.text():
                von_mises = float(self.textbox.text())
            else:
                von_mises = 0.

        elset_id1 = self.combo1.currentIndex() - 1
        thickness_id1 = self.combo0t.currentIndex() - 1
        if elset_id1 != -1:
            if thickness_id1 != -1:
                elset1 = self.materials[elset_id1].Name + self.thicknesses[
                    thickness_id1].Name
            else:  # 0 means None thickness selected
                elset1 = self.materials[elset_id1].Name + "Solid"
            modulus1 = float(
                self.materials[elset_id1].Material["YoungsModulus"].split()
                [0])  # MPa
            if self.materials[elset_id1].Material["YoungsModulus"].split(
            )[1] != "MPa":
                raise Exception(" units not recognised in " +
                                self.materials[elset_id1].Name)
            poisson1 = float(
                self.materials[elset_id1].Material["PoissonRatio"].split()[0])
            try:
                density1 = float(self.materials[elset_id1].Material["Density"].
                                 split()[0]) * 1e-12  # kg/m3 -> t/mm3
                if self.materials[elset_id1].Material["Density"].split(
                )[1] not in ["kg/m^3", "kg/m3"]:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id1].Name)
            except KeyError:
                density1 = 0.
            try:
                conductivity1 = float(
                    self.materials[elset_id1].Material["ThermalConductivity"].
                    split()[0])  # W/m/K
                if self.materials[elset_id1].Material[
                        "ThermalConductivity"].split()[1] != "W/m/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id1].Name)
            except KeyError:
                conductivity1 = 0.
            try:
                if self.materials[elset_id1].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "um/m/K":
                    expansion1 = float(self.materials[elset_id1].
                                       Material["ThermalExpansionCoefficient"].
                                       split()[0]) * 1e-6  # um/m/K -> mm/mm/K
                elif self.materials[elset_id1].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "m/m/K":
                    expansion1 = float(
                        self.materials[elset_id1].
                        Material["ThermalExpansionCoefficient"].split()
                        [0])  # m/m/K -> mm/mm/K
                else:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id1].Name)
            except KeyError:
                expansion1 = 0.
            try:
                specific_heat1 = float(
                    self.materials[elset_id1].Material["SpecificHeat"].split()
                    [0]) * 1e6  #  J/kg/K -> mm^2/s^2/K
                if self.materials[elset_id1].Material["SpecificHeat"].split(
                )[1] != "J/kg/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id1].Name)
            except KeyError:
                specific_heat1 = 0.
            if thickness_id1 != -1:
                thickness1 = str(
                    self.thicknesses[thickness_id1].Thickness).split()[0]  # mm
                if str(self.thicknesses[thickness_id1].Thickness).split(
                )[1] != "mm":
                    raise Exception(" units not recognised in " +
                                    self.thicknesses[thickness_id1].Name)
            else:
                thickness1 = 0.
            optimized1 = self.checkbox1.isChecked()
            if self.textbox1.text():
                von_mises1 = float(self.textbox1.text())
            else:
                von_mises1 = 0.

        elset_id2 = self.combo2.currentIndex() - 1
        thickness_id2 = self.combo0t.currentIndex() - 1
        if elset_id2 != -1:
            if thickness_id2 != -1:
                elset2 = self.materials[elset_id2].Name + self.thicknesses[
                    thickness_id2].Name
            else:  # 0 means None thickness selected
                else2t = self.materials[elset_id2].Name + "Solid"
            modulus2 = float(
                self.materials[elset_id2].Material["YoungsModulus"].split()
                [0])  # MPa
            if self.materials[elset_id2].Material["YoungsModulus"].split(
            )[1] != "MPa":
                raise Exception(" units not recognised in " +
                                self.materials[elset_id2].Name)
            poisson2 = float(
                self.materials[elset_id2].Material["PoissonRatio"].split()[0])
            try:
                density2 = float(self.materials[elset_id2].Material["Density"].
                                 split()[0]) * 1e-12  # kg/m3 -> t/mm3
                if self.materials[elset_id2].Material["Density"].split(
                )[1] not in ["kg/m^3", "kg/m3"]:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id2].Name)
            except KeyError:
                density2 = 0.
            try:
                conductivity2 = float(
                    self.materials[elset_id2].Material["ThermalConductivity"].
                    split()[0])  # W/m/K
                if self.materials[elset_id2].Material[
                        "ThermalConductivity"].split()[1] != "W/m/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id2].Name)
            except KeyError:
                conductivity2 = 0.
            try:
                if self.materials[elset_id2].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "um/m/K":
                    expansion2 = float(self.materials[elset_id2].
                                       Material["ThermalExpansionCoefficient"].
                                       split()[0]) * 1e-6  # um/m/K -> mm/mm/K
                elif self.materials[elset_id2].Material[
                        "ThermalExpansionCoefficient"].split()[1] == "m/m/K":
                    expansion2 = float(
                        self.materials[elset_id2].
                        Material["ThermalExpansionCoefficient"].split()
                        [0])  # m/m/K -> mm/mm/K
                else:
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id2].Name)
            except KeyError:
                expansion2 = 0.
            try:
                specific_heat2 = float(
                    self.materials[elset_id2].Material["SpecificHeat"].split()
                    [0]) * 1e6  #  J/kg/K -> mm^2/s^2/K
                if self.materials[elset_id2].Material["SpecificHeat"].split(
                )[1] != "J/kg/K":
                    raise Exception(" units not recognised in " +
                                    self.materials[elset_id2].Name)
            except KeyError:
                specific_heat2 = 0.
            if thickness_id2 != -1:
                thickness2 = str(
                    self.thicknesses[thickness_id2].Thickness).split()[0]  # mm
                if str(self.thicknesses[thickness_id2].Thickness).split(
                )[1] != "mm":
                    raise Exception(" units not recognised in " +
                                    self.thicknesses[thickness_id2].Name)
            else:
                thickness2 = 0.
            optimized2 = self.checkbox2.isChecked()
            if self.textbox2.text():
                von_mises2 = float(self.textbox2.text())
            else:
                von_mises2 = 0.

        with open(os.path.join(self.beso_dir, "beso_conf.py"), "w") as f:
            f.write(
                "# This is the configuration file with input parameters. It will be executed as python commands\n"
            )
            f.write("# Written by beso_fc_gui.py at {}\n".format(
                datetime.datetime.now()))
            f.write("\n")
            f.write("path_calculix = '{}'\n".format(path_calculix))
            f.write("path = '{}'\n".format(path))
            f.write("file_name = '{}'\n".format(file_name))
            f.write("\n")

            if elset_id != -1:
                f.write("elset_name = '{}'\n".format(elset))
                f.write(
                    "domain_optimized[elset_name] = {}\n".format(optimized))
                f.write("domain_density[elset_name] = [{}, {}]\n".format(
                    density * 1e-6, density))
                if thickness:
                    f.write("domain_thickness[elset_name] = [{}, {}]\n".format(
                        thickness, thickness))
                if von_mises:
                    f.write(
                        "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n"
                        .format(von_mises * 1e6))
                    f.write(
                        "                         [('stress_von_Mises', {:.6})]]\n"
                        .format(von_mises))
                f.write(
                    "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n"
                    "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n"
                    .format(modulus * 1e-6, poisson, density * 1e-6,
                            conductivity * 1e-6, expansion * 1e-6,
                            specific_heat * 1e-6))
                f.write(
                    "                               '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n"
                    "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n"
                    .format(modulus, poisson, density, conductivity, expansion,
                            specific_heat))
                f.write("\n")
            if elset_id1 != -1:
                f.write("elset_name = '{}'\n".format(elset1))
                f.write(
                    "domain_optimized[elset_name] = {}\n".format(optimized1))
                f.write("domain_density[elset_name] = [{}, {}]\n".format(
                    density1 * 1e-6, density1))
                if thickness1:
                    f.write("domain_thickness[elset_name] = [{}, {}]\n".format(
                        thickness1, thickness1))
                if von_mises1:
                    f.write(
                        "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n"
                        .format(von_mises1 * 1e6))
                    f.write(
                        "                         [('stress_von_Mises', {:.6})]]\n"
                        .format(von_mises1))
                f.write(
                    "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY"
                    "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n"
                    .format(modulus1 * 1e-6, poisson1, density1 * 1e-6,
                            conductivity1 * 1e-6, expansion1 * 1e-6,
                            specific_heat1 * 1e-6))
                f.write(
                    "                               '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n"
                    "{:.6}\\n"
                    "*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n".
                    format(modulus1, poisson1, density1, conductivity1,
                           expansion1, specific_heat1))
                f.write("\n")
            if elset_id2 != -1:
                f.write("elset_name = '{}'\n".format(elset2))
                f.write(
                    "domain_optimized[elset_name] = {}\n".format(optimized2))
                f.write("domain_density[elset_name] = [{}, {}]\n".format(
                    density2 * 1e-6, density2))
                if thickness2:
                    f.write("domain_thickness[elset_name] = [{}, {}]\n".format(
                        thickness2, thickness2))
                if von_mises2:
                    f.write(
                        "domain_FI[elset_name] = [[('stress_von_Mises', {:.6})],\n"
                        .format(von_mises2 * 1e6))
                    f.write(
                        "                         [('stress_von_Mises', {:.6})]]\n"
                        .format(von_mises2))
                f.write(
                    "domain_material[elset_name] = ['*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY"
                    "\\n{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n',\n"
                    .format(modulus2 * 1e-6, poisson2, density2 * 1e-6,
                            conductivity2 * 1e-6, expansion2 * 1e-6,
                            specific_heat2 * 1e-6))
                f.write(
                    "                               '*ELASTIC\\n{:.6}, {:.6}\\n*DENSITY\\n{:.6}\\n*CONDUCTIVITY\\n"
                    "{:.6}\\n*EXPANSION\\n{:.6}\\n*SPECIFIC HEAT\\n{:.6}\\n']\n"
                    .format(modulus2, poisson2, density2, conductivity2,
                            expansion2, specific_heat2))
                f.write("\n")
            f.write("mass_goal_ratio = " + self.textbox52.text())
            f.write("\n")

            f.write("filter_list = [")
            filter = self.combo6.currentText()
            range = self.textbox6.text()
            direction = self.textbox9.text()
            selection = [item.text() for item in self.widget.selectedItems()]
            filter_domains = []
            if "All defined" not in selection:
                if "Domain 0" in selection:
                    filter_domains.append(elset)
                if "Domain 1" in selection:
                    filter_domains.append(elset1)
                if "Domain 2" in selection:
                    filter_domains.append(elset2)
            if filter == "simple":
                f.write("['simple', {}".format(range))
                for dn in filter_domains:
                    f.write(", '{}'".format(dn))
                f.write("],\n")
            elif filter == "casting":
                f.write("['casting', {}, ({})".format(range, direction))
                for dn in filter_domains:
                    f.write(", '{}'".format(dn))
                f.write("],\n")

            filter1 = self.combo7.currentText()
            range1 = self.textbox7.text()
            direction1 = self.textbox10.text()
            selection = [item.text() for item in self.widget1.selectedItems()]
            filter_domains1 = []
            if "All defined" not in selection:
                if "Domain 0" in selection:
                    filter_domains1.append(elset)
                if "Domain 1" in selection:
                    filter_domains1.append(elset1)
                if "Domain 2" in selection:
                    filter_domains1.append(elset2)
            if filter1 == "simple":
                f.write("               ['simple', {}".format(range1))
                for dn in filter_domains1:
                    f.write(", '{}'".format(dn))
                f.write("],\n")
            elif filter1 == "casting":
                f.write("               ['casting', {}, ({})".format(
                    range1, direction1))
                for dn in filter_domains1:
                    f.write(", '{}'".format(dn))
                f.write("],\n")

            filter2 = self.combo8.currentText()
            range2 = self.textbox8.text()
            direction2 = self.textbox11.text()
            selection = [item.text() for item in self.widget2.selectedItems()]
            filter_domains2 = []
            if "All defined" not in selection:
                if "Domain 0" in selection:
                    filter_domains2.append(elset)
                if "Domain 1" in selection:
                    filter_domains2.append(elset1)
                if "Domain 2" in selection:
                    filter_domains2.append(elset2)
            if filter2 == "simple":
                f.write("               ['simple', {}".format(range2))
                for dn in filter_domains2:
                    f.write(", '{}'".format(dn))
                f.write("],\n")
            elif filter2 == "casting":
                f.write("               ['casting', {}, ({})".format(
                    range2, direction2))
                for dn in filter_domains2:
                    f.write(", '{}'".format(dn))
                f.write("],\n")
            f.write("               ]\n")
            f.write("\n")

            f.write("optimization_base = '{}'\n".format(optimization_base))
            f.write("\n")

            slider_position = self.slider.value()
            if slider_position == 1:
                f.write("mass_addition_ratio = 0.01\n")
                f.write("mass_removal_ratio = 0.02\n")
            if slider_position == 2:
                f.write("mass_addition_ratio = 0.015\n")
                f.write("mass_removal_ratio = 0.03\n")
            if slider_position == 3:
                f.write("mass_addition_ratio = 0.03\n")
                f.write("mass_removal_ratio = 0.06\n")
            f.write("ratio_type = 'relative'\n")
            f.write("\n")

    def on_click22(self):
        """Open beso_conf.py in FreeCAD editor"""
        FreeCADGui.insert(os.path.join(self.beso_dir, "beso_conf.py"))

    def on_click23(self):
        """"Run optimization"""
        # run in own thread (not freezing FreeCAD):      needs also to comment "plt.show()" on the end of beso_main.py
        # self.optimization_thread = RunOptimization("beso_main")
        # self.optimization_thread.start()

        # run in foreground (freeze FreeCAD)
        exec(open(os.path.join(beso_gui.beso_dir, "beso_main.py")).read())

    def on_click24(self):
        self.on_click21()  # generate beso_conf.py
        self.on_click23()  # run optimization

    def on_click31(self):
        webbrowser.open_new_tab(
            "https://github.com/fandaL/beso/wiki/Example-4:-GUI-in-FreeCAD")

    def on_click32(self):
        webbrowser.open_new_tab(
            "https://github.com/fandaL/beso/blob/master/beso_conf.py")

    def on_click33(self):
        self.close()

    def on_click40(self):
        """Open log file"""
        if self.textbox_file_name.text() in [
                "None analysis file selected", ""
        ]:
            print("None analysis file selected")
        else:
            log_file = os.path.normpath(self.textbox_file_name.text()[:-4] +
                                        ".log")
            webbrowser.open(log_file)

    def on_change(self):
        if self.combo.currentText() == "None":
            self.combo0t.setEnabled(False)
            self.checkbox.setEnabled(False)
            self.textbox.setEnabled(False)
        else:
            self.combo0t.setEnabled(True)
            self.checkbox.setEnabled(True)
            self.textbox.setEnabled(True)

    def on_change1(self):
        if self.combo1.currentText() == "None":
            self.combo1t.setEnabled(False)
            self.checkbox1.setEnabled(False)
            self.textbox1.setEnabled(False)
        else:
            self.combo1t.setEnabled(True)
            self.checkbox1.setEnabled(True)
            self.textbox1.setEnabled(True)

    def on_change2(self):
        if self.combo2.currentText() == "None":
            self.combo2t.setEnabled(False)
            self.checkbox2.setEnabled(False)
            self.textbox2.setEnabled(False)
        else:
            self.combo2t.setEnabled(True)
            self.checkbox2.setEnabled(True)
            self.textbox2.setEnabled(True)

    def on_change6(self):
        if self.combo6.currentText() == "None":
            self.textbox6.setEnabled(False)
            self.textbox9.setEnabled(False)
            self.widget.setEnabled(False)
        elif self.combo6.currentText() == "casting":
            self.textbox6.setEnabled(True)
            self.textbox9.setEnabled(True)
            self.widget.setEnabled(True)
        else:
            self.textbox6.setEnabled(True)
            self.textbox9.setEnabled(False)
            self.widget.setEnabled(True)

    def on_change7(self):
        if self.combo7.currentText() == "None":
            self.textbox7.setEnabled(False)
            self.textbox10.setEnabled(False)
            self.widget1.setEnabled(False)
        elif self.combo7.currentText() == "casting":
            self.textbox7.setEnabled(True)
            self.textbox10.setEnabled(True)
            self.widget1.setEnabled(True)
        else:
            self.textbox7.setEnabled(True)
            self.textbox10.setEnabled(False)
            self.widget1.setEnabled(True)

    def on_change8(self):
        if self.combo8.currentText() == "None":
            self.textbox8.setEnabled(False)
            self.textbox11.setEnabled(False)
            self.widget2.setEnabled(False)
        elif self.combo8.currentText() == "casting":
            self.textbox8.setEnabled(True)
            self.textbox11.setEnabled(True)
            self.widget2.setEnabled(True)
        else:
            self.textbox8.setEnabled(True)
            self.textbox11.setEnabled(False)
            self.widget2.setEnabled(True)
示例#41
0
文件: layer.py 项目: mkovacs/sphaira
class Layer(object):

    def __init__(self):
        super(Layer, self).__init__()
        self.orientation = Quaternion()
        self.picked = None
        self.show = QCheckBox()
        self.show.setChecked(True)
        self.alpha_slider = QSlider(QtCore.Qt.Orientation.Horizontal)
        self.alpha_slider.setRange(0, 1024)
        self.alpha_slider.setValue(1024)
        self.alpha_number = QDoubleSpinBox()
        self.alpha_number.setDecimals(3)
        self.alpha_number.setSingleStep(0.01)
        self.alpha_number.setRange(0, 1)
        self.alpha_number.setValue(1)
        self.alpha_slider.valueChanged.connect(self._alphaSliderChanged)
        self.alpha_number.valueChanged.connect(self._alphaNumberChanged)
        self.move = QCheckBox()
        self.move.setChecked(True)
        self.quat = QLineEdit()
        font = QFont('monospace')
        font.setStyleHint(QFont.TypeWriter)
        self.quat.setFont(font)
        default_quat = '+0.000, +1.000, +0.000, +0.000'
        margins = self.quat.textMargins()
        self.quat.setFixedWidth(
            # HACK -------------------------------------------v
            QFontMetrics(self.quat.font()).width(default_quat + '  ') +
            margins.left() + margins.right()
        )
        self.quat.setInputMask('#0.000, #0.000, #0.000, #0.000')
        self.quat.setMaxLength(30)
        self.quat.setText(default_quat)
        self.quat.editingFinished.connect(self._orientationChanged)
        self.nbytes = QLabel()
        self.nbytes.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.nbytes.setText('0')
        self.label = QLabel()
        self.label.setText('<empty>')

    def multiplyOrientation(self, quat):
        self.setOrientation(quat * self.orientation)

    def setOrientation(self, quat):
        self.orientation = quat
        self.quat.setText(
            '%+1.3f, %+1.3f, %+1.3f, %+1.3f' % (
                self.orientation.w,
                self.orientation.x,
                self.orientation.y,
                self.orientation.z,
            )
        )

    def _orientationChanged(self):
        text = self.quat.text()

    def alpha(self):
        return self.alpha_number.value() if self.show.isChecked() else 0.0

    def _alphaSliderChanged(self):
        self.alpha_number.setValue(self.alpha_slider.value() / 1024.0)

    def _alphaNumberChanged(self):
        self.alpha_slider.setValue(1024 * self.alpha_number.value())

    def setup_ui(self, table, row):
        widgets = [
            None,
            CenterH(self.show),
            self.alpha_slider,
            self.alpha_number,
            CenterH(self.move),
            self.quat,
            self.nbytes,
            self.label,
        ]
        for (column, widget) in enumerate(widgets):
            if widget is not None:
                table.setCellWidget(row, column, widget)

    def load_file(self, file_name, in_format):
        self.sphere = proj.load_sphere(file_name, projection=in_format)
        in_format = self.sphere.__class__
        print('Loaded input %s from %s.' % (in_format.__name__, file_name))
        self.texture_id = glGenTextures(1)
        self.sphere.to_gl(self.texture_id)
        self.shader = Shader(
            vert=VERTEX_SHADER,
            frag=FRAGMENT_SHADER + self.sphere.get_glsl_sampler(),
        )
        self.label.setText(file_name)
        self.nbytes.setText(read_bsize(self.sphere.array.nbytes))
示例#42
0
class QLogger(logging.Handler):
    '''Code from:
  https://stackoverflow.com/questions/28655198/best-way-to-display-logs-in-pyqt
  '''
    def __init__(self,
                 parent=None,
                 format=settings.log_fmt,
                 level=logging.INFO):
        logging.Handler.__init__(self)
        # Initialize a log handler as the super class
        self.setFormatter(logging.Formatter(format))
        # Set the formatter for the logger
        self.setLevel(level)
        # Set the logging level
        self.frame = QFrame(parent)
        # Initialize a QFrame to place other widgets in

        self.frame2 = QFrame(parent)
        # Initialize frame2 for the label and checkbox
        self.label = QLabel('Logs')
        # Define a label for the frame
        self.check = QCheckBox('Debugging')
        # Checkbox to enable debugging logging
        self.check.clicked.connect(self.__changeLevel)
        # Connect checkbox clicked to the __changeLevel method

        self.log_widget = QTextEdit()
        # Initialize a QPlainTextWidget to write logs to
        self.log_widget.verticalScrollBar().minimum()
        # Set a vertical scroll bar on the log widget
        self.log_widget.horizontalScrollBar().minimum()
        # Set a horizontal scroll bar on the log widget
        self.log_widget.setLineWrapMode(self.log_widget.NoWrap)
        # Set line wrap mode to no wrapping
        self.log_widget.setFont(QFont("Courier", 12))
        # Set the font to a monospaced font
        self.log_widget.setReadOnly(True)
        # Set log widget to read only

        layout = QHBoxLayout()
        # Initialize a horizontal layout scheme for the label and checkbox frame
        layout.addWidget(self.label)
        # Add the label to the layout scheme
        layout.addWidget(self.check)
        # Add the checkbox to the layout scheme
        self.frame2.setLayout(layout)
        # Set the layout for frame to the horizontal layout

        layout = QVBoxLayout()
        # Initialize a layout scheme for the widgets
        layout.addWidget(self.frame2)
        # Add the label/checkbox frame to the layout scheme
        layout.addWidget(self.log_widget)
        # Add the text widget to the layout scheme

        self.frame.setLayout(layout)
        # Set the layout of the fram to the layout scheme defined

    ##############################################################################
    def emit(self, record):
        '''
    Overload the emit method so that it prints to the text widget
    '''
        msg = self.format(record)
        # Format the message for logging
        if record.levelno >= logging.CRITICAL:  # If the log level is critical
            self.log_widget.setTextColor(Qt.red)
            # Set text color to red
        elif record.levelno >= logging.ERROR:  # Elif level is error
            self.log_widget.setTextColor(Qt.darkMagenta)
            # Set text color to darkMagenta
        elif record.levelno >= logging.WARNING:  # Elif level is warning
            self.log_widget.setTextColor(Qt.darkCyan)
            # Set text color to darkCyan
        else:  # Else
            self.log_widget.setTextColor(Qt.black)
            # Set text color to black
        self.log_widget.append(msg)
        # Add the log to the text widget

    ##############################################################################
    def write(self, m):
        '''
    Overload the write method so that it does nothing
    '''
        pass

    ##############################################################################
    def __changeLevel(self, *args):
        '''
    Private method to change logging level
    '''
        if self.check.isChecked():
            self.setLevel(logging.DEBUG)
            # Get the Meso1819 root logger and add the handler to it
        else:
            self.setLevel(logging.INFO)
示例#43
0
class SceneTab(QWidget):  #FIXME I'm Ugly.
    """This widget is for changing the Scene propagation policies
       of the module.
    """
    def __init__(self, parent, agent):
        """Construct the SceneTab with the given parent (TabDialog) and
           ModuleAgent.
        """
        super(SceneTab, self).__init__(parent)

        self.agent = agent

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignCenter)

        self.layout.addWidget(self.buildHighlightGroupBox())
        self.layout.addItem(QSpacerItem(5, 5))
        self.layout.addWidget(self.buildModuleGroupBox())
        self.layout.addItem(QSpacerItem(5, 5))
        self.layout.addWidget(self.buildAttributeGroupBox())

        self.setLayout(self.layout)

    def buildHighlightGroupBox(self):
        """Layout/construct the highlight UI for this tab."""
        groupBox = QGroupBox("Highlight Policy")
        layout = QVBoxLayout()

        # agent.propagate_highlights
        self.highlights_propagate = QCheckBox("Propagate highlights to " +
                                              "other modules.")
        self.highlights_propagate.setChecked(self.agent.propagate_highlights)
        self.highlights_propagate.stateChanged.connect(
            self.highlightsPropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_highlights:
            self.highlights_propagate.setDisabled(True)

        # agent.apply_highlights
        self.applyHighlights = QCheckBox("Apply highlights from " +
                                         "other modules.")
        self.applyHighlights.setChecked(self.agent.apply_highlights)
        self.applyHighlights.stateChanged.connect(self.applyHighlightsChanged)

        layout.addWidget(self.applyHighlights)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.highlights_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def highlightsPropagateChanged(self):
        """Called when highlight propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_highlights = self.highlights_propagate.isChecked()

    def applyHighlightsChanged(self):
        """Called when highlight application is changed to update the
           Agent.
        """
        self.agent.apply_highlights = self.applyHighlights.isChecked()

    def buildModuleGroupBox(self):
        """Layout/construct the ModuleScene UI for this tab."""
        groupBox = QGroupBox("Module Policy")
        layout = QVBoxLayout()

        # agent.propagate_module_scenes
        self.module_propagate = QCheckBox(
            "Propagate module scene information " + "to other modules.")
        self.module_propagate.setChecked(self.agent.propagate_module_scenes)
        self.module_propagate.stateChanged.connect(self.modulePropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_module_scenes:
            self.module_propagate.setDisabled(True)

        # agent.apply_module_scenes
        self.module_applyScene = QCheckBox("Apply module scene information " +
                                           "from other modules.")
        self.module_applyScene.setChecked(self.agent.apply_module_scenes)
        self.module_applyScene.stateChanged.connect(self.moduleApplyChanged)

        layout.addWidget(self.module_applyScene)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.module_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def modulePropagateChanged(self):
        """Called when ModuleScene propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_module_scenes = self.module_propagate.isChecked()

    def moduleApplyChanged(self):
        """Called when ModuleScene application is changed to update the
           Agent.
        """
        self.agent.apply_module_scenes = self.module_applyScene.isChecked()

    def buildAttributeGroupBox(self):
        """Layout/construct the AttributeScene UI for this tab."""
        groupBox = QGroupBox("Attribute Policy (Colors)")
        layout = QVBoxLayout()

        # agent.propagate_attribute_scenes
        self.attr_propagate = QCheckBox(
            "Propagate attribute scene " +
            "information (e.g. color maps) to other modules.")
        self.attr_propagate.setChecked(self.agent.propagate_attribute_scenes)
        self.attr_propagate.stateChanged.connect(self.attrPropagateChanged)
        # We only allow this change if the parent does not propagate
        if self.agent.parent().propagate_attribute_scenes:
            self.attr_propagate.setDisabled(True)

        # agent.apply_attribute_scenes
        self.attr_applyScene = QCheckBox("Apply attribute scene information " +
                                         "from other modules.")
        self.attr_applyScene.setChecked(self.agent.apply_attribute_scenes)
        self.attr_applyScene.stateChanged.connect(self.attrApplyChanged)

        layout.addWidget(self.attr_applyScene)
        layout.addItem(QSpacerItem(5, 5))
        layout.addWidget(self.attr_propagate)
        groupBox.setLayout(layout)
        return groupBox

    def attrPropagateChanged(self):
        """Called when AttributeScene propagtion is changed to update the
           Agent.
        """
        self.agent.propagate_attribute_scenes = self.attr_propagate.isChecked()

    def attrApplyChanged(self):
        """Called when AttributeScene application is changed to update the
           Agent.
        """
        self.agent.apply_attribute_scenes = self.attr_applyScene.isChecked()
示例#44
0
class SettingsWindow(QDialog):
    def __init__(self, parent):
        super(self.__class__, self).__init__(parent)
        self.parent = parent
        self.lib = libserial.InitApp(self)
        if self.parent.receive is not None:
            self.boolean_config_is_ok = True
        else:
            self.boolean_config_is_ok = False

        self.config_parser = ConfigParser.ConfigParser()
        self.config_parser.read("config/profiles/profiles.ini")

        self.settings_parser = ConfigParser.ConfigParser()
        self.settings_parser.read('config/settings.ini')

        self.setWindowTitle(SERIAL_CHAT_SETTINGS_TITLE)

        self.button_box_dialog = QDialogButtonBox(QDialogButtonBox.Cancel
                                                  | QDialogButtonBox.Ok)
        self.button_box_dialog.button(QDialogButtonBox.Ok).setText(CONNECT)
        self.button_box_dialog.button(QDialogButtonBox.Cancel).setText(CANCEL)
        self.button_box_dialog.accepted.connect(self.accept)
        self.accepted.connect(self.apply_setting_changes)
        self.button_box_dialog.rejected.connect(self.reject)
        self.serial_dropdown = QComboBox()

        self.lib.init__serial()
        self.serial_values = self.lib.get_serials()
        for serials in self.serial_values:
            self.serial_dropdown.addItem(serials)

        if self.parent.serial_port is not None:
            self.serial_dropdown.setCurrentIndex(
                self.serial_dropdown.findText(self.parent.serial_port.name))

        self.profiles_combobox = QComboBox()
        self.profiles_combobox.addItem("None")
        if self.parent.choosen_profile == "Custom":
            self.profiles_combobox.addItem("Custom")
        for profile in self.config_parser.sections():
            self.profiles_combobox.addItem(profile)
        if self.parent.custom_settings:
            self.profiles_combobox.setCurrentIndex(
                self.profiles_combobox.findText('Custom'))
        elif self.parent.choosen_profile != 'None':
            self.profiles_combobox.setCurrentIndex(
                self.profiles_combobox.findText(self.parent.choosen_profile))
        else:
            self.profiles_combobox.setCurrentIndex(
                self.profiles_combobox.findText('None'))

        self.profiles_combobox.currentIndexChanged.connect(
            self.change_custom_settings_on_profile)

        self.custom_settings_checkbox = QCheckBox()
        self.custom_settings_checkbox.stateChanged.connect(
            self.custom_settings_enable_disable)

        self.interval_time_lineedit = QLineEdit(str(self.parent.interval_time))
        self.interval_time_lineedit.editingFinished.connect(
            self.check_if_digit)
        self.interval_time_lineedit.setDisabled(True)

        self.serial_speed_combobox = QComboBox()
        for sp in serial_speeds:
            self.serial_speed_combobox.addItem(str(sp))
        if self.boolean_config_is_ok:
            self.serial_speed_combobox.setCurrentIndex(
                self.serial_speed_combobox.findText(
                    str(self.parent.serial_port.baudrate)))
        else:
            self.serial_speed_combobox.setCurrentIndex(
                self.serial_speed_combobox.findText('9600'))
        self.serial_speed_combobox.setDisabled(True)

        self.databits_combobox = QComboBox()
        for db in bytesize_values:
            self.databits_combobox.addItem(str(db))
        if self.boolean_config_is_ok:
            self.databits_combobox.setCurrentIndex(
                self.databits_combobox.findText(
                    str(self.parent.serial_port.bytesize)))
        else:
            self.databits_combobox.setCurrentIndex(
                self.databits_combobox.findText('8'))
        self.databits_combobox.setDisabled(True)

        self.stopbits_combobox = QComboBox()
        for sb in stop_values:
            self.stopbits_combobox.addItem(str(sb))
        if self.boolean_config_is_ok:
            sb = str(self.parent.serial_port.stopbits).replace('.', ',')
            self.stopbits_combobox.setCurrentIndex(
                self.stopbits_combobox.findText(str(sb)))
        else:
            self.stopbits_combobox.setCurrentIndex(
                self.stopbits_combobox.findText('1'))
        self.stopbits_combobox.setDisabled(True)

        self.parity_combobox = QComboBox()
        for par in parity_values:
            self.parity_combobox.addItem(str(par))
        if self.boolean_config_is_ok:
            table = {'O': 'Odd', 'E': 'Even', 'N': 'None'}
            xxx = [
                item for key, item in table.items()
                if self.parent.serial_port.parity == key
            ]
            self.parity_combobox.setCurrentIndex(parity_values.index(xxx[0]))
        else:
            self.parity_combobox.setCurrentIndex(
                self.parity_combobox.findText("None"))
        self.parity_combobox.setDisabled(True)

        self.flowcontrol_combobox = QComboBox()
        for fc in flow_control_values:
            self.flowcontrol_combobox.addItem(str(fc))
        if self.boolean_config_is_ok:
            if self.parent.serial_port.xonxoff:
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("XON/XOFF"))
            elif self.parent.serial_port.rtscts:
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("RTS/CTS"))
            else:
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("None"))
        else:
            self.flowcontrol_combobox.setCurrentIndex(
                self.flowcontrol_combobox.findText("None"))
        self.flowcontrol_combobox.setDisabled(True)

        self.nickname_lineedit = QLineEdit()
        if self.settings_parser.has_option('default', 'nickname'):
            nickname = self.settings_parser.get('default', 'nickname')
            if type(nickname) == str:
                nickname = nickname.decode('utf-8')
            self.nickname_lineedit.setText(
                self.settings_parser.get('default', 'nickname'))
        else:
            if self.parent.nickname is None:
                self.nickname_lineedit.setText("Guest_" + MD5.new(
                    str(datetime.datetime.now())).digest().encode('hex')[:5])
            else:
                self.nickname_lineedit.setText(self.parent.nickname)

        self.save_folder_editline = QLineEdit(self.parent.default_save_folder)
        self.save_folder_editline.editingFinished.connect(
            self.check_if_folder_exists)
        if self.settings_parser.has_option('default', 'default_save_folder'):
            folder = self.settings_parser.get('default', 'default_save_folder')
            if type(folder) == str:
                folder = folder.decode('utf-8')
            self.save_folder_editline.setText(folder)
            self.check_if_folder_exists()

        self.dir_browser_button = QPushButton()
        self.dir_browser_button.setIcon(QIcon(icons_folder + 'folder.png'))
        self.dir_browser_button.clicked.connect(self.choose_save_dir)

        self.horizontal_box_hboxlayout = QHBoxLayout()
        self.horizontal_box_hboxlayout.addWidget(self.save_folder_editline)
        self.horizontal_box_hboxlayout.addWidget(self.dir_browser_button)
        self.horizontal_box_container_widget = QWidget()
        self.horizontal_box_container_widget.setLayout(
            self.horizontal_box_hboxlayout)

        self.enable_ACP127 = QCheckBox()
        self.enable_ACP127.stateChanged.connect(
            self.enable_functionality_ACP127)
        if self.parent.acp127:
            self.enable_ACP127.setChecked(True)

        self.encryption_password_lineedit = QLineEdit()
        self.enable_encryption_checkbox = QCheckBox()
        self.enable_encryption_checkbox.stateChanged.connect(
            self.enable_functionality_encryption)
        if self.parent.isEncryptionEnabled:
            self.enable_encryption_checkbox.setChecked(True)

        self.encryption_password_lineedit.setEchoMode(
            QLineEdit.EchoMode.PasswordEchoOnEdit)
        if self.parent.encryption_key is not None:
            self.encryption_password_lineedit.setText(
                self.parent.encryption_key)
        if self.enable_encryption_checkbox.isChecked():
            self.encryption_password_lineedit.setDisabled(False)
        else:
            self.encryption_password_lineedit.setDisabled(True)

        self.grid_form_layout = QFormLayout()
        self.grid_form_layout.addRow(FORMLAYOUT_SERIAL_TITLE + ":",
                                     self.serial_dropdown)
        self.grid_form_layout.addRow(FORMLAYOUT_PROFILE_TITLE + ":",
                                     self.profiles_combobox)
        self.grid_form_layout.addRow(FORMLAYOUT_CUSTOM_SERIAL_SETTINGS_TITLE,
                                     self.custom_settings_checkbox)
        self.grid_form_layout.addRow(FORMLAYOUT_INTERVAL_TIME_TITLE + ":",
                                     self.interval_time_lineedit)
        self.grid_form_layout.addRow(FORMLAYOUT_SERIAL_SPEED_TITLE + "(baud):",
                                     self.serial_speed_combobox)
        self.grid_form_layout.addRow(FORMLAYOUT_DATA_BITS_TITLE + ":",
                                     self.databits_combobox)
        self.grid_form_layout.addRow(FORMLAYOUT_STOP_BITS_TITLE + ":",
                                     self.stopbits_combobox)
        self.grid_form_layout.addRow(FORMLAYOUT_PARITY_TITLE + ":",
                                     self.parity_combobox)
        self.grid_form_layout.addRow(FORMLAYOUT_FLOWCONTROL_TITLE + ":",
                                     self.flowcontrol_combobox)
        self.grid_form_layout.addRow(
            FORMLAYOUT_ENABLE_ACP127_TITLE + " ACP-127", self.enable_ACP127)
        self.grid_form_layout.addRow(FORMLAYOUT_ENABLE_ENCRYPTION_TITLE,
                                     self.enable_encryption_checkbox)
        self.grid_form_layout.addRow(FORMLAYOUT_ENCRYPTION_KEY_TITLE,
                                     self.encryption_password_lineedit)
        self.grid_form_layout.addRow(FORMLAYOUT_NICKNAME_TITLE + ":",
                                     self.nickname_lineedit)
        self.grid_form_layout.addRow(FORMLAYOUT_SAVE_FOLDER_FILE_TITLE + ":",
                                     self.horizontal_box_container_widget)
        self.grid_form_layout.addRow("", self.button_box_dialog)
        self.setLayout(self.grid_form_layout)
        self.show()

    def enable_functionality_encryption(self):
        if self.enable_encryption_checkbox.isChecked():
            self.encryption_password_lineedit.setDisabled(False)
        else:
            self.encryption_password_lineedit.setDisabled(True)

    def check_if_folder_exists(self):

        if not os.path.isdir(self.save_folder_editline.text()):
            msgBox = QMessageBox(icon=QMessageBox.Warning,
                                 text=ERROR_NO_DIR_MESSAGE)
            msgBox.setWindowTitle(ERROR_NO_DIR_TITLE)
            msgBox.exec_()
            self.save_folder_editline.setText(self.parent.default_save_folder)

    def check_if_digit(self):

        try:
            int(self.interval_time_lineedit.text())
        except:
            msgBox = QMessageBox(icon=QMessageBox.Warning,
                                 text=ERROR_NO_INT_MESSAGE)
            msgBox.setWindowTitle(ERROR_NO_INT_TITLE)
            msgBox.exec_()
            self.interval_time_lineedit.setText(str(self.parent.interval_time))

    def choose_save_dir(self):
        fname = QFileDialog(self, FILEBROWSER_SAVE_FOLDER_TITLE)
        fname.setFileMode(QFileDialog.Directory)
        looking_label = QFileDialog.DialogLabel(QFileDialog.LookIn)
        filename_label = QFileDialog.DialogLabel(QFileDialog.FileName)
        filetype_label = QFileDialog.DialogLabel(QFileDialog.FileType)
        fname.setLabelText(looking_label, FILEBROWSER_SAVE_FOLDER_LOOKIN)
        fname.setLabelText(filename_label, FILEBROWSER_SAVE_FOLDER_FOLDERNAME)
        fname.setLabelText(filetype_label, FILEBROWSER_SAVE_FOLDER_FOLDERTYPE)
        fname.setOption(QFileDialog.ShowDirsOnly)

        if fname.exec_():
            filename = fname.selectedFiles()[0]
            self.save_folder_editline.setText(filename)

    def enable_functionality_ACP127(self):
        if self.enable_ACP127.isChecked():
            self.parent.acp127 = True
        else:
            self.parent.acp127 = False

    def apply_setting_changes(self):

        res = None
        self.parent.custom_settings_enable_disable = self.custom_settings_checkbox.isChecked(
        )
        self.parent.choosen_profile = self.profiles_combobox.currentText()
        if self.parent.custom_settings_enable_disable:
            self.parent.choosen_profile = "Custom"

        if self.enable_encryption_checkbox.isChecked():
            self.parent.isEncryptionEnabled = True
            self.parent.encryption_key = self.encryption_password_lineedit.text(
            )
        else:
            self.parent.isEncryptionEnabled = False
            self.parent.encryption_key = None

        if self.nickname_lineedit.text() != "":
            nick = self.nickname_lineedit.text().rstrip()
            nick = nick.replace(" ", "_")
            self.parent.nickname = nick
        if self.save_folder_editline.text() != "":
            if os.path.isdir(self.save_folder_editline.text()):
                self.parent.default_save_folder = self.save_folder_editline.text(
                )
        self.parent.interval_time = int(self.interval_time_lineedit.text())
        if self.flowcontrol_combobox.currentText() == "XON/XOFF":
            x_control = True
        else:
            x_control = False

        if self.flowcontrol_combobox.currentText() == "RTS/CTS":
            r_control = True
        else:
            r_control = False
        if self.parent.receive is None:
            res = self.lib.set_serial(
                port=self.serial_dropdown.currentText(),
                baudrate=self.serial_speed_combobox.currentText(),
                bytesize=self.databits_combobox.currentText(),
                stopbits=self.stopbits_combobox.currentText(),
                parity=self.parity_combobox.currentText(),
                xonxoff=x_control,
                rtscts=r_control)
        else:
            self.parent.receive.loop_run = False
            self.parent.receive.wait()
            self.parent.receive = None
            res = self.lib.set_serial(
                port=self.serial_dropdown.currentText(),
                baudrate=self.serial_speed_combobox.currentText(),
                bytesize=self.databits_combobox.currentText(),
                stopbits=self.stopbits_combobox.currentText(),
                parity=self.parity_combobox.currentText(),
                xonxoff=x_control,
                rtscts=r_control)
        if type(res) == OSError:
            self.parent.status_bar_widget.showMessage(str(res), 5000)
            msgBox = QMessageBox(icon=QMessageBox.Critical, text=str(res))
            msgBox.setWindowTitle(ERROR_INTERFACE_TITLE)
            msgBox.exec_()
        if type(res) is not None and type(res) != OSError:
            self.parent.serial_port = res
            self.parent.start_threads()
            self.parent.status_bar_widget.showMessage(
                MSG_SERIAL_INT_STARTED % self.parent.serial_port.port)

    def change_custom_settings_on_profile(self):
        if self.profiles_combobox.currentText() != 'None':

            section = self.profiles_combobox.currentText()
            self.interval_time_lineedit.setText(
                self.config_parser.get(section, "interval"))
            self.serial_speed_combobox.setCurrentIndex(
                self.serial_speed_combobox.findText(
                    self.config_parser.get(section, "serialspeed")))
            self.databits_combobox.setCurrentIndex(
                self.databits_combobox.findText(
                    self.config_parser.get(section, "bytesize")))
            self.stopbits_combobox.setCurrentIndex(
                self.stopbits_combobox.findText(
                    self.config_parser.get(section, "stopbits")))
            self.parity_combobox.setCurrentIndex(
                self.parity_combobox.findText(
                    self.config_parser.get(section, "parity")))
            if self.config_parser.get(section, "xonxoff") == 'True':
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("XON/XOFF"))
            elif self.config_parser.get(section, "rtscts") == 'True':
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("RTS/CTS"))
            else:
                self.flowcontrol_combobox.setCurrentIndex(
                    self.flowcontrol_combobox.findText("None"))
            if self.config_parser.get(section, "acp127") == "True":
                self.enable_ACP127.setChecked(True)
            else:
                self.enable_ACP127.setChecked(False)
        elif self.profiles_combobox.currentText() == "None":
            self.serial_speed_combobox.setCurrentIndex(
                self.serial_speed_combobox.findText('9600'))
            self.interval_time_lineedit.setText(str(self.parent.intervaltime))
            self.databits_combobox.setCurrentIndex(
                self.databits_combobox.findText('8'))
            self.stopbits_combobox.setCurrentIndex(
                self.stopbits_combobox.findText('1'))
            self.parity_combobox.setCurrentIndex(
                self.parity_combobox.findText('None'))
            self.flowcontrol_combobox.setCurrentIndex(
                self.flowcontrol_combobox.findText('None'))
            self.enable_ACP127.setChecked(False)

    def custom_settings_enable_disable(self):
        if self.custom_settings_checkbox.isChecked():
            self.interval_time_lineedit.setDisabled(False)
            self.serial_speed_combobox.setDisabled(False)
            self.databits_combobox.setDisabled(False)
            self.stopbits_combobox.setDisabled(False)
            self.parity_combobox.setDisabled(False)
            self.flowcontrol_combobox.setDisabled(False)
        else:
            self.interval_time_lineedit.setDisabled(True)
            self.serial_speed_combobox.setDisabled(True)
            self.databits_combobox.setDisabled(True)
            self.stopbits_combobox.setDisabled(True)
            self.parity_combobox.setDisabled(True)
            self.flowcontrol_combobox.setDisabled(True)
示例#45
0
class PushupForm(QDialog):
    '''
    classdocs
    '''
    pushupCreated = Signal(Pushup_Model)

    def __init__(self, athlete):
        '''
        Constructor
        '''
        QDialog.__init__(self)

        self.setWindowTitle("Pushup form")
        self.athlete = athlete
        self.pushupForm = QFormLayout()
        self.createGUI()

    def createGUI(self):
        self.series = QSpinBox()
        self.series.setMinimum(1)

        self.repetitions = QSpinBox()
        self.repetitions.setMaximum(512)

        self.avgHeartRateToggle = QCheckBox()
        self.avgHeartRateToggle.toggled.connect(self._toggleHeartRateSpinBox)

        self.avgHeartRate = QSpinBox()
        self.avgHeartRate.setMinimum(30)
        self.avgHeartRate.setMaximum(250)
        self.avgHeartRate.setValue(120)
        self.avgHeartRate.setDisabled(True)

        self.dateSelector_widget = QCalendarWidget()
        self.dateSelector_widget.setMaximumDate(QDate.currentDate())

        self.addButton = QPushButton("Add pushup")
        self.addButton.setMaximumWidth(90)
        self.addButton.clicked.connect(self._createPushup)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.setMaximumWidth(90)
        self.cancelButton.clicked.connect(self.reject)

        self.pushupForm.addRow("Series", self.series)
        self.pushupForm.addRow("Repetitions", self.repetitions)
        self.pushupForm.addRow("Store average heart rate ? ",
                               self.avgHeartRateToggle)
        self.pushupForm.addRow("Average Heart Rate", self.avgHeartRate)
        self.pushupForm.addRow("Exercise Date", self.dateSelector_widget)

        btnsLayout = QVBoxLayout()
        btnsLayout.addWidget(self.addButton)
        btnsLayout.addWidget(self.cancelButton)
        btnsLayout.setAlignment(Qt.AlignRight)

        layoutWrapper = QVBoxLayout()
        layoutWrapper.addLayout(self.pushupForm)
        layoutWrapper.addLayout(btnsLayout)

        self.setLayout(layoutWrapper)

    def _createPushup(self):
        exerciseDate = self.dateSelector_widget.selectedDate()
        exerciseDate = self.qDate_to_date(exerciseDate)

        if self.avgHeartRateToggle.isChecked():
            heartRate = self.avgHeartRate.value()
        else:
            heartRate = None

        pushup = Pushup_Model(self.athlete._name, exerciseDate, heartRate,
                              self.series.value(), self.repetitions.value())

        self.pushupCreated.emit(pushup)
        self.accept()

    def _toggleHeartRateSpinBox(self):
        if self.avgHeartRateToggle.isChecked():
            self.avgHeartRate.setDisabled(False)
        else:
            self.avgHeartRate.setDisabled(True)

    def qDate_to_date(self, qDate):
        return date(qDate.year(), qDate.month(), qDate.day())
示例#46
0
class MainWindow(object):
    '''
    Contains the implementation for building and displaying the 
    application's main window.
    '''

    def __init__(self, model, alg):
        '''
        Constructs the GUI and initializes internal parameters.
        '''
        self._window = QMainWindow()
        self._window.setWindowTitle("Reverse A*")
        self._worldWidget = WorldWidget(model, alg)
        self._model = model
        self._alg = alg
        self._spdSetting = 0
        self._timer = QTimer()
        #Every time the timer times out, invoke the _onStep method.
        self._timer.timeout.connect(self._onStep)        
        self._buildGUI()
        self._window.show()

    def _buildGUI(self):
        '''
        Construct the GUI widgets and layouts.
        '''
        centerWidget = QWidget()
        self._window.setCentralWidget(centerWidget)
        
        worldLayout = QHBoxLayout()
        worldLayout.addWidget(self._worldWidget)
        grpBx = QGroupBox("2D World")
        grpBx.setLayout(worldLayout)
        grpBx.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        
        ctrlPan = self._buildControlPanel()
        layout = QHBoxLayout()
        layout.addWidget(ctrlPan)
        layout.addWidget(grpBx)
        layout.setAlignment(ctrlPan, Qt.AlignLeft | Qt.AlignTop)
        centerWidget.setLayout(layout)

        
    def _buildControlPanel(self):
        '''
        Create all buttons, labels, etc for the application control elements
        '''
        layout = QVBoxLayout()
        layout.addWidget(self._buildSetupPanel())
        layout.addWidget(self._buildSpeedPanel())
        layout.addWidget(self._buildResultsPanel())
        layout.addWidget(self._buildRenderingOptions())
        layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        
        ctrlWidget = QWidget(self._window)
        ctrlWidget.setLayout(layout)
        ctrlWidget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        return ctrlWidget        
    
    def _buildSetupPanel(self):
        '''
        Creates the sub-panel containing control widgets for re-initializing 
        the world on demand.
        '''
        self._percentLbl = QLabel("%")
        self._setupBtn = QPushButton("Setup", self._window)
        self._setupBtn.clicked.connect(self._onSetup)
        
        self._percentObstacleSldr = QSlider(Qt.Horizontal, self._window)
        self._percentObstacleSldr.setTickPosition(QSlider.TickPosition.TicksBelow)
        self._percentObstacleSldr.setTickInterval(10)
        self._percentObstacleSldr.setMinimum(0)
        self._percentObstacleSldr.setMaximum(100)
        self._percentObstacleSldr.valueChanged.connect(self._onPercentSlideChange)
        self._percentObstacleSldr.setValue(33)
        
        layout = QGridLayout()
        layout.addWidget(self._setupBtn, 0, 0, 1, 2)
        layout.addWidget(QLabel("Percent Occupied:"), 1, 0)
        layout.addWidget(self._percentLbl, 1, 1)
        layout.addWidget(self._percentObstacleSldr, 2, 0, 1, 2)
        
        grpBx = QGroupBox("Setup Controls")
        grpBx.setLayout(layout)
        grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        return grpBx        
        
    def _buildSpeedPanel(self):
        '''
        Creates the sub-panel containing control widgets for controlling the 
        speed of execution of the algorithm.
        '''
        self._runBtn = QPushButton("Run", self._window)
        self._stepBtn = QPushButton("Step Once", self._window)        
        self._runBtn.clicked.connect(self._onRun)
        self._stepBtn.clicked.connect(self._onStep)        
        
        slowRadio = QRadioButton('Slow', self._window)
        medRadio = QRadioButton('Medium', self._window)
        fastRadio = QRadioButton('Fast', self._window)
        notVisRadio = QRadioButton('Not visible', self._window)
        slowRadio.setChecked(True)        
        
        self._speedGroup = QButtonGroup(self._window)
        self._speedGroup.addButton(slowRadio, 0)
        self._speedGroup.addButton(medRadio, 1)
        self._speedGroup.addButton(fastRadio, 2)
        self._speedGroup.addButton(notVisRadio, 3)
        self._speedGroup.buttonClicked.connect(self._onSpeedChange)
          
        layout = QVBoxLayout()
        layout.addWidget(self._runBtn)
        layout.addWidget(self._stepBtn)
        layout.addWidget(slowRadio)
        layout.addWidget(medRadio)
        layout.addWidget(fastRadio)
        layout.addWidget(notVisRadio)
        
        grpBx = QGroupBox("Run Controls")
        grpBx.setLayout(layout)
        grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        return grpBx
    
    def _buildResultsPanel(self):
        '''
        Creates the sub-panel containing displays widgets for informing the 
        user on the results of running the algorithm.
        '''        
        self._doneLbl = QLabel("No", self._window)
        self._solvableLbl = QLabel("Yes", self._window)
        
        #_doneLbl is highlighted green upon successful algorithm completion
        pal = self._doneLbl.palette()
        pal.setColor(QPalette.Window, Qt.green)
        self._doneLbl.setPalette(pal)

        #_solvableLbl is highlighted red if the world model isn't solvable
        pal = self._solvableLbl.palette()
        pal.setColor(QPalette.Window, Qt.red)
        self._solvableLbl.setPalette(pal)          
        
        layout = QGridLayout()
        layout.addWidget(QLabel("Path Found:"), 0, 0)
        layout.addWidget(self._doneLbl, 0, 1)
        layout.addWidget(QLabel("Is Solvable:"), 1, 0)
        layout.addWidget(self._solvableLbl, 1, 1)
        
        grpBx = QGroupBox("Results")
        grpBx.setLayout(layout)
        grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        return grpBx
    
    def _buildRenderingOptions(self):
        '''
        Creates the sub-panel containing control widgets for setting options
        in how the world is rendered on the GUI.
        '''        
        self._openChk = QCheckBox("Active Cells")
        self._visitedChk = QCheckBox("Visited Cells")
        self._pathChk = QCheckBox("Draw Path")
        self._costChk = QCheckBox("Draw Estimated Costs")
        
        pal = self._openChk.palette()
        pal.setColor(QPalette.WindowText, Qt.green)
        self._openChk.setPalette(pal)
        
        pal = self._visitedChk.palette()
        pal.setColor(QPalette.WindowText, Qt.cyan)
        self._visitedChk.setPalette(pal)
        
        pal = self._pathChk.palette()
        pal.setColor(QPalette.WindowText, Qt.red)
        self._pathChk.setPalette(pal)
        
        self._visitedChk.setChecked(True)
        self._pathChk.setChecked(True)
        self._costChk.setChecked(True)
        
        self._openChk.stateChanged.connect(self._renderingOptionChanged)
        self._visitedChk.stateChanged.connect(self._renderingOptionChanged)
        self._pathChk.stateChanged.connect(self._renderingOptionChanged)
        self._costChk.stateChanged.connect(self._renderingOptionChanged)
        
        layout = QVBoxLayout()
        layout.addWidget(self._openChk)
        layout.addWidget(self._visitedChk)
        layout.addWidget(self._pathChk)
        layout.addWidget(self._costChk)
        
        grpBx = QGroupBox("Rendering Options")
        grpBx.setLayout(layout)
        grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        return grpBx        
    
    @Slot()
    def _renderingOptionChanged(self, value):
        '''
        When any rendering option is changed this method is invoked.  It polls
        the GUI for the selected setting values and passes them to the 2D
        world widget.
        '''
        self._worldWidget.setDrawActiveCells(self._openChk.isChecked())
        self._worldWidget.setDrawVisitedCells(self._visitedChk.isChecked())
        self._worldWidget.setDrawPath(self._pathChk.isChecked())
        self._worldWidget.setDrawCosts(self._costChk.isChecked())
        self._worldWidget.repaint()
    
    @Slot()
    def _onPercentSlideChange(self, value):
        '''
        Invoked every time the percent slider is changed.  Displays the percent
        value on the GUI.
        '''
        
        #Add extra padding to the front of the string to help prevent
        #gui layout resizing
        if value < 10:
            self._percentLbl.setText("  " + str(value) + "%")
        elif value < 100:
            self._percentLbl.setText(" " + str(value) + "%")
        else:
            self._percentLbl.setText(str(value) + "%")
    
    @Slot()
    def _onSpeedChange(self, value):
        '''
        Invoked every time one of the speed setting radio buttons are selected.
        Resets the algorithm iterating callback timer if it's currently running.
        '''
        self._spdSetting = self._speedGroup.checkedId()
        if self._timer.isActive():
            self._resetTimer()            
         
    @Slot()
    def _onSetup(self):
        '''
        Invoked when the setup button is pushed.  Re-initializes the world model
        and the algorithm.
        '''
        self._timer.stop()
        self._runBtn.setText('Run')
        self._model.reset(self._percentObstacleSldr.value() / 100.0)
        self._alg.reset()
        self._doneLbl.setText("No")
        self._solvableLbl.setText("Yes")
        self._doneLbl.setAutoFillBackground(False)
        self._solvableLbl.setAutoFillBackground(False)
        self._worldWidget.repaint()
    
    @Slot()
    def _onRun(self):
        '''
        Invoked when the run button is pushed.  Toggles the algorithm iterating
        timer on and off.
        '''
        if self._timer.isActive():
            self._timer.stop()
            self._runBtn.setText("Run")
        else:
            self._resetTimer()
            self._runBtn.setText("Stop")
    
    @Slot()
    def _onStep(self):
        '''
        Invoked on every 'step once' call and on every timer timeout.  Iterates
        one step of the algorithm and then checks for termination conditions
        such as the algorithm being done or solvable.
        '''
        self._alg.step()
        self._worldWidget.repaint()
        
        if self._alg.isDone() or not self._alg.isSolvable():
            self._timer.stop()
            self._runBtn.setText('Run')
        
        self._checkTerminalConditions()
            
    def _checkTerminalConditions(self):
        '''
        Sets the 'results' labels based on the algorithm results.
        '''
        if self._alg.isDone():
            self._doneLbl.setText("Yes")
            self._doneLbl.setAutoFillBackground(True)

        if not self._alg.isSolvable():
            self._solvableLbl.setAutoFillBackground(True)
            self._solvableLbl.setText("No")

    def _resetTimer(self):
        '''
        When the algorithm run speed is modified by the user this resets the
        algorithm timer.
        '''
        if self._spdSetting == 3:
            while not self._alg.isDone() and self._alg.isSolvable():
                self._alg.step()
                
            self._worldWidget.repaint()
            self._timer.stop()
            self._runBtn.setText("Run")
            
            self._checkTerminalConditions()            
        else:
            timeOut = 1
            if self._spdSetting == 0:
                timeOut = 500
            elif self._spdSetting == 1:
                timeOut = 250
            elif self._spdSetting == 2:
                timeOut = 1            
            self._timer.start(timeOut)
示例#47
0
文件: SceneInfo.py 项目: LLNL/boxfish
class RangeWidget(QWidget):
    """Interface for changing Range information. It shows the current
       range and range policy.
       This widget was designed for use with the tab dialog. It can be used by
       itself or it can be used as part of a bigger color tab.

       Changes to this widget are emitted via a changeSignal as a boolean
       on policy, range tuple and this widget's tag.
    """

    changeSignal = Signal(bool, float, float, str)

    def __init__(self, parent, use_max, current_range, max_range, tag):
        """Creates a ColorMap widget.

           parent
               The Qt parent of this widget.

           use_max
               Whether the policy is to use max possible or set range.

           current_range
               The min and max range on creation.

           tag
               A name for this widget, will be emitted on change.
        """
        super(RangeWidget, self).__init__(parent)
        self.edit_range = (current_range[0], current_range[1])
        self.max_range = max_range
        self.use_max = use_max
        self.tag = tag

        layout = QVBoxLayout()


        self.range_check = QCheckBox("Use maximum range across applicable "
            + "modules.")
        layout.addWidget(self.range_check)
        if self.use_max:
            self.range_check.setChecked(True)
        else:
            self.range_check.setChecked(False)
        self.range_check.stateChanged.connect(self.checkChanged)
        layout.addItem(QSpacerItem(3,3))

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel("Set range: "))
        self.range_min = QLineEdit(str(current_range[0]), self)
        self.range_min.editingFinished.connect(self.rangeChanged)
        hlayout.addWidget(self.range_min)
        hlayout.addWidget(QLabel(" to "))
        self.range_max = QLineEdit(str(current_range[1]), self)
        self.range_max.editingFinished.connect(self.rangeChanged)
        hlayout.addWidget(self.range_max)
        layout.addLayout(hlayout)

        self.setStates()
        self.setLayout(layout)

    def setStates(self):
        if self.use_max:
            self.range_min.setDisabled(True)
            self.range_max.setDisabled(True)
        else:
            self.range_min.setDisabled(False)
            self.range_max.setDisabled(False)

    @Slot()
    def checkChanged(self):
        """Handles check/uncheck of use max."""
        self.use_max = self.range_check.isChecked()
        self.setStates()

        if self.use_max:
            self.changeSignal.emit(self.use_max, self.max_range[0],
                self.max_range[1], self.tag)
        else:
            self.changeSignal.emit(self.use_max, self.edit_range[0],
                self.edit_range[1], self.tag)


    @Slot()
    def rangeChanged(self):
        self.edit_range = (float(self.range_min.text()),
                float(self.range_max.text()))

        self.changeSignal.emit(self.use_max, self.edit_range[0],
                self.edit_range[1], self.tag)
示例#48
0
文件: QtUI.py 项目: rkycia/blather
class UI(gobject.GObject):
    __gsignals__ = {
        'command':
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, ))
    }

    def __init__(self, args, continuous):
        self.continuous = continuous
        gobject.GObject.__init__(self)
        #start by making our app
        self.app = QApplication(args)
        #make a window
        self.window = QMainWindow()
        #give the window a name
        self.window.setWindowTitle("BlatherQt")
        self.window.setMaximumSize(400, 200)
        center = QWidget()
        self.window.setCentralWidget(center)

        layout = QVBoxLayout()
        center.setLayout(layout)
        #make a listen/stop button
        self.lsbutton = QPushButton("Listen")
        layout.addWidget(self.lsbutton)
        #make a continuous button
        self.ccheckbox = QCheckBox("Continuous Listen")
        layout.addWidget(self.ccheckbox)

        #connect the buttons
        self.lsbutton.clicked.connect(self.lsbutton_clicked)
        self.ccheckbox.clicked.connect(self.ccheckbox_clicked)

        #add a label to the UI to display the last command
        self.label = QLabel()
        layout.addWidget(self.label)

        #add the actions for quiting
        quit_action = QAction(self.window)
        quit_action.setShortcut('Ctrl+Q')
        quit_action.triggered.connect(self.accel_quit)
        self.window.addAction(quit_action)

    def accel_quit(self):
        #emit the quit
        self.emit("command", "quit")

    def ccheckbox_clicked(self):
        checked = self.ccheckbox.isChecked()
        if checked:
            #disable lsbutton
            self.lsbutton.setEnabled(False)
            self.lsbutton_stopped()
            self.emit('command', "continuous_listen")
        else:
            self.lsbutton.setEnabled(True)
            self.emit('command', "continuous_stop")

    def lsbutton_stopped(self):
        self.lsbutton.setText("Listen")

    def lsbutton_clicked(self):
        val = self.lsbutton.text()
        if val == "Listen":
            self.emit("command", "listen")
            self.lsbutton.setText("Stop")
            #clear the label
            self.label.setText("")
        else:
            self.lsbutton_stopped()
            self.emit("command", "stop")

    def run(self):
        self.window.show()
        if self.continuous:
            self.ccheckbox.setCheckState(Qt.Checked)
            self.ccheckbox_clicked()
        self.app.exec_()
        self.emit("command", "quit")

    def finished(self, text):
        print text
        #if the continuous isn't pressed
        if not self.ccheckbox.isChecked():
            self.lsbutton_stopped()
        self.label.setText(text)

    def set_icon(self, icon):
        self.window.setWindowIcon(QIcon(icon))
示例#49
0
class window(QMainWindow):
    def __init__(self):
        super(window, self).__init__()

        self.resize(1024,720)
        self.centralWidget = QWidget(self)
        self.setWindowTitle('Plotting Points (Google Maps)')
        
        self.layout = QHBoxLayout(self.centralWidget)
        
        self.frame = QFrame(self.centralWidget)
        self.frameLayout = QVBoxLayout(self.frame)
        
        self.web = QtWebKit.QWebView()
        
        group_left = QGroupBox('Data Preparation')
        groupLeft_layout = QGridLayout()
        
        self.openButton = QPushButton("Open file")
        self.openButton.clicked.connect(self.openfile)
        
        self.optUTM = QCheckBox('UTM Data')
        
        
        groupLeft_layout.addWidget(self.optUTM,0,0)
        groupLeft_layout.addWidget(self.openButton,1,0)
        
        groupLeft_layout.setRowStretch(2,1)
        group_left.setLayout(groupLeft_layout)
        
        self.frameLayout.addWidget(self.web)
        self.layout.addWidget(group_left)
        self.layout.addWidget(self.frame)
        self.layout.setStretch(1,1)
        self.setCentralWidget(self.centralWidget)
        
        url = 'http://maps.google.com'
        
        self.showMap(url)   
        
    def openfile(self):
        
        fname, _ = QFileDialog.getOpenFileName(self, 'Open file', '/home')
        
        if fname:
            f = open(fname)
            
            with f:
                data = f.read().splitlines()
                self.plottomap(data)
        else:
            print 'a'
    
    
    def dataConst(self,dataline):
    
        coord_list = []
    
        for data in dataline:
            catch_data = map(float, data.strip().split())
            coord_list.append(tuple(catch_data))
        
        if self.optUTM.isChecked() == True:
            coord_list = self.UTMtoLatLon(coord_list)
        
        return coord_list
        
        
    def plottomap(self,data):
        
        
        coords_data = self.dataConst(data)
        
        
        mymap = pygmaps.maps(coords_data[0][0], coords_data[0][1], 6)
        
        
        for i, point in enumerate(coords_data):
            mymap.addpoint(point[0], point[1], "#FF0000")
        
        mymap.addpath(coords_data, '#0000FF')
        
        mymap.draw('./mymap.draw.html')
        url = './mymap.draw.html'
        
        self.showMap(url)
    
    def UTMtoLatLon(self, utmData):
        utm_list = utmData
        latlon_list = []
        for i in range(len(utm_list)-1):
        
            (lat, lon) = utm.to_latlon(utm_list[i][0], utm_list[i][1], 52, 'M')
            
            latlon_list.append((lat,lon))
        
        return latlon_list
    
     
    def showMap(self, url):
        
        self.web.load(QtCore.QUrl(url))
        
        self.web.show()
示例#50
0
class _PhotonIntensityResultOptionsToolItem(_ResultToolItem):
    def _initUI(self):
        # Variables
        solidangle_sr = self.options().detectors[self.key()].solidangle_sr
        self._factors = {
            "counts / (s.A)": solidangle_sr / physics.e,
            "counts / (s.nA)": solidangle_sr / physics.e / 1e9,
        }

        # Widgets
        self._cb_unit = QComboBox()
        self._cb_unit.addItem("counts / (sr.electron)")
        self._cb_unit.addItem("counts / (s.A)")
        self._cb_unit.addItem("counts / (s.nA)")

        self._chk_uncertainty = QCheckBox("Show uncertainties")
        self._chk_uncertainty.setChecked(True)

        self._chk_pg = QCheckBox("No fluorescence")
        self._chk_pg.setChecked(True)

        self._chk_cg = QCheckBox("Characteristic fluorescence")
        self._chk_cg.setChecked(True)

        self._chk_bg = QCheckBox("Bremsstrahlung fluorescence")
        self._chk_bg.setChecked(True)

        self._chk_tg = QCheckBox("Total")
        self._chk_tg.setChecked(True)

        self._chk_pe = QCheckBox("No fluorescence")
        self._chk_pe.setChecked(True)

        self._chk_ce = QCheckBox("Characteristic fluorescence")
        self._chk_ce.setChecked(True)

        self._chk_be = QCheckBox("Bremsstrahlung fluorescence")
        self._chk_be.setChecked(True)

        self._chk_te = QCheckBox("Total")
        self._chk_te.setChecked(True)

        # Layouts
        layout = _ResultToolItem._initUI(self)
        layout.addRow("Unit", self._cb_unit)
        layout.addRow(self._chk_uncertainty)

        boxlayout = QVBoxLayout()
        boxlayout.addWidget(self._chk_pg)
        boxlayout.addWidget(self._chk_cg)
        boxlayout.addWidget(self._chk_bg)
        boxlayout.addWidget(self._chk_tg)

        box_generated = QGroupBox("Generated intensities (no absorption)")
        box_generated.setLayout(boxlayout)
        layout.addRow(box_generated)

        boxlayout = QVBoxLayout()
        boxlayout.addWidget(self._chk_pe)
        boxlayout.addWidget(self._chk_ce)
        boxlayout.addWidget(self._chk_be)
        boxlayout.addWidget(self._chk_te)

        box_emitted = QGroupBox("Emitted intensities (with absorption)")
        box_emitted.setLayout(boxlayout)
        layout.addRow(box_emitted)

        # Signals
        self._cb_unit.currentIndexChanged.connect(self.stateChanged)
        self._chk_uncertainty.stateChanged.connect(self.stateChanged)
        self._chk_pg.stateChanged.connect(self.stateChanged)
        self._chk_cg.stateChanged.connect(self.stateChanged)
        self._chk_bg.stateChanged.connect(self.stateChanged)
        self._chk_tg.stateChanged.connect(self.stateChanged)
        self._chk_pe.stateChanged.connect(self.stateChanged)
        self._chk_ce.stateChanged.connect(self.stateChanged)
        self._chk_be.stateChanged.connect(self.stateChanged)
        self._chk_te.stateChanged.connect(self.stateChanged)

        return layout

    def showUncertainty(self):
        return self._chk_uncertainty.isChecked()

    def showGenerated(self):
        return (self._chk_pg.isChecked(), self._chk_cg.isChecked(), self._chk_bg.isChecked(), self._chk_tg.isChecked())

    def showEmitted(self):
        return (self._chk_pe.isChecked(), self._chk_ce.isChecked(), self._chk_be.isChecked(), self._chk_te.isChecked())

    def factor(self):
        unit = self._cb_unit.currentText()
        return self._factors.get(unit, 1.0)
示例#51
0
class Panel(QWidget):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        self.state = state
        self.entry = None
        self.saf = Saf.AUTO
        self.peid = ROOT
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()
        self.showOrHideNotes()
        self.showOrHideSortAs()
        self.termEdit.setFocus()

    def createWidgets(self):
        self.helpButton = QToolButton()
        self.helpButton.setIcon(QIcon(":/help.svg"))
        self.helpButton.setFocusPolicy(Qt.NoFocus)
        self.tooltips.append((self.helpButton, "Help on the Entry panel."))
        self.addingLabel = Widgets.Label.HtmlLabel(CANCEL_ADD)
        self.addingLabel.hide()
        self.termLabel = QLabel("&Term")
        self.termEdit = Widgets.LineEdit.HtmlLineEdit(self.state)
        self.tooltips.append((self.termEdit, """\
<p><b>Term editor</b> (Alt+T)</p>
<p>The entry's term text styled (e.g., <b>bold</b>, <i>italic</i>), as
it should appear in the final index.</p>"""))
        self.spellHighlighter = Widgets.SpellHighlighter.Highlighter(
            self.state, self.termEdit.document())
        self.termLabel.setBuddy(self.termEdit)
        self.pagesLabel = QLabel("&Pages")
        self.pagesEdit = Widgets.LineEdit.HtmlPagesLineEdit(self.state,
                                                            maxLines=3)
        self.tooltips.append((self.pagesEdit, """\
<p><b>Pages editor</b> (Alt+P)</p>
<p>The entry's pages styled (e.g., <b>bold</b>, <i>italic</i>), as they
should appear in the final index.</p> <p>The pages are automatically
sorted, and exact duplicates are automatically removed.</p> <p>See also
<b>Index→Combine Overlapping Pages</b> and <b>Index→Renumber
Pages</b>.</p>"""))
        self.pagesLabel.setBuddy(self.pagesEdit)
        self.calcSortAsCheckBox = QCheckBox("&Automatically Calculate Sort As")
        self.tooltips.append((self.calcSortAsCheckBox, """\
<p><b>Automatically Calculate Sort As</b> (Alt+A)</p>
<p>This checkbox controls how the Sort As text is created.</p>
<p>If checked, {} will either automatically create the sort as
text, or will present some choices from which to choose the sort as
text, depending on the term text.</p>
<p>If unchecked, the sort as text should be entered
manually.</p>""".format(QApplication.applicationName())))
        self.calcSortAsCheckBox.setChecked(True)
        self.sortAsHelpButton = QToolButton()
        self.sortAsHelpButton.setIcon(QIcon(":/help.svg"))
        self.sortAsHelpButton.setFocusPolicy(Qt.NoFocus)
        self.tooltips.append(
            (self.sortAsHelpButton, "Help on the Sort As text."))
        self.sortAsEdit = Widgets.LineEdit.LineEdit(self.state)
        self.tooltips.append((self.sortAsEdit, """\
<p><b>Sort As editor</b> (Alt+S)</p>
<p>The entry's sort as text.</p>
<p>If the <b>Automatically Calculate Sort As</b> checkbox is unchecked,
manually enter the sort as text to use for sorting the entry.</p>
<p>Main entry's are sorted using the sort as text, so it is easy to
force a non-standard ordering by entering a custom sort as text.</p>
<p>Subentries are also sorted using the sort as text, but the first word
of a subentry will be ignored for sorting purposes if it is in the
Ignore Subentry Function words list (see <b>Index→Ignore Subentry
Function words</b>) <i>and</i> the <b>Index→Options, Rules,
Ignore Subenty Function Words</b> checkbox is checked for this
index.</p>"""))
        self.sortAsEdit.setEnabled(False)
        self.sortAsLabel = QLabel("&Sort As")
        self.sortAsLabel.setBuddy(self.sortAsEdit)
        self.sortAsLabel.setEnabled(False)
        self.xrefLabel = QLabel("&Cross-references")
        self.xrefList = Widgets.List.HtmlListWidget(self.state, minLines=4)
        self.tooltips.append((self.xrefList, """\
<p><b>Cross-references list</b> (Alt+C)</p>
<p>The list of the entry's see and see also cross-references, both
generic and to other entries.</p>
<p>To add a cross-reference to an entry, circle the <i>to</i> entry
(<b>Entry→Circle</b>), then go to the <i>from</i> entry and click
<img src=":/xref-add.svg" width={0} height={0}> or press
<b>Entry→Add Cross-reference</b> (See also the <b>Entry</b>
menu.)</p>""".format(TOOLTIP_IMAGE_SIZE)))
        self.xrefLabel.setBuddy(self.xrefList)
        self.notesLabel = QLabel("&Notes")
        self.notesEdit = Widgets.LineEdit.MultilineHtmlEdit(self.state)
        self.tooltips.append((self.notesEdit, """\
<p><b>Notes editor</b> (Alt+N)</p>
<p>The entry's notes.</p>
<p>The notes shown here are never output as part of
the index so may be freely used for any purpose.</p>
<p>If the notes facility isn't wanted, the notes can be hidden by
unchecking the <b>Index→Options, General, Show Notes</b>
checkbox.</p>"""))
        self.notesLabel.setBuddy(self.notesEdit)

    def layoutWidgets(self):
        form = QFormLayout()
        form.addRow(self.addingLabel)
        hbox = QHBoxLayout()
        hbox.addWidget(self.termEdit, 1)
        hbox.addWidget(self.helpButton)
        form.addRow(self.termLabel, hbox)
        form.addRow(self.pagesLabel, self.pagesEdit)
        hbox = QHBoxLayout()
        hbox.addWidget(self.calcSortAsCheckBox, 1)
        hbox.addWidget(self.sortAsHelpButton)
        form.addRow(hbox)
        form.addRow(self.sortAsLabel, self.sortAsEdit)
        vbox = QVBoxLayout()
        vbox.addLayout(form)
        vbox.addWidget(self.xrefLabel)
        vbox.addWidget(self.xrefList, 1)
        vbox.addWidget(self.notesLabel)
        vbox.addWidget(self.notesEdit, 1)
        self.setLayout(vbox)

    def createConnections(self):
        self.helpButton.clicked.connect(self.help)
        self.sortAsHelpButton.clicked.connect(
            lambda: self.help("xix_ref_sortas.html"))
        self.termEdit.textChanged.connect(self.termChanged)
        self.termEdit.cursorPositionChanged.connect(self.maybeSetSuggestions)
        self.termEdit.textChanged.connect(self.updateMode)
        self.termEdit.lostFocus.connect(self.maybeSave)
        self.termEdit.enterPressed.connect(
            lambda: self.tabAndMaybeSave(self.pagesEdit))
        self.pagesEdit.textChanged.connect(self.updateMode)
        self.pagesEdit.lostFocus.connect(self.maybeSave)
        self.pagesEdit.enterPressed.connect(
            lambda: self.tabAndMaybeSave(self.calcSortAsCheckBox))
        self.calcSortAsCheckBox.toggled.connect(self.calcSortAsToggled)
        self.sortAsEdit.textChanged.connect(self.updateMode)
        self.sortAsEdit.lostFocus.connect(self.maybeSave)
        self.sortAsEdit.enterPressed.connect(
            lambda: self.tabAndMaybeSave(self.xrefList))
        self.notesEdit.textChanged.connect(self.updateMode)
        self.notesEdit.lostFocus.connect(self.maybeSave)

    def help(self, page="xix_ref_panel_entry.html"):
        self.state.help(page)

    def tabAndMaybeSave(self, widget):
        self.maybeSave()
        widget.setFocus()

    def updateUi(self):
        enable = self.state.mode not in {ModeKind.NO_INDEX, ModeKind.CHANGE}
        self.setEnabled(enable)
        if enable:
            enable = (self.state.mode in {ModeKind.ADD, ModeKind.EDIT}
                      or not self.termEdit.isEmpty())
            for widget in (self.termEdit, self.pagesEdit,
                           self.calcSortAsCheckBox, self.xrefList,
                           self.notesEdit):
                widget.setEnabled(enable)
            self.sortAsEdit.setEnabled(
                enable and not self.calcSortAsCheckBox.isChecked())
            if self.state.mode is ModeKind.ADD:
                self.state.window.modeLabel.setText(
                    "<font color=green>Adding</font>")

    def updateDisplayFonts(self):
        for widget in (self.termEdit, self.sortAsEdit, self.pagesEdit,
                       self.notesEdit, self.xrefList):
            widget.updateDisplayFonts()

    def populateEditors(self, editors):
        editors |= {
            self.termEdit, self.sortAsEdit, self.pagesEdit, self.notesEdit
        }

    def maybeSave(self):
        if self.hasChanged():
            if not bool(self.sortAsEdit.toPlainText().strip()):
                sortas = self.state.model.sortBy(self.termEdit.toHtml(),
                                                 self.saf, self.peid
                                                 is not ROOT)
                self.sortAsEdit.setPlainText(sortas)
            self.state.save()

    def hasChanged(self):
        term = self.termEdit.toHtml()
        sortas = self.sortAsEdit.toPlainText().strip()
        pages = self.pagesEdit.toHtml()
        notes = self.notesEdit.toHtml()
        if self.entry is None:
            return bool(term or sortas or pages or notes)
        return (self.entry.term != term or self.entry.sortas != sortas
                or self.entry.pages != pages or self.entry.notes != notes
                or self.entry.saf != self.saf)

    def updateMode(self):
        if (self.state.mode not in {
                ModeKind.NO_INDEX, ModeKind.ADD, ModeKind.EDIT, ModeKind.CHANGE
        } and self.hasChanged()):
            self.state.setMode(ModeKind.EDIT)

    def clearForm(self):
        self.state.spellPanel.clearSuggestions()
        self.state.groupsPanel.clear()
        positions = Positions(self.termEdit.textCursor().position(),
                              self.sortAsEdit.textCursor().position(),
                              self.pagesEdit.textCursor().position(),
                              self.notesEdit.textCursor().position())
        self.termEdit.clear()
        self.calcSortAsCheckBox.setChecked(True)
        self.sortAsEdit.clear()
        self.pagesEdit.clear()
        self.xrefList.clear()
        self.notesEdit.clear()
        return positions

    def setEntry(self, entry):
        positions = self.clearForm()
        self.entry = entry
        if entry is not None:
            self.termEdit.setHtml(entry.term, positions.term)
            self.saf = entry.saf or Saf.AUTO
            self.calcSortAsCheckBox.setChecked(self.saf != Saf.CUSTOM)
            self.sortAsEdit.setPlainText(entry.sortas, positions.sortas)
            self.pagesEdit.setHtml(entry.pages, positions.pages)
            self.notesEdit.setHtml(entry.notes, positions.notes)
            for xref in list(self.state.model.xrefs(entry.eid)):
                kind = "See" if xref.kind is XrefKind.SEE else "See also"
                term = Lib.elidePatchHtml(self.state.model.termPath(
                    xref.to_eid),
                                          self.state,
                                          maxlen=None)
                item = QListWidgetItem("{} <i>{}</i> {}".format(
                    XREF_INDICATOR, kind, term))
                item.setData(Qt.UserRole, xref)
                self.xrefList.addItem(item)
            for xref in list(self.state.model.generic_xrefs(entry.eid)):
                kind = ("See (generic)" if xref.kind is XrefKind.SEE_GENERIC
                        else "See also (generic)")
                item = QListWidgetItem("{} <i>{}</i> {}".format(
                    XREF_INDICATOR, kind, xref.term))
                item.setData(Qt.UserRole, xref)
                self.xrefList.addItem(item)
            if self.xrefList.count():
                self.xrefList.setCurrentRow(0)
            self.state.updateGotoEids(entry.eid)
        self.state.groupsPanel.updateGroups()
        self.state.updateNavigationStatus()
        self.state.setMode(ModeKind.VIEW)

    @property
    def unknownWords(self):
        return self.spellHighlighter.unknownWords

    def termChanged(self):
        if self.addingLabel.isVisible():
            self.addingLabel.setText(CANCEL_ADD)
            text = self.termEdit.toPlainText()
            if bool(self.state.model):
                while text:
                    eid = self.state.model.firstForPrefix(text)
                    if eid is not None:
                        term = Lib.elidePatchHtml(self.state.model.term(eid),
                                                  self.state)
                        self.addingLabel.setText(CANCEL_ADD +
                                                 " and goto “{}”".format(term))
                        break
                    text = text[:-1]
        self.maybeSetSuggestions()

    def maybeSetSuggestions(self):
        word, _ = self.termEdit.wordAndPosition()
        if word:
            if self.termEdit.hasFocus():
                replacement = self.state.model.autoReplacementFor(word)
                if replacement is not None:
                    self.termEdit.replaceWord(replacement)
                    return
            self.state.spellPanel.populateSuggestions(word)
        else:
            self.state.spellPanel.clearSuggestions()

    def rememberWord(self):
        word = self.findNearestUnknownWord()
        if word:
            Spell.add(word, self.state.language.value)
            self.state.model.addSpellWord(word)
            self.spellHighlighter.rehighlight()

    def ignoreWord(self):
        word = self.findNearestUnknownWord()
        if word:
            self.spellHighlighter.wordsToIgnore.add(word)
            self.spellHighlighter.rehighlight()

    def findNearestUnknownWord(self):
        pos = self.termEdit.textCursor().position()
        where = -1
        unknownWord = None
        unknownWords = sorted(self.unknownWords)
        for i, word in unknownWords:
            if i > where and i <= pos:
                where = i
                unknownWord = word
            if i > pos:
                break
        if unknownWord is None and unknownWords:
            unknownWord = unknownWords[-1][1]
        return unknownWord

    def completeWithSuggested(self):
        index = self.state.spellPanel.currentRow()
        self.complete(index)

    def complete(self, i):
        item = self.state.spellPanel.item(i)
        if item:
            word = self.state.spellPanel.item(i).text()
            self.completeWord(word)

    def completeWord(self, word):
        word = COMPLETE_WORD_RX.sub("", word)
        if word:
            self.termEdit.replaceWord(word)

    def showOrHideNotes(self):
        settings = QSettings()
        visible = bool(
            int(settings.value(Gopt.Key.ShowNotes, Gopt.Default.ShowNotes)))
        self.notesLabel.setVisible(visible)
        self.notesEdit.setVisible(visible)

    def showOrHideSortAs(self):
        settings = QSettings()
        alwaysShowSortAs = bool(
            int(
                settings.value(Gopt.Key.AlwaysShowSortAs,
                               Gopt.Default.AlwaysShowSortAs)))
        editable = not self.calcSortAsCheckBox.isChecked()
        visible = alwaysShowSortAs or editable
        for widget in (self.sortAsLabel, self.sortAsEdit):
            widget.setVisible(visible)
            widget.setEnabled(editable)

    def calcSortAsToggled(self):
        self.showOrHideSortAs()
        self.updateMode()
        if self.calcSortAsCheckBox.isChecked():
            saf = self.saf if self.saf != Saf.CUSTOM else Saf.AUTO
            self.state.calculateSortAs(saf, force=True)
        else:
            self.saf = Saf.CUSTOM
示例#52
0
class _PhotonDistributionResultOptionsToolItem(_ResultToolItem):
    def _initUI(self):
        # Variables
        result = self.result()
        transitions = sorted(result.iter_transitions())
        transition0 = transitions[0]
        model = _TransitionListModel(transitions)

        # Widgets
        self._chk_errorbar = QCheckBox("Show error bars")
        self._chk_errorbar.setChecked(True)

        self._cb_transition = QComboBox()
        self._cb_transition.setModel(model)
        self._cb_transition.setCurrentIndex(0)

        self._chk_pg = QCheckBox("No absorption, no fluorescence")
        state = result.exists(transition0, True, False, False, False)
        self._chk_pg.setEnabled(state)
        self._chk_pg.setChecked(state)

        self._chk_eg = QCheckBox("With absorption, no fluorescence")
        state = result.exists(transition0, True, True, False, False)
        self._chk_eg.setEnabled(state)
        self._chk_eg.setChecked(state)

        self._chk_pt = QCheckBox("No absorption, with fluorescence")
        state = result.exists(transition0, True, False, True, True)
        self._chk_pt.setEnabled(state)
        self._chk_pt.setChecked(state)

        self._chk_et = QCheckBox("With absorption, with fluorescence")
        state = result.exists(transition0, True, True, True, True)
        self._chk_et.setEnabled(state)
        self._chk_et.setChecked(state)

        # Layouts
        layout = _ResultToolItem._initUI(self)
        layout.addRow(self._chk_errorbar)
        layout.addRow("Transition", self._cb_transition)

        boxlayout = QVBoxLayout()
        boxlayout.addWidget(self._chk_pg)
        boxlayout.addWidget(self._chk_eg)
        boxlayout.addWidget(self._chk_pt)
        boxlayout.addWidget(self._chk_et)

        box_generated = QGroupBox("Curves")
        box_generated.setLayout(boxlayout)
        layout.addRow(box_generated)

        # Signals
        self._cb_transition.currentIndexChanged.connect(self._onTransitionChanged)
        self._chk_pg.stateChanged.connect(self.stateChanged)
        self._chk_eg.stateChanged.connect(self.stateChanged)
        self._chk_pt.stateChanged.connect(self.stateChanged)
        self._chk_et.stateChanged.connect(self.stateChanged)
        self._chk_errorbar.stateChanged.connect(self.stateChanged)

        return layout

    def _onTransitionChanged(self):
        result = self.result()

        index = self._cb_transition.currentIndex()
        transition = self._cb_transition.model().transition(index)

        self._chk_pg.setEnabled(result.exists(transition, True, False, False, False))
        self._chk_eg.setEnabled(result.exists(transition, True, True, False, False))
        self._chk_pt.setEnabled(result.exists(transition, True, False, True, True))
        self._chk_et.setEnabled(result.exists(transition, True, True, True, True))

        self.stateChanged.emit()

    def transition(self):
        index = self._cb_transition.currentIndex()
        return self._cb_transition.model().transition(index)

    def showConditions(self):
        return (
            self._chk_pg.isChecked() and self._chk_pg.isEnabled(),
            self._chk_eg.isChecked() and self._chk_eg.isEnabled(),
            self._chk_pt.isChecked() and self._chk_pt.isEnabled(),
            self._chk_et.isChecked() and self._chk_et.isEnabled(),
        )

    def showErrorbar(self):
        return self._chk_errorbar.isChecked()
示例#53
0
文件: Display.py 项目: ra2003/xindex
class Panel(QWidget):
    def __init__(self, state, config, parent):
        super().__init__(parent)
        self.state = state
        self.config = config
        self.form = parent
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()

    def createWidgets(self):
        size = self.font().pointSize() + (1 if WIN else 2)
        Lib.createFontBoxesFor(self,
                               "DisplayStd",
                               *self.getFontFamilyAndSize(
                                   Gopt.Key.StdFont, Gopt.StdFont,
                                   Gopt.Key.StdFontSize, size),
                               tooltips=self.form.tooltips,
                               which="Std.")
        self.onDisplayStdFontChange(False)
        Lib.createFontBoxesFor(self,
                               "DisplayAlt",
                               *self.getFontFamilyAndSize(
                                   Gopt.Key.AltFont, Gopt.AltFont,
                                   Gopt.Key.AltFontSize, size),
                               tooltips=self.form.tooltips,
                               which="Alt.")
        self.onDisplayAltFontChange(False)
        Lib.createFontBoxesFor(self,
                               "DisplayMono",
                               *self.getFontFamilyAndSize(
                                   Gopt.Key.MonoFont, Gopt.MonoFont,
                                   Gopt.Key.MonoFontSize, size - 1),
                               mono=True,
                               tooltips=self.form.tooltips,
                               which="Mono.")
        self.onDisplayMonoFontChange(False)

        settings = QSettings()

        index = int(
            settings.value(Gopt.Key.MainForm_IndexViewPosition,
                           Gopt.Default.MainForm_IndexViewPosition))
        self.indexViewOnLeft = QCheckBox("&Index View on Left")
        self.indexViewOnLeft.setChecked(not index)
        self.form.tooltips.append((self.indexViewOnLeft, """\
<p><b>Index View on Left</b></p>
<p>If checked, the index view will appear on the left with the entry,
suggestions, and filtered panels on the right.</p>"""))

        showNotes = bool(
            int(settings.value(Gopt.Key.ShowNotes, Gopt.Default.ShowNotes)))
        self.showNotesCheckBox = QCheckBox("Show &Notes")
        self.showNotesCheckBox.setChecked(showNotes)
        self.form.tooltips.append((self.showNotesCheckBox, """\
<p><b>Show Notes</b></p>
<p>If checked, a notes edit&mdash;and any notes that have been
entered&mdash; is visible in the entry panel.</p>"""))

        alwaysShowSortAs = bool(
            int(
                settings.value(Gopt.Key.AlwaysShowSortAs,
                               Gopt.Default.AlwaysShowSortAs)))
        self.alwaysShowSortAsCheckBox = QCheckBox("A&lways Show Sort As")
        self.alwaysShowSortAsCheckBox.setChecked(alwaysShowSortAs)
        self.form.tooltips.append((self.alwaysShowSortAsCheckBox, """\
<p><b>Always Show Sort As</b></p>
<p>If checked, every entry's sort as text is shown. If unchecked,  the
sort as text is only shown if it is entered manually, i.e., if the
<b>Automatically Calculate Sort As</b> checkbox is checked.</p>"""))

        showMenuToolTips = bool(
            int(
                settings.value(Gopt.Key.ShowMenuToolTips,
                               Gopt.Default.ShowMenuToolTips)))
        self.showMenuToolTipsCheckBox = QCheckBox("Show Menu &Tooltips")
        self.showMenuToolTipsCheckBox.setChecked(showMenuToolTips)
        self.form.tooltips.append((self.showMenuToolTipsCheckBox, """\
<p><b>Show Menu Tooltips</b></p>
<p>If checked, menu tooltips are shown when menus are pulled down and
navigated using the mouse or keyboard.</p>"""))

        showMainWindowToolTips = bool(
            int(
                settings.value(Gopt.Key.ShowMainWindowToolTips,
                               Gopt.Default.ShowMainWindowToolTips)))
        self.showMainWindowToolTipsCheckBox = QCheckBox(
            "Show Main &Window Tooltips")
        self.showMainWindowToolTipsCheckBox.setChecked(showMainWindowToolTips)
        self.form.tooltips.append((self.showMainWindowToolTipsCheckBox, """\
<p><b>Show Main Window Tooltips</b></p>
<p>If checked, tooltips are shown when the mouse hovers over controls in
the main window.</p>"""))

        showDialogToolTips = bool(
            int(
                settings.value(Gopt.Key.ShowDialogToolTips,
                               Gopt.Default.ShowDialogToolTips)))
        self.showDialogToolTipsCheckBox = QCheckBox("Show &Dialog Tooltips")
        self.showDialogToolTipsCheckBox.setChecked(showDialogToolTips)
        self.form.tooltips.append((self.showDialogToolTipsCheckBox, """\
<p><b>Show Dialog Tooltips</b></p>
<p>If checked, tooltips are shown when the mouse hovers over controls in
dialogs (such as this one).</p>"""))

        keepHelpOnTop = bool(
            int(
                settings.value(Gopt.Key.KeepHelpOnTop,
                               Gopt.Default.KeepHelpOnTop)))
        self.keepHelpOnTopCheckBox = QCheckBox("Keep &Help on Top")
        self.keepHelpOnTopCheckBox.setChecked(keepHelpOnTop)
        self.form.tooltips.append((self.keepHelpOnTopCheckBox, """\
<p><b>Keep Help on Top</b></p>
<p>If checked, when you pop up the help window it will stay above any
other XindeX window, even if you click another XindeX window.</p>"""))

        showSplash = bool(
            int(settings.value(Gopt.Key.ShowSplash, Gopt.Default.ShowSplash)))
        self.showSplashCheckBox = QCheckBox("Show S&plash at Startup")
        self.showSplashCheckBox.setChecked(showSplash)
        self.form.tooltips.append((self.showSplashCheckBox, """\
<p><b>Show Splash at Startup</b></p>
<p>If checked, a splash window showing the XindeX icon and name will appear
while XindeX is starting.</p>"""))

    def layoutWidgets(self):
        form = QFormLayout()
        grid = QGridLayout()
        grid.addWidget(self.indexViewOnLeft, 0, 0)
        grid.addWidget(self.alwaysShowSortAsCheckBox, 1, 0)
        grid.addWidget(self.showNotesCheckBox, 2, 0)
        grid.addWidget(self.showMenuToolTipsCheckBox, 0, 1)
        grid.addWidget(self.showMainWindowToolTipsCheckBox, 1, 1)
        grid.addWidget(self.showDialogToolTipsCheckBox, 2, 1)
        grid.addWidget(self.keepHelpOnTopCheckBox, 3, 1)
        grid.addWidget(self.showSplashCheckBox, 4, 1)
        hbox = QHBoxLayout()
        hbox.addLayout(grid)
        hbox.addStretch()
        form.addRow(hbox)
        hbox = QHBoxLayout()
        hbox.addWidget(self.displaystdFontComboBox, 1)
        hbox.addWidget(self.displaystdFontSizeSpinBox)
        hbox.addStretch()
        label = QLabel("&Std. Font")
        label.setBuddy(self.displaystdFontComboBox)
        form.addRow(label, hbox)
        hbox = QHBoxLayout()
        hbox.addWidget(self.displayaltFontComboBox, 1)
        hbox.addWidget(self.displayaltFontSizeSpinBox)
        hbox.addStretch()
        label = QLabel("&Alt. Font")
        label.setBuddy(self.displayaltFontComboBox)
        form.addRow(label, hbox)
        hbox = QHBoxLayout()
        hbox.addWidget(self.displaymonoFontComboBox, 1)
        hbox.addWidget(self.displaymonoFontSizeSpinBox)
        hbox.addStretch()
        label = QLabel("&Mono. Font")
        label.setBuddy(self.displaymonoFontComboBox)
        form.addRow(label, hbox)
        self.setLayout(form)

    def createConnections(self):
        self.displaystdFontComboBox.currentFontChanged.connect(
            self.onDisplayStdFontChange)
        self.displaystdFontSizeSpinBox.valueChanged[int].connect(
            self.onDisplayStdFontChange)
        self.displayaltFontComboBox.currentFontChanged.connect(
            self.onDisplayAltFontChange)
        self.displayaltFontSizeSpinBox.valueChanged[int].connect(
            self.onDisplayAltFontChange)
        self.displaymonoFontComboBox.currentFontChanged.connect(
            self.onDisplayMonoFontChange)
        self.displaymonoFontSizeSpinBox.valueChanged[int].connect(
            self.onDisplayMonoFontChange)
        self.indexViewOnLeft.stateChanged.connect(self.setIndexViewOnLeft)
        self.showNotesCheckBox.stateChanged.connect(self.setShowNotes)
        self.alwaysShowSortAsCheckBox.stateChanged.connect(
            self.setAlwaysShowSortAs)
        self.showMenuToolTipsCheckBox.stateChanged.connect(
            self.setShowMenuToolTips)
        self.showMainWindowToolTipsCheckBox.stateChanged.connect(
            self.setShowMainWindowToolTips)
        self.showDialogToolTipsCheckBox.stateChanged.connect(
            self.setShowDialogToolTips)
        self.showSplashCheckBox.stateChanged.connect(self.setShowSplash)
        self.keepHelpOnTopCheckBox.stateChanged.connect(self.setKeepHelpOnTop)

    def getFontFamilyAndSize(self, familyOpt, familyDef, sizeOpt, sizeDef):
        settings = QSettings()
        family = settings.value(familyOpt, familyDef)
        size = int(settings.value(sizeOpt, sizeDef))
        return family, size

    def onDisplayStdFontChange(self, propagate=True):
        font = QFont(self.displaystdFontComboBox.currentFont())
        font.setPointSize(self.displaystdFontSizeSpinBox.value())
        if propagate:
            settings = QSettings()
            settings.setValue(Gopt.Key.StdFont, font.family())
            settings.setValue(Gopt.Key.StdFontSize, font.pointSize())
            self.state.updateDisplayFonts()

    def onDisplayAltFontChange(self, propagate=True):
        font = QFont(self.displayaltFontComboBox.currentFont())
        font.setPointSize(self.displayaltFontSizeSpinBox.value())
        if propagate:
            settings = QSettings()
            settings.setValue(Gopt.Key.AltFont, font.family())
            settings.setValue(Gopt.Key.AltFontSize, font.pointSize())
            self.state.updateDisplayFonts()

    def onDisplayMonoFontChange(self, propagate=True):
        font = QFont(self.displaymonoFontComboBox.currentFont())
        font.setPointSize(self.displaymonoFontSizeSpinBox.value())
        if propagate:
            settings = QSettings()
            settings.setValue(Gopt.Key.MonoFont, font.family())
            settings.setValue(Gopt.Key.MonoFontSize, font.pointSize())
            self.state.updateDisplayFonts()

    def setIndexViewOnLeft(self):
        index = 0 if self.indexViewOnLeft.isChecked() else 1
        settings = QSettings()
        settings.setValue(Gopt.Key.MainForm_IndexViewPosition, index)
        self.state.window.setIndexViewPosition()

    def setShowNotes(self):
        showNotes = int(self.showNotesCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.ShowNotes, showNotes)
        self.state.entryPanel.showOrHideNotes()

    def setAlwaysShowSortAs(self):
        alwaysShowSortAs = int(self.alwaysShowSortAsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.AlwaysShowSortAs, alwaysShowSortAs)
        self.state.entryPanel.showOrHideSortAs()

    def setShowMenuToolTips(self):
        showMenuToolTips = int(self.showMenuToolTipsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.ShowMenuToolTips, showMenuToolTips)

    def setShowMainWindowToolTips(self):
        showMainWindowToolTips = int(
            self.showMainWindowToolTipsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.ShowMainWindowToolTips,
                          showMainWindowToolTips)
        self.state.window.updateToolTips()

    def setShowDialogToolTips(self):
        showDialogToolTips = int(self.showDialogToolTipsCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.ShowDialogToolTips, showDialogToolTips)
        self.form.updateToolTips(showDialogToolTips)

    def setShowSplash(self):
        showSplash = int(self.showSplashCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.ShowSplash, showSplash)

    def setKeepHelpOnTop(self):
        keepHelpOnTop = int(self.keepHelpOnTopCheckBox.isChecked())
        settings = QSettings()
        settings.setValue(Gopt.Key.KeepHelpOnTop, keepHelpOnTop)
示例#54
0
class SettingsPage(grumble.qt.bridge.FormWidget):
    def __init__(self, parent = None):
        super(SettingsPage, self).__init__(parent)
        self.setMinimumSize(800, 600)
        self.addProperty(grizzle.User, "email", 0, 0)
        self.addProperty(grizzle.User, "display_name", 1, 0)
        self.addProperty(sweattrails.userprofile.UserProfile,
                         "_userprofile.dob", 2, 0)
        self.addProperty(sweattrails.userprofile.UserProfile,
                         "_userprofile.gender", 3, 0,
                         style = "radio")
        self.addProperty(sweattrails.userprofile.UserProfile,
                         "_userprofile.height", 4, 0,
                         min = 100, max = 240, suffix = "cm")
        self.addProperty(sweattrails.userprofile.UserProfile,
                         "_userprofile.units", 5, 0,
                         style = "radio")
        
        withingsB = QGroupBox("Withings Support",  self)
        withingsL = QGridLayout(withingsB)
        self.enableWithings = QCheckBox("Enable Withings",  withingsB)
        self.enableWithings.toggled.connect(self.toggleWithings)
        withingsL.addWidget(self.enableWithings, 0, 0)
        withingsL.addWidget(QLabel("Withings User ID"), 1, 0)
        self.withingsUserID = QLineEdit(withingsB)
        withingsL.addWidget(self.withingsUserID, 1, 1)
        withingsL.addWidget(QLabel("Withings Key"), 2, 0)
        self.withingsKey = QLineEdit(withingsB)
        withingsL.addWidget(self.withingsKey, 2, 1)
        self.addWidget(withingsB, self.form.rowCount(), 0, 1, 2)
        self.addStretch()
        self.statusMessage.connect(QCoreApplication.instance().status_message)
        
    def toggleWithings(self, checked):
        with gripe.db.Tx.begin():
            part = self.instance().get_part("WeightMgmt")
            if not part:
                return
            if checked:
                auth = sweattrails.userprofile.WithingsAuth.query(parent = part).get()
                self.withingsUserID.setEnabled(True)
                self.withingsKey.setEnabled(True)
                if auth:
                    self.withingsUserID.setText(auth.userid)
                    self.withingsKey.setText(auth.public_key)
            else:
                self.withingsUserID.setText("")
                self.withingsUserID.setEnabled(False)
                self.withingsKey.setText("")
                self.withingsKey.setEnabled(False)
            
    def assign(self, user):
        with gripe.db.Tx.begin():
            part = user.get_part("WeightMgmt")
            if not part:
                return
            auth = sweattrails.userprofile.WithingsAuth.query(parent = part).get()
            if auth:
                self.enableWithings.setChecked(bool(auth))

    def retrieve(self, user):
        with gripe.db.Tx.begin():
            part = user.get_part("WeightMgmt")
            if not part:
                return
            auth = sweattrails.userprofile.WithingsAuth.query(parent = part).get()
            if self.enableWithings.isChecked():
                if not auth:
                    auth = sweattrails.userprofile.WithingsAuth(parent = part)
                auth.userid = self.withingsUserID.text()
                auth.public_key = self.withingsKey.text()
                auth.put()
            else:
                if auth:
                    grumble.model.delete(auth)
    
    def refresh(self):
        self.activate()

    def activate(self):
        if QCoreApplication.instance().user:
            self.setInstance(QCoreApplication.instance().user)
示例#55
0
class qHotField(QWidget):
    def __init__(self, name, mytype, initial_value, value_list = None, pos = "left", help_text = None, help_instance = None, min_size = 0, max_size = None, handler = None, multiline=False):
        QWidget.__init__(self)
        if max_size == None:
            max_size = 300
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) # Let it expand horizontally but not vertically
        self.name = name
        self.mytype = mytype
        self.multiline = multiline
        self.setContentsMargins(1, 1, 1, 1)
        self.is_popup = (value_list != None)
        if self.is_popup:
            self.value_list = [str(v) for v in value_list] # It's possible the values won't be strings.
        if pos == "top":
            self.layout1 = QVBoxLayout()
        else:
            self.layout1=QHBoxLayout()
        self.layout1.setContentsMargins(1, 1, 1, 1)
        self.layout1.setSpacing(1)
        self.setLayout(self.layout1)
        if mytype == bool:
            self.cb = QCheckBox(name)
            self.cb.setFont(regular_small_font)
            self.layout1.addWidget(self.cb)
            self.cb.setChecked(initial_value)
            if handler != None:
                self.cb.toggled.connect(handler)
        else:
            if not self.is_popup:
                if multiline:
                    self.efield=QPlainTextEdit("")
                    self.efield.appendPlainText(str(initial_value))
                else:
                    self.efield = QLineEdit("Default Text")
                    self.efield.setText(str(initial_value))
                if handler != None:
                    self.efield.textChanged.connect(handler)
            else:
                self.efield = QComboBox()
                self.efield.addItems(value_list)
                if len(value_list) != 0:
                    self.efield.setCurrentIndex(value_list.index(initial_value))
                self.efield.setSizeAdjustPolicy(QComboBox.AdjustToContents)
                if handler != None:
                    self.efield.currentIndexChanged.connect(handler)
                self.layout1.setContentsMargins(5, 5, 5, 5) # Popups need a little more space
                self.layout1.setSpacing(2)
            self.efield.setFont(regular_small_font)
            self.label = QLabel(name)
            self.label.setFont(regular_small_font)
            if pos == "right":
                self.layout1.addWidget(self.efield)
                self.layout1.addWidget(self.label)
            else:
                self.layout1.addWidget(self.label)
                self.layout1.addWidget(self.efield)
            
            self.efield.setMaximumWidth(max_size)
            if min_size != 0:
                self.efield.setMinimumWidth(min_size)
        self.layout1.addStretch()
        if help_text != None:
            if (help_instance == None):
                print "No help instance specified."
            else:
                help_button_widget = help_instance.create_button(name, help_text)
                self.layout1.addWidget(help_button_widget)
                    
    def repopulate_list(self, initial_value, value_list):
        if not self.is_popup:
            print "This qHotField is not a popup list. So it can't be repopulated"
            return
        self.value_list = [str(v) for v in value_list] # It's possible the values won't be strings
        self.efield.clear()
        self.efield.addItems(value_list)
        self.efield.setCurrentIndex(value_list.index(initial_value))
        return
        
    def get_myvalue(self):
        if self.mytype == bool:
            return self.cb.isChecked()
        else:
            if self.is_popup:
                the_txt = self.efield.currentText()
            else:
                if self.multiline:
                    the_txt = self.efield.toPlainText()
                else:
                    the_txt = self.efield.text()
            if (self.mytype == str) or (self.mytype == unicode):
                return (self.mytype)(the_txt)
            else: # if we have a numerical type, the user might have entered a list separated by spaces. Handle that specially
                the_val = re.findall(r"\S+", the_txt) # We might have a list of values separated by spaces if this is a numerical variable
                if len(the_val) == 1:  # it's just a single value
                    result = (self.mytype)(the_txt)
                else: # it's a list. We want to convert treat this as a monte sequence
                    res = []
                    for v in the_val:
                        res.append((self.mytype)(v))
                    result = MonteSequence(res)
                return result
        
    def set_myvalue(self, val):
        if self.mytype == bool:
            self.cb.setChecked(val)
        elif self.is_popup:
            self.efield.setCurrentIndex(self.value_list.index(val))
        else:
            if type(val) == list:
                result = ""
                for x in val:
                    result = result + str(x) + " "
                self.efield.setText(result)
            else:
                if self.multiline:
                    self.efield.clear()
                    self.efield.appendPlainText(str(val))
                else:
                    self.efield.setText(str(val))
    value = property(get_myvalue, set_myvalue)
示例#56
0
class FindReplaceDialog(QDialog):
  """A find and replace dialog that has a search-as-I-type option
     The caller should keep a reference to this dialog, or delete it
     explicitly"""
  find_text_changed = Signal(str)
  replace_committed = Signal(str, str)
  find_cancelled = Signal()
  
  def __init__(self, parent=None):
    super(FindReplaceDialog, self).__init__(parent)
    layout = QGridLayout()
    # prepare the widgets
    label_find = QLabel(self.tr("Find"))
    self.lineedit_find = QLineEdit()
    label_replace = QLabel(self.tr("Replace"))
    self.lineedit_replace = QLineEdit()
    self.checkbox_dynamic_find = QCheckBox(self.tr("Search as I type"))
    self.button_find = QPushButton(self.tr("Find"))
    self.button_replace = QPushButton(self.tr("Replace"))
    button_cancel = QPushButton(self.tr("Cancel"))
    # connect the signals
    self.lineedit_find.textEdited.connect(self._findEdited)
    self.button_find.clicked.connect(self._emitFind)
    self.checkbox_dynamic_find.stateChanged.connect(self._dynamicFindChanged)
    self.button_replace.clicked.connect(self._emitReplacement)
    button_cancel.clicked.connect(self._cancel)
    # setup the layout
    row = 0; col = 0;
    layout.addWidget(label_find, row, col)
    col += 1;
    layout.addWidget(self.lineedit_find, row, col)
    row += 1; col -= 1
    layout.addWidget(label_replace, row, col)
    col += 1
    layout.addWidget(self.lineedit_replace, row, col)
    row += 1; col -= 1;
    layout.addWidget(self.checkbox_dynamic_find, row, col, 1, 2)
    row += 1
    layout.addWidget(self.button_find, row, col)
    col += 1
    layout.addWidget(self.button_replace, row, col)
    row += 1; col -= 1
    layout.addWidget(button_cancel, row, col, 1, 2)
    self.setLayout(layout)
    self.setWindowTitle(self.tr("Find/Replace"))
    
  def keyPressEvent(self, kpe):
    if kpe.key() == Qt.Key.Key_Enter:
      self._emitFind()
    else:
      super(FindReplaceDialog, self).keyPressEvent(kpe)
    
  def _findEdited(self, text):
    if self.checkbox_dynamic_find.isChecked():
      self.find_text_changed.emit(text)
    else: pass
    
  def _emitFind(self):
    self.find_text_changed.emit(self.lineedit_find.text())
    
  def _dynamicFindChanged(self, state):
    print state
    if self.button_find.isEnabled():
      self.button_find.setEnabled(False)
    else: self.button_find.setEnabled(True)
    
  def _emitReplacement(self):
    # don't emit a replacement with empty fields
    if not self.lineedit_find.text() or not self.lineedit_replace.text():
      QApplication.beep()
    else:
      self.replace_committed.emit(self.lineedit_find.text(), self.lineedit_replace.text())
    
  def _cancel(self):
    self.find_cancelled.emit()
    self.hide()
    
  def closeEvent(self, ce):
    self._cancel()