Exemplo n.º 1
0
class ProfileFormWidget(QWidget):
    '''
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        QWidget.__init__(self)
        self._initGUI()

    def _initGUI(self):
        self.layout = QVBoxLayout()
        self.form = QFormLayout()

        self.name = QLineEdit()
        self.surname = QLineEdit()

        self.birthdate = QCalendarWidget()
        self.birthdate.setGridVisible(True)
        self.birthdate.setMinimumDate(QDate(1850, 1, 1))
        self.birthdate.setMaximumDate(QDate.currentDate())

        self.male = QRadioButton("Male")
        self.male.setChecked(True)
        self.female = QRadioButton("Female")

        self.height = QDoubleSpinBox()
        self.height.setMaximum(250)
        self.height.setMinimum(50)
        self.height.setValue(165)
        self.height.setSuffix(" cm")

        self.mass = QDoubleSpinBox()
        self.mass.setMaximum(300)
        self.mass.setMinimum(20)
        self.mass.setValue(60)
        self.mass.setSuffix(" Kg")

        btnLayout = QVBoxLayout()

        self.form.addRow("Name", self.name)
        self.form.addRow("Surname", self.surname)
        self.form.addRow("Birth date", self.birthdate)

        sexLayout = QHBoxLayout()
        sexLayout.addWidget(self.male)
        sexLayout.addWidget(self.female)
        self.form.addRow("Sex", sexLayout)

        self.form.addRow("Height", self.height)
        self.form.addRow("Mass", self.mass)

        self.layout.addLayout(self.form)
        self.layout.addLayout(btnLayout)
        self.setLayout(self.layout)

    def getLayout(self):
        return self.layout

    def getWidget(self):
        widget = QWidget()
        widget.setLayout(self.layout)

        return widget

    def setProfile(self, athlete):
        self.name.setText(athlete._name)
        self.surname.setText(athlete._surname)
        self.birthdate.setSelectedDate(athlete._birthDate)

        if athlete._sex == "Male":
            self.male.setChecked(True)
        else:
            self.female.setChecked(True)

        self.height.setValue(athlete._height)
        self.mass.setValue(athlete._mass)

    def getProfile(self):
        qDate = self.birthdate.selectedDate()
        birthDate = self.qDate_to_date(qDate)

        athleteProfile = Athlete(self.name.text(), self.surname.text(),
                                 self._getSex(), birthDate,
                                 self.height.value(), self.mass.value())
        return athleteProfile

    def qDate_to_date(self, qDate):
        return date(qDate.year(), qDate.month(), qDate.day())

    def _getSex(self):
        if (self.male.isChecked()):
            return "Male"
        elif (self.female.isChecked()):
            return "Female"
        else:
            print "Error: No sex selected"
            return False
Exemplo n.º 2
0
class Form(QDialog):

    def __init__(self, state, term, candidates, result, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.term = term
        self.candidates = []
        for candidate in candidates:
            self.candidates.append(humanizedCandidate(
                term, candidate.candidate, candidate.saf))
        self.result = result
        self.setWindowTitle("Sort As — {}".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.termLabel = Widgets.Label.HtmlLabel(
            "<p>Sort “{}” with</p>".format(Lib.elidePatchHtml(self.term,
                                                              self.state)))
        self.radioButtons = []
        seen = set()
        for index, candidate in enumerate(self.candidates, 1):
            candidate_word = str(candidate.candidate_word)
            name = self.nameForKind(candidate.kind, candidate_word)
            extra = ""
            if candidate_word in seen:
                extra = " (treat roman numbers as literal text)"
            else:
                seen.add(candidate_word)
            radioButton = QRadioButton("&{} “{}” as{} “{}”{}".format(
                index, candidate.term_word, name, candidate_word, extra))
            self.radioButtons.append(radioButton)
        self.radioButtons[0].setChecked(True)
        self.customRadioButton = QRadioButton("&Custom:")
        self.tooltips.append((self.customRadioButton, """\
<p><b>Custom</b></p>
<p>If checked, this entry's <b>Automatically Calculate Sort As</b>
setting will be <i>unchecked</i>, and the sort as text entered here will
be used as ther entry's sort as text.</p>"""))
        self.sortAsEdit = Widgets.LineEdit.LineEdit(self.state)
        self.tooltips.append((self.sortAsEdit, """\
<p><b>Custom Sort As editor</b></p>
<p>If <b>Custom</b> is checked, this entry's <b>Automatically Calculate
Sort As</b> setting will be <i>unchecked</i>, and the sort as text
entered here will be used as ther entry's sort as text.</p>"""))
        self.sortAsEdit.setText(self.candidates[0].candidate)
        self.sortAsEdit.selectAll()
        self.buttonBox = QDialogButtonBox()
        self.okButton = QPushButton(QIcon(":/ok.svg"), "&OK")
        self.tooltips.append((self.okButton, """\
<p><b>OK</b></p>
<p>Use the specified or custom sort as text for entry
“{}”.</p>""".format(Lib.elidePatchHtml(self.term, self.state))))
        self.buttonBox.addButton(
            self.okButton, QDialogButtonBox.AcceptRole)
        self.helpButton = QPushButton(QIcon(":/help.svg"), "Help")
        self.tooltips.append((self.helpButton,
                              "Help on the Sort As dialog"))
        self.buttonBox.addButton(
            self.helpButton, QDialogButtonBox.HelpRole)


    def nameForKind(self, kind, candidate_word):
        name = kind.name.lower()
        if name == "unchanged":
            name = ""
        elif (name == "roman" or (
                name == "phrase" and
                re.fullmatch(r"[\d.]+", candidate_word) is not None)):
            name = "number"
        if name:
            name = " " + name
        return name


    def layoutWidgets(self):
        vbox = QVBoxLayout()
        vbox.addWidget(self.termLabel)
        for radioButton in self.radioButtons:
            vbox.addWidget(radioButton)
        hbox = QHBoxLayout()
        hbox.addWidget(self.customRadioButton)
        hbox.addWidget(self.sortAsEdit)
        vbox.addLayout(hbox)
        vbox.addWidget(self.buttonBox)
        self.setLayout(vbox)


    def createConnections(self):
        for radioButton in itertools.chain((self.customRadioButton,),
                                           self.radioButtons):
            radioButton.toggled.connect(self.updateUi)
        self.sortAsEdit.textChanged.connect(self.updateUi)
        self.okButton.clicked.connect(self.accept)
        self.helpButton.clicked.connect(self.help)


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


    def updateUi(self):
        self.sortAsEdit.setEnabled(self.customRadioButton.isChecked())
        with Lib.BlockSignals(self.sortAsEdit):
            for i, radioButton in enumerate(self.radioButtons):
                if radioButton.isChecked():
                    self.sortAsEdit.setText(self.candidates[i].candidate)
                    self.sortAsEdit.selectAll()
                    break
        self.okButton.setEnabled(
            not self.customRadioButton.isChecked() or
            (self.customRadioButton.isChecked() and
             bool(self.sortAsEdit.toPlainText())))


    def reject(self):
        self.accept()


    def accept(self):
        if self.customRadioButton.isChecked():
            self.result.sortas = self.sortAsEdit.toPlainText()
            self.result.saf = Saf.CUSTOM
        else:
            for index, radioButton in enumerate(self.radioButtons):
                if radioButton.isChecked():
                    self.result.sortas = self.candidates[index].candidate
                    kind = self.candidates[index].kind
                    if kind is CandidateKind.LITERAL:
                        saf = Saf.AUTO_BASIC
                    elif kind is CandidateKind.NUMBER:
                        saf = Saf.AUTO_NUMBER
                    elif kind is CandidateKind.ROMAN:
                        saf = Saf.AUTO_NUMBER_ROMAN
                    elif kind is CandidateKind.PHRASE:
                        saf = Saf.AUTO
                    elif kind is CandidateKind.UNCHANGED:
                        saf = self.candidates[index].saf
                    self.result.saf = saf
                    break
        super().accept()
Exemplo n.º 3
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()
Exemplo n.º 4
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
Exemplo n.º 5
0
class RateView(QGroupBox):
    '''The box containing the rate value'''

    def __init__(self, title = 'Rate', parent = None):
        '''Initialize'''
        super(RateView, self).__init__(parent)
        self.setTitle(title)
        self._createWidgets()

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

        # Rate or lifetime chooser
        self.rate = QRadioButton('Rate', self)
        self.rate.setToolTip(ttt('Choose this to express exchange as rate'))
        self.lifetime = QRadioButton('Lifetime', self)
        self.lifetime.setToolTip(ttt('Choose this to express exchange as '
                                     'lifetime'))

        # Box containing value
        self.rate_value = QLineEdit(self)
        validate = QDoubleValidator(self.rate_value)
        validate.setDecimals(3)
        validate.setBottom(0.0)
        self.rate_value.setValidator(validate)
        self.rate_value.setToolTip(ttt('The rate or lifetime value'))

        # Unit
        self.unit = QComboBox(self)
        self.unit.setToolTip(ttt('Selects the input unit for the rate '
                                 'or lifetime'))

    def initUI(self):
        '''Lays out the widgets'''
        radios = QVBoxLayout()
        radios.addWidget(self.rate)
        radios.addWidget(self.lifetime)
        rate = QGridLayout()
        rate.addWidget(QLabel("Unit: "), 1, 1)
        rate.addWidget(self.unit, 1, 2)
        rate.addWidget(QLabel("Value: "), 2, 1)
        rate.addWidget(self.rate_value, 2, 2)
        total = QHBoxLayout()
        total.addLayout(radios)
        total.addStretch()
        total.addLayout(rate)
        self.setLayout(total)

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

        # When one radio button is checked, change the combo box model
        # and un-check the other radio button
        self.rate.clicked.connect(self.setRateModel)
        self.lifetime.clicked.connect(self.setLifetimeModel)

        # If the text changes, emit that rate
        self.rate_value.editingFinished.connect(self.emitRate)

        # If the underlying model changes, adjust the text
        self.model.rateChanged.connect(self.updateRate)

        # If the unit changes, update rate
        self.unit.currentIndexChanged.connect(self.updateUnit)

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

    def setRate(self, rate):
        '''Set the rate manually'''
        self.rate_value.setText(str(rate))
        self.rate_value.editingFinished.emit()

    def setUnit(self, unit):
        '''Set the unit manually'''
        if unit == 's':
            self.lifetime.click()
            self.unit.setCurrentIndex(0)
        elif unit == 'ns':
            self.lifetime.click()
            self.unit.setCurrentIndex(1)
        elif unit == 'ps':
            self.lifetime.click()
            self.unit.setCurrentIndex(2)
        elif unit == 'fs':
            self.lifetime.click()
            self.unit.setCurrentIndex(3)
        elif unit in ('Hz', 'hz'):
            self.rate.click()
            self.unit.setCurrentIndex(0)
        elif unit in ('GHz', 'ghz'):
            self.rate.click()
            self.unit.setCurrentIndex(1)
        elif unit in ('THz', 'thz'):
            self.rate.click()
            self.unit.setCurrentIndex(2)
        elif unit in ('PHz', 'phz'):
            self.rate.click()
            self.unit.setCurrentIndex(3)
        else:
            error.showMessage('Invalid unit: {0}'.format(unit))

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

    def updateRate(self):
        '''Updates the rate of the text box'''
        # Do nothing if rate is not yet defined
        try:
            rate = self.model.rate
        except AttributeError:
            return
        if 0.1 > rate or rate > 100:
            self.rate_value.setText('{0:.3E}'.format(rate))
        else:
            self.rate_value.setText('{0:.3F}'.format(rate))

    def emitRate(self):
        '''Converts the text to a float and emits'''
        # Do nothing if there is no number
        try:
            self.model.setRate(float(self.rate_value.text()))
        except ValueError:
            pass

    def updateUnit(self):
        '''Update for a change of unit'''
        # If there is no unit yet, just set it
        try:
            unit = self.model.unit
        except AttributeError:
            self.model.setConverter(str(self.unit.currentText()))
            try:
                self.model.setRate(float(self.rate_value.text()))
            except ValueError:
                pass
            return
        # Convert unit appropriately
        if self.rate.isChecked():
            if unit == 'Hz':
                conv = { 'GHz' : 1E-9,
                         'THz' : 1E-12,
                         'PHz' : 1E-15 }
            elif unit == 'GHz':
                conv = { 'Hz'  : 1E9,
                         'THz' : 1E-3,
                         'PHz' : 1E-6 }
            elif unit == 'THz':
                conv = { 'Hz'  : 1E12,
                         'GHz' : 1E3,
                         'PHz' : 1E-3 }
            elif unit == 'PHz':
                conv = { 'Hz'  : 1E15,
                         'GHz' : 1E6,
                         'THz' : 1E3 }
            else:
                conv = { ''    : 1,
                         'Hz'  : 1, 
                         'GHz' : 1, 
                         'THz' : 1, 
                         'PHz' : 1, }
        else:
            if unit == 's':
                conv = { 'ns' : 1E9,
                         'ps' : 1E12,
                         'fs' : 1E15 }
            elif unit == 'ns':
                conv = { 's'  : 1E-9,
                         'ps' : 1E3,
                         'fs' : 1E6 }
            elif unit == 'ps':
                conv = { 's'  : 1E-12,
                         'ns' : 1E-3,
                         'fs' : 1E3 }
            elif unit == 'fs':
                conv = { 's'  : 1E-15,
                         'ns' : 1E-6,
                         'ps' : 1E-3 }
            else:
                conv = { ''   : 1,
                         's'  : 1, 
                         'ns' : 1, 
                         'ps' : 1, 
                         'fs' : 1, }
        try:
            # Set the new converter, then change the rate
            self.model.setConverter(str(self.unit.currentText()))
            try:
                self.model.setRate(float(self.rate_value.text())
                                 * conv[str(self.unit.currentText())])
            except ValueError:
                pass
        except KeyError:
            pass

        # Save the new unit
        self.model.unit = str(self.unit.currentText())

    def setRateModel(self):
        '''Change the model to use the rate'''
        if self.model.method == 'rate':
            return
        self.model.method = 'rate'
        indx = self.unit.currentIndex()
        self.unit.setModel(self.model.runits)
        self.model.unit = str(self.unit.itemText(indx))
        self.unit.setCurrentIndex(indx)
        self.model.setConverter(self.model.unit)
        try:
            self.model.setRate(1 / float(self.rate_value.text()))
        except (ZeroDivisionError, ValueError):
            pass

    def setLifetimeModel(self):
        '''Change the model to use the lifetime'''
        if self.model.method == 'lifetime':
            return
        self.model.method = 'lifetime'
        indx = self.unit.currentIndex()
        self.unit.setModel(self.model.lunits)
        self.model.unit = str(self.unit.itemText(indx))
        self.unit.setCurrentIndex(indx)
        self.model.setConverter(self.model.unit)
        try:
            self.model.setRate(1 / float(self.rate_value.text()))
        except (ZeroDivisionError, ValueError):
            pass
class OptionsContainer(QWidget):
    def __init__(self,main_window):
        QWidget.__init__(self)
        self.main_window = main_window
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        
        self.lr = numpy.zeros(2)
        
        self.fps = QSpinBox()
        self.fps.setValue(25)
        self.fps.setMinimum(1)
        self.fps.setMaximum(1000)
        self.layout.addWidget(QLabel("FPS:"),10,10)
        self.layout.addWidget(self.fps,10,11)
        
        self.capture_area_group = QButtonGroup()
        self.capture_area_fs = QRadioButton("Full Screen")
        self.connect(self.capture_area_fs, SIGNAL("clicked()"),self.capture_area_change)
        self.capture_area_fs.setChecked(True)
        self.capture_area_sa = QRadioButton("Selected Area")
        self.connect(self.capture_area_sa, SIGNAL("clicked()"),self.capture_area_change)
        self.capture_area_group.addButton(self.capture_area_fs)
        self.capture_area_group.addButton(self.capture_area_sa)
        self.capture_area_group.setExclusive(True)
        
        self.layout.addWidget(self.capture_area_fs,12,10)
        self.layout.addWidget(self.capture_area_sa,12,11)
        
        self.sa_group = QGroupBox()
        self.sa_grid = QGridLayout()
        self.sa_group.setLayout(self.sa_grid)
        
        
        self.sa_ul_bt = QPushButton("Select Upper Left")
        self.connect(self.sa_ul_bt, SIGNAL("clicked()"), self.select_ul)
        self.sa_lr_bt = QPushButton("Select Lower Right")
        self.connect(self.sa_lr_bt, SIGNAL("clicked()"), self.select_lr)

        self.sa_x = QSpinBox()
        self.sa_y = QSpinBox()
        self.sa_w = QSpinBox()
        self.sa_h = QSpinBox()
        for sb in [self.sa_h,self.sa_w,self.sa_x,self.sa_y]:
            sb.setMaximum(999999)
            sb.setMinimum(0)
        
        self.sa_grid.addWidget(self.sa_ul_bt,14,10,1,1)
        self.sa_grid.addWidget(self.sa_lr_bt,15,10,1,1)
        self.sa_grid.addWidget(QLabel("x"),14,11,1,1)
        self.sa_grid.addWidget(self.sa_x,14,12,1,1)
        self.sa_grid.addWidget(QLabel("y"),15,11,1,1)
        self.sa_grid.addWidget(self.sa_y,15,12,1,1)
        self.sa_grid.addWidget(QLabel("w"),16,11,1,1)
        self.sa_grid.addWidget(self.sa_w,16,12,1,1)
        self.sa_grid.addWidget(QLabel("h"),17,11,1,1)
        self.sa_grid.addWidget(self.sa_h,17,12,1,1)
        
        self.sa_show_bt = QPushButton("Show Area")
        self.sa_show_bt.setCheckable(True)
        self.connect(self.sa_show_bt, SIGNAL("clicked()"), self.show_selected_area)

        
        self.sa_grid.addWidget(self.sa_show_bt,18,10,1,10)
        
        self.sa_group.hide()
        
        self.layout.addWidget(self.sa_group,14,10,1,10)
        
        self.capture_delay = QSpinBox()
        self.capture_delay.setMinimum(0)
        self.capture_delay.setMaximum(10000)
        
        self.layout.addWidget(QLabel("Capture Delay"),18,10,1,1)
        self.layout.addWidget(self.capture_delay,18,11,1,1)
        
        self.capture_bt = QPushButton("Capture")
        self.stop_capture_bt = QPushButton("Stop")
        self.stop_capture_bt.hide()
        self.layout.addWidget(self.capture_bt,20,10,1,10)
        self.layout.addWidget(self.stop_capture_bt,30,10,1,10)
        
        self.ffmpeg_flags = QLineEdit()
        self.ffmpeg_flags.setText("-qscale 0 -vcodec mpeg4")
        self.layout.addWidget(QLabel("FFMPEG Flags:"),40,10)
        self.layout.addWidget(self.ffmpeg_flags,50,10,1,10)
        
        self.encode_bt = QPushButton("Encode Video")
        self.layout.addWidget(self.encode_bt,60,10,1,10)
        
        self.open_dir_bt = QPushButton("Open Directory")
        self.layout.addWidget(self.open_dir_bt,80,10,1,10)
        
        self.connect(self.open_dir_bt, SIGNAL("clicked()"),self.open_cwd)
    
        self.selected_area = SelectedArea()
    
    def show_selected_area(self):
        x = self.sa_x.value()
        y = self.sa_y.value()
        w = self.sa_w.value()
        h = self.sa_h.value()
        
        self.selected_area.setGeometry(x,y,w,h)
        self.selected_area.activateWindow()
        self.selected_area.raise_()
        if(self.sa_show_bt.isChecked()):
            self.selected_area.show()
        else:self.selected_area.hide()
        
    def select_ul(self):
        print "select_ul"
        self.clicked  = False
        self.tw = TransWindow()
        self.tw.mouse_press = False
        self.tw.show()
        
        self.connect(self.tw, SIGNAL("mouse_press()"),self.set_ul)
        
    def select_lr(self):
        print "select_lr"
        self.clicked  = False
        self.tw = TransWindow()
        self.tw.mouse_press = False
        self.tw.show()
        
        self.connect(self.tw, SIGNAL("mouse_press()"),self.set_lr)
    
    def set_ul(self):
        self.sa_x.setValue( self.tw.pos[0])       
        self.sa_y.setValue( self.tw.pos[1])
        self.sa_w.setValue( self.lr[0] - self.sa_x.value())       
        self.sa_h.setValue( self.lr[1] - self.sa_y.value())
        self.show_selected_area()
        
    
    def set_lr(self):
        self.lr = numpy.array([self.tw.pos[0],self.tw.pos[1]])
        self.sa_w.setValue( self.tw.pos[0] - self.sa_x.value())       
        self.sa_h.setValue( self.tw.pos[1] - self.sa_y.value())     
        self.show_selected_area()
        
    
    def capture_area_change(self):
        print "capture_area_change"
        if(self.capture_area_fs.isChecked()):
            self.sa_group.hide()
        else:
            self.sa_group.show()
            
        self.adjustSize()
        self.main_window.adjustSize()
    
    def open_cwd(self):
        #will need to detect os and change accordingly
        os.system("open {}".format(os.getcwd()))
Exemplo n.º 7
0
class ProfileFormWidget(QWidget):
    '''
    classdocs
    '''
    
    def __init__(self):
        '''
        Constructor
        '''
        QWidget.__init__(self)
        self._initGUI()
        
    def _initGUI(self):
        self.layout = QVBoxLayout()
        self.form = QFormLayout()
        
        self.name = QLineEdit()
        self.surname = QLineEdit()
        
        self.birthdate = QCalendarWidget()
        self.birthdate.setGridVisible(True)
        self.birthdate.setMinimumDate(QDate(1850,1,1))
        self.birthdate.setMaximumDate(QDate.currentDate())
        
        self.male = QRadioButton("Male")
        self.male.setChecked(True)
        self.female = QRadioButton("Female")
        
        self.height = QDoubleSpinBox()
        self.height.setMaximum(250)
        self.height.setMinimum(50)
        self.height.setValue(165)
        self.height.setSuffix(" cm")
        
        self.mass = QDoubleSpinBox()
        self.mass.setMaximum(300)
        self.mass.setMinimum(20)
        self.mass.setValue(60)
        self.mass.setSuffix(" Kg")
        
        btnLayout = QVBoxLayout()
        
        self.form.addRow("Name", self.name)
        self.form.addRow("Surname", self.surname)
        self.form.addRow("Birth date",self.birthdate)
        
        sexLayout = QHBoxLayout()
        sexLayout.addWidget(self.male)
        sexLayout.addWidget(self.female)
        self.form.addRow("Sex", sexLayout)
        
        self.form.addRow("Height", self.height)
        self.form.addRow("Mass", self.mass)
                
        self.layout.addLayout(self.form)
        self.layout.addLayout(btnLayout)
        self.setLayout(self.layout)
        
    def getLayout(self):
        return self.layout
    
    def getWidget(self):
        widget = QWidget()
        widget.setLayout(self.layout)
    
        return widget
    
    def setProfile(self, athlete):
        self.name.setText(athlete._name)
        self.surname.setText(athlete._surname)
        self.birthdate.setSelectedDate(athlete._birthDate)
        
        if athlete._sex=="Male":
            self.male.setChecked(True)
        else:
            self.female.setChecked(True)
            
        self.height.setValue(athlete._height)
        self.mass.setValue(athlete._mass)
                
    def getProfile(self):        
        qDate = self.birthdate.selectedDate()
        birthDate = self.qDate_to_date(qDate)
        
        athleteProfile = Athlete(self.name.text(),
                                 self.surname.text(),
                                 self._getSex(),
                                 birthDate,
                                 self.height.value(),
                                 self.mass.value())
        return athleteProfile 
    
    def qDate_to_date(self, qDate):        
        return date(qDate.year(), qDate.month(),qDate.day())
     
    def _getSex(self):
        if (self.male.isChecked()):
            return "Male"
        elif (self.female.isChecked()):
            return "Female"
        else :
            print "Error: No sex selected"
            return False
Exemplo n.º 8
0
class _DelimitedDetectorWidget(_DetectorWidget):

    def _initUI(self):
        # Widgets
        self._rb_delimited = QRadioButton('Delimited')
        self._rb_delimited.setChecked(False)

        self._lbl_elevation = QLabel("Elevation")
        self._lbl_elevation.setStyleSheet("color: blue")
        self._txt_elevation = _AngleRangeWidget(_DelimitedDetector.elevation_rad)
        self._txt_elevation.setEnabled(False)
        self._txt_elevation.setRequired(False)

        self._lbl_azimuth = QLabel('Azimuth')
        self._lbl_azimuth.setStyleSheet("color: blue")
        self._txt_azimuth = _AngleRangeWidget(_DelimitedDetector.azimuth_rad)
        self._txt_azimuth.setEnabled(False)
        self._txt_azimuth.setRequired(False)

        self._rb_annular = QRadioButton('Annular')
        self._rb_annular.setChecked(True)

        self._lbl_takeoffangle = QLabel('Take-off angle')
        self._lbl_takeoffangle.setStyleSheet("color: blue")
        param_takeoffangle = \
            AngleParameter(validators=range_validator(0.0, HALFPI),
                           doc='Take-off angle from the x-y plane')
        param_takeoffangle._name = 'takeoffangle'
        self._txt_takeoffangle = AngleParameterWidget(param_takeoffangle)

        self._lbl_opening = QLabel('Opening')
        self._lbl_opening.setStyleSheet("color: blue")
        param_opening = \
            AngleParameter(validators=range_validator(0.0, HALFPI, False),
                           doc='Opening angle from the take-off angle (above and below)')
        param_opening._name = 'opening'
        self._txt_opening = AngleParameterWidget(param_opening)

        # Layouts
        layout = _DetectorWidget._initUI(self)

        layout.addRow(self._rb_delimited)

        sublayout = QFormLayout()
        sublayout.setContentsMargins(10, 0, 0, 0)
        if sys.platform == 'darwin': # Fix for Mac OS
            sublayout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
        sublayout.addRow(self._lbl_elevation, self._txt_elevation)
        sublayout.addRow(self._lbl_azimuth, self._txt_azimuth)
        layout.addRow(sublayout)

        layout.addRow(self._rb_annular)

        sublayout = QFormLayout()
        sublayout.setContentsMargins(10, 0, 0, 0)
        if sys.platform == 'darwin': # Fix for Mac OS
            sublayout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
        sublayout.addRow(self._lbl_takeoffangle, self._txt_takeoffangle)
        sublayout.addRow(self._lbl_opening, self._txt_opening)
        layout.addRow(sublayout)

        # Signals
        self._rb_delimited.toggled.connect(self._onToggle)
        self._rb_annular.toggled.connect(self._onToggle)

        return layout

    def _onToggle(self):
        state = self._rb_delimited.isChecked()
        self._txt_elevation.setEnabled(state)
        self._txt_azimuth.setEnabled(state)
        self._txt_elevation.setRequired(state)
        self._txt_azimuth.setRequired(state)
        self._txt_takeoffangle.setEnabled(not state)
        self._txt_opening.setEnabled(not state)
        self._txt_takeoffangle.setRequired(not state)
        self._txt_opening.setRequired(not state)

    def _getElevationValues(self):
        if self._rb_delimited.isChecked():
            return self._txt_elevation.values()
        else:
            takeoffangles = self._txt_takeoffangle.values()
            openings = self._txt_opening.values()

            elevations = []
            for takeoffangle, opening in product(takeoffangles, openings):
                elevation = (takeoffangle - opening, takeoffangle + opening)
                elevations.append(elevation)

            return elevations

    def _getAzimuthValues(self):
        if self._rb_delimited.isChecked():
            return self._txt_azimuth.values()
        else:
            return [(0.0, TWOPI)]

    def setValue(self, value):
        self._rb_delimited.setChecked(True)
        self._txt_elevation.setValues(value.elevation_rad)
        self._txt_azimuth.setValues(value.azimuth_rad)
        self._txt_takeoffangle.setValues([])
        self._txt_opening.setValues([])

    def setReadOnly(self, state):
        _DetectorWidget.setReadOnly(self, state)
        style = 'color: none' if state else 'color: blue'
        self._rb_delimited.setEnabled(not state)
        self._rb_annular.setEnabled(not state)
        self._lbl_elevation.setStyleSheet(style)
        self._txt_elevation.setReadOnly(state)
        self._lbl_azimuth.setStyleSheet(style)
        self._txt_azimuth.setReadOnly(state)
        self._lbl_takeoffangle.setStyleSheet(style)
        self._txt_takeoffangle.setReadOnly(state)
        self._lbl_opening.setStyleSheet(style)
        self._txt_opening.setReadOnly(state)
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
class PostViewWidget(HorsePanel):
    def __init__(self, parent, order_overview_widget, find_order_slot):
        global configuration

        super(PostViewWidget, self).__init__(parent)

        self.set_panel_title(_("Post overview"))
        self.bold_font = QFont(self.font())
        self.bold_font.setBold(True)
        self.nb_cols = 8  # Number of columns in the operation definition table

        self.order_overview_widget = order_overview_widget

        self.button = QPushButton(_("Refresh"), self)
        self.button.clicked.connect(self.refresh_action)
        self.sort_by_deadline_button = QRadioButton(_("By deadline"), self)
        self.sort_by_deadline_button.toggled.connect(self.sort_by_deadline)
        self.sort_by_size_button = QRadioButton(_("By hours left to do"), self)
        self.sort_by_size_button.toggled.connect(self.sort_by_size)

        # hlayout = QHBoxLayout()
        # hlayout.setObjectName("halyout")
        # hlayout.setContentsMargins(0,0,0,0)
        # hlayout.addWidget(self.sort_by_deadline_button)
        # hlayout.addWidget(self.sort_by_size_button)
        # hlayout.addWidget(self.button)
        # hlayout.addStretch()

        self.navbar = NavBar(self, [(self.sort_by_deadline_button, None),
                                    (self.sort_by_size_button, None),
                                    (self.button, None),
                                    (_("Find"), find_order_slot)])
        self.navbar.buttons[3].setObjectName("specialMenuButton")

        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(
            TitleWidget(_("Posts Overview"), self, self.navbar))

        self._table_model = QStandardItemModel(1, self.nb_cols, self)
        self.table_view = QTableView(None)
        self.table_view.setModel(self._table_model)
        self.table_view.selectionModel().currentChanged.connect(
            self.operation_selected)

        self.table_view.verticalHeader().hide()
        self.table_view.horizontalHeader().hide()
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        # This forces Qt to expand layout once I fill data in
        # FIXME dirty but I really don't get why setting
        # the mini width to something smaller (that happens at
        # startup, on first refresh) doesn't work
        self.table_view.setMinimumWidth(1)
        self.table_view.setMaximumWidth(1)

        self.post_view_scene = PostViewScene(self, order_overview_widget)
        self.post_view_scene_view = QGraphicsView(self)
        self.post_view_scene_view.setScene(self.post_view_scene)
        self.post_view_scene_view.setSizePolicy(QSizePolicy.Expanding,
                                                QSizePolicy.Expanding)

        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(
            SubFrame(_("Posts"), self.table_view, self.splitter))
        self.splitter.addWidget(
            SubFrame(_("Workload"), self.post_view_scene_view, self.splitter))
        # self.splitter.setStretchFactor(0,1)
        self.splitter.setStretchFactor(1, 1)
        self.vlayout.addWidget(self.splitter)

        # hlayout = QHBoxLayout()
        # hlayout.addWidget(SubFrame(_("Posts"),self.table_view,self))
        # hlayout.addWidget(SubFrame(_("Workload"),self.post_view_scene_view,self))
        # hlayout.setStretch(1,1)
        # self.vlayout.addLayout(hlayout)

        self.vlayout.setStretch(0, 0)
        self.vlayout.setStretch(1, 1)

        self.setLayout(self.vlayout)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.slidePostsScene)

        self.current_view_y = 0

    def _data_load(self):
        global dao

        all_operations = dao.operation_dao.load_all_operations_ready_for_production(
        )
        operation_definitions = dao.operation_definition_dao.all_direct_frozen(
        )

        return operation_definitions, all_operations

    def _reset_operation_definitions(self, operations):
        self._table_model.setColumnCount(1)
        self._table_model.setRowCount(len(operations))

        # BUG This should be refreshed on reload() too

        row = col = 0
        first_active = None

        for opdef in operations:

            if opdef.operation_definition_id in self.post_view_scene.drawn_operations_data:
                # currently total planned time
                t = self.post_view_scene.drawn_operations_data[
                    opdef.operation_definition_id]
                ndx = self._table_model.index(row, col)
                if not first_active:
                    first_active = ndx
                self._table_model.setData(
                    ndx, u"{} {}".format(opdef.description, t), Qt.DisplayRole)
                # self._table_model.setData(ndx,self.bold_font,Qt.FontRole)

                self._table_model.setData(self._table_model.index(row, col),
                                          opdef.operation_definition_id,
                                          Qt.UserRole)
                row += 1

            else:
                pass
                # self._table_model.setData(self._table_model.index(row,col),opdef.description,Qt.DisplayRole)

            # = col + 1
            # if col == self.nb_cols:
            #     col = 0
            #     row += 1

        self._table_model.setRowCount(row)

        # self.table_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.vlayout.setStretch(0,0)
        # self.vlayout.setStretch(1,10)
        # self.vlayout.setStretch(2,10000)

        # height = 0
        # for c in range(self.table_view.model().rowCount()):
        #     height += self.table_view.rowHeight(c) + 1 # +1 for cell border
        # self.table_view.setMinimumHeight(height)
        # self.table_view.setMaximumHeight(height)
        for i in range(self.nb_cols):
            self.table_view.resizeColumnToContents(i)
        self.table_view.setMaximumWidth(self.table_view.columnWidth(0))
        self.table_view.setMinimumWidth(self.table_view.columnWidth(0))
        self.table_view.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Preferred)

        self.table_view.update()
        self.splitter.update()

        return first_active

    def slide_to_operation(self, opdef_id):
        if opdef_id in self.post_view_scene.posts_offsets:
            self.slide_target_opdef_id = opdef_id
            # mainlog.debug("Target y = {}".format(self.post_view_scene.posts_offsets[self.slide_target_opdef]))
            self.timer.start(20)

    @Slot()
    def slidePostsScene(self):
        if self.slide_target_opdef_id is None:
            return

        # self.post_view_scene_view
        self.post_view_scene.set_cursor_on(
            self.slide_target_opdef_id
        )  # This done here also aviod some screen trashing

        v = self.post_view_scene_view.verticalScrollBar().value()
        # mainlog.debug( "slidePostsScene : {}".format(v))

        r = self.post_view_scene.posts_offsets[self.slide_target_opdef_id]
        target_y = r.y() + r.height() / 2
        delta = (target_y - self.current_view_y) * 0.4
        self.current_view_y = self.current_view_y + delta
        self.post_view_scene_view.centerOn(0, self.current_view_y)
        # mainlog.debug( "slidePostsScene : {} / {}".format(target_y, self.current_view_y))

        if self.post_view_scene_view.verticalScrollBar().value() == v:
            # Close enough => stop moving
            # FIXME not correct because we must stop when the view stops moving, not when the goal we set for centerOn is reached
            self.timer.stop()

    @Slot(QModelIndex, QModelIndex)
    def operation_selected(self, ndx_cur, ndx_old):
        if ndx_cur.isValid():
            opdef = self._table_model.data(ndx_cur, Qt.UserRole)
            if opdef:
                self.slide_to_operation(
                    self._table_model.data(ndx_cur, Qt.UserRole))

    @Slot()
    def refresh_action(self):
        # FIXME reload operations as well

        operation_definitions, all_operations = self._data_load()

        # mainlog.debug("reload")
        if self.sort_by_deadline_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 1)
        elif self.sort_by_size_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 2)
        else:
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 0)

        # mainlog.debug("reset")
        first_active = self._reset_operation_definitions(operation_definitions)
        # self.table_view.selectionModel().currentChanged.connect(self.operation_selected)
        if first_active:
            self.table_view.setCurrentIndex(first_active)

        # mainlog.debug("done reset")

    @Slot(bool)
    def sort_by_deadline(self, checked):
        if checked:
            self.refresh_action()

    @Slot(bool)
    def sort_by_size(self, checked):
        if checked:
            self.refresh_action()

    order_part_double_clicked = Signal(int)

    # Callback that will be called by HooverBar
    def set_on_order_part(self, order_part_id):
        self.order_part_double_clicked.emit(order_part_id)
Exemplo n.º 12
0
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("Move Entry — {}".format(
            QApplication.applicationName()))
        self.message = None
        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("Move ")
        self.termLabel = Widgets.Label.HtmlLabel("“{}”".format(
            Lib.elidePatchHtml(self.selectedEntry.term, self.state)))

        self.eidGroup = QGroupBox()

        parentEid = self.selectedEntry.peid
        self.moveToTopRadioButton = QRadioButton("to be a &Main Entry")
        self.grandParentEntry = None
        grandParentEid = None
        if parentEid != ROOT:
            grandParentEid = self.state.model.parentOf(parentEid)
            if grandParentEid != ROOT:
                self.grandParentEntry = self.state.model.entry(grandParentEid)
        self.grandParentRadioButton = QRadioButton("up under &Grandparent")

        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>Move the current entry under a recently visited entry.</p>"""))

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

        self.moveToTopRadioButton.setEnabled(parentEid != ROOT)
        self.moveToTopRadioButton.setChecked(parentEid != ROOT)
        seen = {selectedEid, self.selectedEntry.peid}
        self.buttons = (self.moveToTopRadioButton, self.grandParentRadioButton,
                        self.filteredRadioButton, self.circledRadioButton,
                        self.recentRadioButton)
        Forms.Util.setUpRadioButton(
            self, self.grandParentEntry, self.grandParentRadioButton,
            self.grandParentLabel, self.buttons, seen,
            """<p><b>under Grandparent</b></p>
<p>Move the current entry up under its grandparent “{}”.</p>""")
        Forms.Util.setUpRadioButton(
            self, self.filteredEntry, self.filteredRadioButton,
            self.filteredLabel, self.buttons, seen,
            """<p><b>under Filtered</b></p>
<p>Move 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>Move the current entry under the circled entry “{}”.</p>""")
        self.recentComboBox = Forms.Util.createTermsComboBox(
            self.state, self.state.gotoEids, ignore=seen, maximum=MAX_RECENT)
        if self.recentComboBox.count() and all(not radio.isChecked()
                                               for radio in self.buttons):
            self.recentRadioButton.setChecked(True)
            self.recentComboBox.setFocus()

        self.buttonBox = QDialogButtonBox()
        self.moveButton = QPushButton(QIcon(":/move.svg"), "M&ove")
        self.tooltips.append((self.moveButton, """<p><b>Move</b></p>
<p>Move the “{}” entry.</p>""".format(self.termLabel.text())))
        self.buttonBox.addButton(self.moveButton, 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 Move 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.moveToTopRadioButton)
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.addWidget(self.grandParentRadioButton)
        hbox.addWidget(self.grandParentLabel, 1)
        eidLayout.addLayout(hbox)
        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)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.buttonBox.accepted.connect(self.move)
        self.buttonBox.rejected.connect(self.reject)
        self.helpButton.clicked.connect(self.help)
        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())
        self.moveButton.setEnabled(
            any(button.isChecked() for button in self.buttons))

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

    def move(self):
        self.state.maybeSave()
        eid = self.selectedEntry.eid
        if self.moveToTopRadioButton.isChecked():
            self.state.model.moveToTop(eid)
        else:
            peid = None
            if self.grandParentRadioButton.isChecked():
                peid = self.grandParentEntry.eid
                message = "move up"
            elif self.filteredRadioButton.isChecked():
                peid = self.filteredEntry.eid
                message = "move under filtered"
            elif self.circledRadioButton.isChecked():
                peid = self.circledEntry.eid
                message = "move under circled"
            elif self.recentRadioButton.isChecked():
                peid = self.recentComboBox.itemData(
                    self.recentComboBox.currentIndex())
                message = "move under recently visited"
            if peid is not None:  # Should always be True
                self.state.model.moveUnder(eid, peid, message)
                term = Lib.htmlToPlainText(self.state.model.term(eid))
                if peid == ROOT:
                    message = "Moved “{}” to be a main entry".format(term)
                else:
                    message = "Moved “{}” under “{}”".format(
                        term, Lib.htmlToPlainText(self.state.model.term(peid)))
                say(message, SAY_TIMEOUT)
        self.accept()
Exemplo n.º 13
0
class Form(QDialog):
    def __init__(self, state, parent=None):
        super().__init__(parent)
        Lib.prepareModalDialog(self)
        self.state = state
        self.setWindowTitle("Add Cross-reference — {}".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.entry1Label = QLabel("cross-reference from ")
        self.termLabel = Widgets.Label.HtmlLabel("“{}”".format(
            Lib.elidePatchHtml(self.selectedEntry.term, self.state)))
        self.entry2Label = QLabel(" to")
        self.seeRadioButton = QRadioButton("&See")
        self.seeRadioButton.setChecked(True)
        self.tooltips.append((self.seeRadioButton, """<p><b>See</b></p>
<p>Check to create a <i>see</i> cross-reference.</p>"""))
        self.alsoRadioButton = QRadioButton("See &Also")
        self.tooltips.append((self.alsoRadioButton, """<p><b>See
Also</b></p>
<p>Check to create a <i>see also</i> cross-reference.</p>"""))
        self.whichGroup = QGroupBox("Add")
        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("&Filtered")
        self.circledRadioButton = QRadioButton("C&ircled")
        self.recentRadioButton = QRadioButton("&Recent")
        self.tooltips.append((self.recentRadioButton, """<p><b>Recent</b></p>
<p>Create a cross-reference to a recently visited entry.</p>"""))
        self.filteredLabel = Widgets.Label.HtmlLabel()
        self.circledLabel = Widgets.Label.HtmlLabel()
        seen = {selectedEid}
        buttons = (self.filteredRadioButton, self.circledRadioButton,
                   self.recentRadioButton)
        Forms.Util.setUpRadioButton(
            self, self.filteredEntry, self.filteredRadioButton,
            self.filteredLabel, buttons, seen, """<p><b>Filtered</b></p>
<p>Create a cross-reference to the filtered entry “{}”.</p>""")
        Forms.Util.setUpRadioButton(
            self, self.circledEntry, self.circledRadioButton,
            self.circledLabel, buttons, seen, """<p><b>Circled</b></p>
<p>Create a cross-reference to the circled entry “{}”.</p>""")
        self.recentComboBox = Forms.Util.createTermsComboBox(
            self.state, self.state.gotoEids, ignore=seen, maximum=MAX_RECENT)
        self.groupRadioButton = QRadioButton("All in &Group")
        self.groupComboBox = QComboBox()
        for i, (gid, name, linked) in enumerate(self.state.model.allGroups()):
            self.groupComboBox.addItem(
                QIcon(":/grouplink.svg" if linked else ":/groups.svg"), name,
                gid)
        if not self.groupComboBox.count():
            self.groupRadioButton.setEnabled(False)
            self.groupComboBox.setEnabled(False)
        self.eidGroup = QGroupBox()
        self.genericTermRadioButton = QRadioButton("Generic &Term")
        self.tooltips.append((self.genericTermRadioButton, """\
<p><b>Generic Term</b></p>
<p>Create a cross-reference to the given generic term.</p>"""))
        self.genericTermLineEdit = EnableOnClickLineEdit(
            self.state, self.genericTermRadioButton, self)
        self.tooltips.append((self.genericTermLineEdit, """\
<p><b>Generic Term text</b></p>
<p>The generic term text styled (e.g., <b>bold</b>, <i>italic</i>), as
it should appear in the final index.</p>"""))
        self.formatPanel = Widgets.FormatPanel.Panel(self.state, self)
        self.formatPanel.state.editors = [self.genericTermLineEdit]
        self.formatActions = self.formatPanel.formatActions
        self.buttonBox = QDialogButtonBox()
        self.addButton = QPushButton(QIcon(":/xref-add.svg"), "A&dd")
        self.tooltips.append((self.addButton, """<p><b>Add</b></p>
<p>Add the specified cross-reference to the <b>Entry</b> {}.</p>""".format(
            self.termLabel.text())))
        self.buttonBox.addButton(self.addButton, 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 Add Cross-reference dialog"))
        self.buttonBox.addButton(self.helpButton, QDialogButtonBox.HelpRole)
        if (not self.filteredRadioButton.isChecked()
                and not self.circledRadioButton.isChecked()):
            if self.recentComboBox.count():
                self.recentRadioButton.setChecked(True)
            else:
                self.genericTermRadioButton.setChecked(True)
                self.genericTermLineEdit.setFocus()

    def layoutWidgets(self):
        layout = QVBoxLayout()
        whichLayout = QHBoxLayout()
        whichLayout.addWidget(self.seeRadioButton)
        whichLayout.addWidget(self.alsoRadioButton)
        whichLayout.addStretch()
        self.whichGroup.setLayout(whichLayout)
        layout.addWidget(self.whichGroup)
        entryLayout = QHBoxLayout()
        entryLayout.setSpacing(0)
        entryLayout.addWidget(self.entry1Label)
        entryLayout.addWidget(self.termLabel)
        entryLayout.addWidget(self.entry2Label)
        entryLayout.addStretch()
        layout.addLayout(entryLayout)
        eidLayout = QVBoxLayout()
        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)
        hbox = QHBoxLayout()
        hbox.addWidget(self.groupRadioButton)
        hbox.addWidget(self.groupComboBox, 1)
        eidLayout.addLayout(hbox)
        grid = QGridLayout()
        grid.addWidget(self.formatPanel, 0, 0, 1, 2, Qt.AlignRight)
        grid.addWidget(self.genericTermRadioButton, 1, 0)
        grid.addWidget(self.genericTermLineEdit, 1, 1)
        eidLayout.addLayout(grid)
        eidLayout.addStretch()
        self.eidGroup.setLayout(eidLayout)
        layout.addWidget(self.eidGroup)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def createConnections(self):
        self.buttonBox.accepted.connect(self.addXRef)
        self.buttonBox.rejected.connect(self.reject)
        self.helpButton.clicked.connect(self.help)
        self.filteredRadioButton.clicked.connect(self.updateUi)
        self.circledRadioButton.clicked.connect(self.updateUi)
        self.recentRadioButton.clicked.connect(self.updateUi)
        self.recentRadioButton.toggled.connect(self.moveFocus)
        self.recentComboBox.currentIndexChanged[int].connect(
            self.recentChanged)
        self.groupRadioButton.clicked.connect(self.updateUi)
        self.groupRadioButton.toggled.connect(self.moveFocus)
        self.groupComboBox.currentIndexChanged[int].connect(self.groupChanged)
        self.genericTermRadioButton.clicked.connect(self.updateUi)
        self.genericTermRadioButton.clicked.connect(
            self.genericTermLineEdit.setFocus)
        self.genericTermLineEdit.textChanged.connect(self.updateUi)
        self.genericTermLineEdit.enterPressed.connect(self.maybeAdd)

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

    def groupChanged(self):
        self.groupRadioButton.setChecked(True)
        self.updateUi()

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

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

    def updateUi(self):
        enable = (self.genericTermRadioButton.isChecked()
                  or (self.groupRadioButton.isChecked()
                      and self.groupComboBox.count()))
        for widget in (self.genericTermLineEdit, self.formatPanel):
            widget.setEnabled(enable)
        self.recentRadioButton.setEnabled(self.recentComboBox.count())
        self.recentComboBox.setEnabled(self.recentComboBox.count())
        enable = True
        if (self.filteredRadioButton.isChecked()
                and self.filteredEntry is None):
            enable = False
        if (self.circledRadioButton.isChecked() and self.circledEntry is None):
            enable = False
        if (self.recentRadioButton.isChecked()
                and self.recentComboBox.currentIndex() < 0):
            enable = False
        if (self.groupRadioButton.isChecked()
                and not self.groupComboBox.count()):
            enable = False
        if (self.genericTermRadioButton.isChecked()
                and self.genericTermLineEdit.isEmpty()):
            enable = False
        self.addButton.setEnabled(enable)

    def maybeAdd(self):
        if (self.genericTermRadioButton.isChecked()
                and not self.genericTermLineEdit.isEmpty()):
            self.addXRef()

    def addXRef(self):
        from_eid = self.selectedEntry.eid
        assert from_eid is not None
        kind = (XrefKind.SEE
                if self.seeRadioButton.isChecked() else XrefKind.SEE_ALSO)
        if self.groupRadioButton.isChecked():
            gid = int(
                self.groupComboBox.itemData(self.groupComboBox.currentIndex()))
            for to_eid in tuple(self.state.model.eidsForGid(gid)):
                self.state.model.addXRef(from_eid, to_eid, kind)
        elif not self.genericTermRadioButton.isChecked():
            to_eid = None
            if self.filteredRadioButton.isChecked():
                to_eid = self.filteredEntry.eid
            elif self.circledRadioButton.isChecked():
                to_eid = self.circledEntry.eid
            elif self.recentRadioButton.isChecked():
                to_eid = self.recentComboBox.itemData(
                    self.recentComboBox.currentIndex())
            assert to_eid is not None
            self.state.model.addXRef(from_eid, to_eid, kind)
        else:
            term = self.genericTermLineEdit.toHtml()
            kind = (XrefKind.SEE_GENERIC if self.seeRadioButton.isChecked()
                    else XrefKind.SEE_ALSO_GENERIC)
            self.state.model.addGenericXRef(from_eid, term, kind)
        say("Added cross-reference", SAY_TIMEOUT)
        self.accept()