def loadListForFindingType(self, findingType): model = QSqlRelationalTableModel(self, self.dbm.db) model.setTable(u"befundart") model.removeColumn(0) model.setFilter( u"befundart = '{0}' AND befundart_detail IS NOT NULL".format( findingType)) model.select() if model.rowCount() < 1: QMessageBox.warning( self, "Result", u"Für die Befundart '{0}' wurden keine Detail Einträge gefunden." .format(findingType)) return False self.uiFindingTypeDetailTableV.setModel(model) self.uiFindingTypeDetailTableV.setSelectionBehavior( QAbstractItemView.SelectRows) self.uiFindingTypeDetailTableV.verticalHeader().setVisible(False) self.uiFindingTypeDetailTableV.hideColumn(0) if findingType != "Siedlung": self.uiFindingTypeDetailTableV.hideColumn(2) #self.uiRemarksTableV.model().insertColumn(0) self.uiFindingTypeDetailTableV.resizeRowsToContents() self.uiFindingTypeDetailTableV.resizeColumnsToContents() self.uiFindingTypeDetailTableV.horizontalHeader( ).setStretchLastSection(True) self.uiFindingTypeDetailTableV.selectionModel( ).selectionChanged.connect(self.generateFindingTypeDetail) return True
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setTable() self.setLayout() self.setCentralWidget(self.widget) self.resize(600,400) def setTable(self): self.search = QLineEdit() self.search.textChanged.connect(self.setFilter) self.table = QTableView() self.model = QSqlRelationalTableModel(db=db) self.model.setTable('album') self.table.setModel(self.model) index = self.model.fieldIndex("Title") self.model.setSort(index, Qt.DescendingOrder) self.model.setRelation(2, QSqlRelation("artist", "ArtistId","Name")) self.model.select() def setLayout(self): self.layout = QVBoxLayout() self.layout.addWidget(self.search) self.layout.addWidget(self.table) self.widget = QWidget() self.widget.setLayout(self.layout) def setFilter(self, word): filterLastName = f'Name LIKE "%{word}%"' self.model.setFilter(filterLastName)
def openSearchFilmDialog(self): """Run method that performs all the real work""" # show the dialog self.searchFilmDlg.show() #self.filmSelectionDlg.uiFilmNumberEdit.setFocus() # Run the dialog event loop and See if OK was pressed if self.searchFilmDlg.exec_(): # QMessageBox.warning(None, "FilmNumber", self.searchFilmDlg.generateSearchQuery()) model = QSqlRelationalTableModel(self, self.dbm.db) model.setTable("film") searchMode, searchFilter = self.searchFilmDlg.generateSearchFilter() # QMessageBox.information(self, "info", searchFilter) model.setFilter(searchFilter) model.select() rc = model.rowCount() while (model.canFetchMore()): model.fetchMore() rc = model.rowCount() query = QSqlQuery(self.dbm.db) searchQuery = "select filmnummer, substr(filmnummer, 3, 8) as 'ohne_hersteller', flugdatum, anzahl_bilder, weise, art_ausarbeitung, militaernummer, militaernummer_alt from film where {0}".format(searchFilter) query.exec_(searchQuery) querySize = 0 while(query.next()): querySize += 1 query.seek(-1) # if model.rowCount(): if querySize > 0: # open film selection list dialog searchListDlg = APISFilmSelectionList(self.iface, model, self.dbm, self.imageRegistry, parent=self) searchListDlg.uiFilmCountLbl.setText(str(rc)) searchListDlg.uiFilmCountDescriptionLbl.setText(u"Film gefunden" if model.rowCount() == 1 else u"Filme gefunden") searchListDlg.uiFilmSearchModeLbl.setText(searchMode) res = searchListDlg.loadFilmListBySqlQuery(query) if res and searchListDlg.exec_(): #QMessageBox.warning(None, "FilmNumber", unicode(searchListDlg.filmNumberToLoad)) self.loadRecordByKeyAttribute("filmnummer", searchListDlg.filmNumberToLoad) else: QMessageBox.warning(self, u"Film Suche", u"Keine Ergebnisse mit den angegebenen Suchkriterien.") self.openSearchFilmDialog()
class MainWindow(QMainWindow): def __init__(self): super().__init__() container = QWidget() layout = QVBoxLayout() self.search = QLineEdit() self.search.textChanged.connect(self.update_filter) self.table = QTableView() layout.addWidget(self.search) layout.addWidget(self.table) container.setLayout(layout) self.model = QSqlRelationalTableModel(db=db) self.table.setModel(self.model) self.model.setTable("Track") self.model.setRelation(2, QSqlRelation("Album", "AlbumId", "Title")) self.model.setRelation(3, QSqlRelation("MediaType", "MediaTypeId", "Name")) self.model.setRelation(4, QSqlRelation("Genre", "GenreId", "Name")) delegate = QSqlRelationalDelegate(self.table) self.table.setItemDelegate(delegate) self.model.select() self.setMinimumSize(QSize(1024, 600)) self.setCentralWidget(container) def update_filter(self, s): s = re.sub("[\W]+", "", s) filter_str = 'Name LIKE "%{}%"'.format(s) self.model.setFilter(filter_str)
class StampTableWidget(StampTableView): addStampSignal = pyqtSignal(str) # deleteStampSignal = pyqtSignal() surveyModeSignal = pyqtSignal(bool) def __init__(self): super().__init__() self.hasSelection = False # todo self.surveyDatetime = None # init table model self.stampTableModel = QSqlRelationalTableModel() self.stampTableModel.setTable(R.tableName) self.stampTableModel.setEditStrategy(QSqlTableModel.OnFieldChange) self.stampTableModel.setFilter("survey_datetime = None") self.stampTableModel.select() self.stampTableView.setModel(self.stampTableModel) self.stampTableSelectionModel = self.stampTableView.selectionModel() self.stampTableSelectionModel.selectionChanged.connect( self.onStampSelectionChange) # connect buttons self.addStampButton.clicked.connect( lambda ignore, key="-": self.addStampSignal.emit(key)) self.deleteStampButton.clicked.connect(self.deleteButtonAction) self.hotkeyButton.clicked.connect(self.enableHotkeys) # self.recordButton.clicked.connect(self.surveyMode) # hotkeys self.hotkeys = self.initHotkeys() # copy selection to clipboard self.installEventFilter(self) def eventFilter(self, source, event): if (event.type() == QEvent.KeyPress and event.matches(QKeySequence.Copy)): self.copySelection() return True return super().eventFilter(source, event) def copySelection(self): selection = self.stampTableView.selectedIndexes() if selection: rows = sorted(index.row() for index in selection) columns = sorted(index.column() for index in selection) rowcount = rows[-1] - rows[0] + 1 colcount = columns[-1] - columns[0] + 1 table = [[''] * colcount for _ in range(rowcount)] for index in selection: row = index.row() - rows[0] column = index.column() - columns[0] table[row][column] = index.data() stream = io.StringIO() csv.writer(stream).writerows(table) QApplication.clipboard().setText(stream.getvalue()) def initHotkeys(self): keyList = [] shortcut = QShortcut( QKeySequence(Qt.Key_Space, QKeySequence.NativeText), self) keyList.append(shortcut) shortcut.activated.connect( lambda key="-": self.addStampSignal.emit(key)) for i in range(0, 10): print(i) shortcut = QShortcut(QKeySequence(str(i), QKeySequence.NativeText), self) keyList.append(shortcut) shortcut.activated.connect( lambda key=str(i): self.addStampSignal.emit(key)) return keyList def enableHotkeys(self, isClicked): for shortcut in self.hotkeys: shortcut.setEnabled(isClicked) def onDeselection(self): self.enableHotkeys(False) self.hotkeyButton.setChecked(False) # TODO delete def testHotKey(self, key): print("test") print(key) # TODO maybe repaint def loadSurveyStamps(self, keys): print("LSS") self.surveyDatetime = keys[0] filter = self.createFilter(keys) self.stampTableModel.setFilter(filter) self.stampTableModel.select() print("survey_datetime = " + self.surveyDatetime) QApplication.processEvents() self.repaint() def createFilter(self, keys): filter = "survey_datetime = \"" + self.surveyDatetime + "\"" for i in range(1, len(keys)): filter = filter + " OR survey_datetime = \"" + keys[i] + "\"" print(filter) return filter @pyqtSlot() def deleteButtonAction(self): for row in self.stampTableSelectionModel.selectedRows(): self.stampTableModel.removeRow(row.row()) self.stampTableSelectionModel.clearSelection() self.stampTableModel.select() QApplication.processEvents() def clearSurveyStamps(self): self.surveyDatetime = None # self.stampTableModel.setFilter("") # TODO will this work? self.stampTableModel.setFilter("survey_datetime = None") print("survey_datetime = None") def addStamp(self, stamp, key="-"): stampRecord = StampRecord(miliseconds=stamp, surveyDatetime=self.surveyDatetime, label=key, note="") sqlRecord = stampRecord.getQSQLRecord(self.stampTableModel.record()) self.stampTableModel.insertRecord(0, sqlRecord) # self.surveyWidget.sortByKey() # self.surveyWidget.select(0) QApplication.processEvents() # allow for selection highlight def addRecord(self, stampRecord): sqlRecord = stampRecord.getQSQLRecord(self.stampTableModel.record()) print(self.stampTableModel.insertRowIntoTable(sqlRecord)) # self.repaint() # TODO # self.surveyModeSignal.emit(modeOn) # @pyqtSlot(bool) # def enableSurvey(self, canSurvey): # print(canSurvey) # self.recordButton.setEnabled(canSurvey) @pyqtSlot() def testButtonAction(self): print("Test") @pyqtSlot(bool) def surveyMode(self, modeOn): self.addStampButton.setEnabled(modeOn) self.hotkeyButton.setEnabled(modeOn) self.enableHotkeys(self.hotkeyButton.isChecked()) @pyqtSlot(QItemSelection) def onStampSelectionChange(self, selection): self.hasSelection = selection.count() > 0 self.deleteStampButton.setEnabled(self.hasSelection) @pyqtSlot(bool) def enableStamps(self, modeOn): self.addStampButton.setEnabled(modeOn) self.hotkeyButton.setEnabled(modeOn) if not modeOn and self.hotkeyButton.isChecked(): self.hotkeyButton.setChecked(False) self.enableHotkeys(False)
class MainForm(QDialog): def __init__(self): super(MainForm, self).__init__() self.assetModel = QSqlRelationalTableModel(self) self.assetModel.setTable("assets") self.assetModel.setRelation(CATEGORYID, QSqlRelation("categories", "id", "name")) self.assetModel.setSort(ROOM, Qt.AscendingOrder) self.assetModel.setHeaderData(ID, Qt.Horizontal, "ID") self.assetModel.setHeaderData(NAME, Qt.Horizontal, "Name") self.assetModel.setHeaderData(CATEGORYID, Qt.Horizontal, "Category") self.assetModel.setHeaderData(ROOM, Qt.Horizontal, "Room") self.assetModel.select() self.assetView = QTableView() self.assetView.setModel(self.assetModel) self.assetView.setItemDelegate(AssetDelegate(self)) self.assetView.setSelectionMode(QTableView.SingleSelection) self.assetView.setSelectionBehavior(QTableView.SelectRows) self.assetView.setColumnHidden(ID, True) self.assetView.resizeColumnsToContents() assetLabel = QLabel("A&ssets") assetLabel.setBuddy(self.assetView) self.logModel = QSqlRelationalTableModel(self) self.logModel.setTable("logs") self.logModel.setRelation(ACTIONID, QSqlRelation("actions", "id", "name")) self.logModel.setSort(DATE, Qt.AscendingOrder) self.logModel.setHeaderData(DATE, Qt.Horizontal, "Date") self.logModel.setHeaderData(ACTIONID, Qt.Horizontal, "Action") self.logModel.select() self.logView = QTableView() self.logView.setModel(self.logModel) self.logView.setItemDelegate(LogDelegate(self)) self.logView.setSelectionMode(QTableView.SingleSelection) self.logView.setSelectionBehavior(QTableView.SelectRows) self.logView.setColumnHidden(ID, True) self.logView.setColumnHidden(ASSETID, True) self.logView.resizeColumnsToContents() self.logView.horizontalHeader().setStretchLastSection(True) logLabel = QLabel("&Logs") logLabel.setBuddy(self.logView) addAssetButton = QPushButton("&Add Asset") deleteAssetButton = QPushButton("&Delete Asset") addActionButton = QPushButton("Add A&ction") deleteActionButton = QPushButton("Delete Ac&tion") editActionsButton = QPushButton("&Edit Actions...") editCategoriesButton = QPushButton("Ed&it Categories...") quitButton = QPushButton("&Quit") for button in (addAssetButton, deleteAssetButton, addActionButton, deleteActionButton, editActionsButton, editCategoriesButton, quitButton): if MAC: button.setDefault(False) button.setAutoDefault(False) else: button.setFocusPolicy(Qt.NoFocus) dataLayout = QVBoxLayout() dataLayout.addWidget(assetLabel) dataLayout.addWidget(self.assetView, 1) dataLayout.addWidget(logLabel) dataLayout.addWidget(self.logView) buttonLayout = QVBoxLayout() buttonLayout.addWidget(addAssetButton) buttonLayout.addWidget(deleteAssetButton) buttonLayout.addWidget(addActionButton) buttonLayout.addWidget(deleteActionButton) buttonLayout.addWidget(editActionsButton) buttonLayout.addWidget(editCategoriesButton) buttonLayout.addStretch() buttonLayout.addWidget(quitButton) layout = QHBoxLayout() layout.addLayout(dataLayout, 1) layout.addLayout(buttonLayout) self.setLayout(layout) #self.connect(self.assetView.selectionModel(), #SIGNAL(("currentRowChanged(QModelIndex,QModelIndex)")), #self.assetChanged) self.assetView.selectionModel().currentRowChanged.connect( self.assetChanged) addAssetButton.clicked.connect(self.addAsset) deleteAssetButton.clicked.connect(self.deleteAsset) addActionButton.clicked.connect(self.addAction) deleteActionButton.clicked.connect(self.deleteAction) editActionsButton.clicked.connect(self.editActions) editCategoriesButton.clicked.connect(self.editCategories) quitButton.clicked.connect(self.done) self.assetChanged(self.assetView.currentIndex()) self.setMinimumWidth(650) self.setWindowTitle("Asset Manager") def done(self, result=1): query = QSqlQuery() query.exec_("DELETE FROM logs WHERE logs.assetid NOT IN" "(SELECT id FROM assets)") QDialog.done(self, 1) def assetChanged(self, index): if index.isValid(): record = self.assetModel.record(index.row()) #print(index.row()) id = record.value("id") self.logModel.setFilter("assetid = {0}".format(id)) else: self.logModel.setFilter("assetid = -1") #self.logModel.reset() # workaround for Qt <= 4.3.3/SQLite bug #self.logModel.beginResetModel() self.logModel.select() self.logView.horizontalHeader().setVisible( self.logModel.rowCount() > 0) if PYQT_VERSION_STR < "4.1.0": self.logView.setColumnHidden(ID, True) self.logView.setColumnHidden(ASSETID, True) #self.logModel.endResetModel() def addAsset(self): row = (self.assetView.currentIndex().row() if self.assetView.currentIndex().isValid() else 0) QSqlDatabase.database().transaction() self.assetModel.insertRow(row) index = self.assetModel.index(row, NAME) self.assetView.setCurrentIndex(index) assetid = 1 query = QSqlQuery() query.exec_("SELECT MAX(id) FROM assets") if query.next(): assetid = query.value(0) query.prepare("INSERT INTO logs (assetid, date, actionid) " "VALUES (:assetid, :date, :actionid)") query.bindValue(":assetid", assetid + 1) query.bindValue(":date", QDate.currentDate()) query.bindValue(":actionid", ACQUIRED) query.exec_() QSqlDatabase.database().commit() #self.logModel.select() self.assetView.edit(index) def deleteAsset(self): index = self.assetView.currentIndex() if not index.isValid(): return QSqlDatabase.database().transaction() record = self.assetModel.record(index.row()) assetid = record.value(ID) logrecords = 1 query = QSqlQuery( "SELECT COUNT(*) FROM logs WHERE assetid = {0}".format(assetid)) if query.next(): logrecords = query.value(0) msg = ("<font color=red>Delete</font><br><b>{0}</b>" "<br>from room {1}").format(record.value(NAME), record.value(ROOM)) if logrecords > 1: msg += (", along with {0} log records".format(logrecords)) msg += "?" if (QMessageBox.question(self, "Delete Asset", msg, QMessageBox.Yes | QMessageBox.No) == QMessageBox.No): QSqlDatabase.database().rollback() return #query.exec_("DELETE FROM logs WHERE assetid = {0}" # .format(assetid)) #use model API self.logModel.setFilter("assetid={0}".format(assetid)) self.logModel.select() if self.logModel.rowCount() > 0: self.logModel.removeRows(0, self.logModel.rowCount()) self.logModel.submitAll() self.assetModel.removeRow(index.row()) self.assetModel.submitAll() QSqlDatabase.database().commit() self.assetModel.select() self.assetChanged(self.assetView.currentIndex()) def addAction(self): index = self.assetView.currentIndex() if not index.isValid(): return QSqlDatabase.database().transaction() record = self.assetModel.record(index.row()) assetid = record.value(ID) row = self.logModel.rowCount() self.logModel.insertRow(row) self.logModel.setData(self.logModel.index(row, ASSETID), assetid) self.logModel.setData(self.logModel.index(row, DATE), QDate.currentDate()) QSqlDatabase.database().commit() index = self.logModel.index(row, ACTIONID) self.logView.setCurrentIndex(index) self.logView.edit(index) def deleteAction(self): index = self.logView.currentIndex() if not index.isValid(): return record = self.logModel.record(index.row()) action = record.value(ACTIONID) if action == "Acquired": QMessageBox.information( self, "Delete Log", "The 'Acquired' log record cannot be deleted.<br>" "You could delete the entire asset instead.") return when = str(record.value(DATE)) if (QMessageBox.question(self, "Delete Log", "Delete log<br>{0} {1}?".format(when, action), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No): return self.logModel.removeRow(index.row()) self.logModel.submitAll() self.logModel.select() def editActions(self): form = ReferenceDataDlg("actions", "Action", self) form.exec_() def editCategories(self): form = ReferenceDataDlg("categories", "Category", self) form.exec_()
class APISAdvancedInputDialog(QDialog): def __init__(self, dbm, tableName, showEntriesCombo, modelColumnName=None, excludeEntries=None, parent=None): super(APISAdvancedInputDialog, self).__init__(parent) self.dbm = dbm self.tableName = tableName self.modelColumnName = modelColumnName self.showEntriesCombo = showEntriesCombo self.excludeEntries = excludeEntries self.valueToBeAdded = None self.editors = None self.record = None self.tableExists = False if self.prepairEditorsAndRecord(): self.setupForm() else: pass # something went wrong preping def prepairEditorsAndRecord(self): if not DbHasTable(self.dbm.db, self.tableName): return False self.tableExists = True self.model = QSqlRelationalTableModel(self, self.dbm.db) self.model.setTable(self.tableName) self.model.select() while (self.model.canFetchMore()): self.model.fetchMore() self.record = self.model.record() self.editors = [] for fIdx in range(self.record.count()): field = self.record.field(fIdx) if field.name() != "ogc_fid": self.editors.append({ 'name': field.name(), 'type': field.type(), 'lineEdit': QLineEdit() }) return True def setupForm(self): layout = QFormLayout() if self.showEntriesCombo: self.uiAvailableEntriesCombo = QComboBox() # populate (but exlude if exclude has elements) if self.excludeEntries and len(self.excludeEntries) > 0: self.model.setFilter("{0} NOT IN ({1})".format( self.modelColumnName, ",".join("'{0}'".format(i) for i in self.excludeEntries))) # QMessageBox.information(self, "info", "{0} NOT IN ({1})".format(self.modelColumnName, ",".join("'{0}'".format(i) for i in self.excludeEntries))) # self.model.select() self.model.removeColumn(0) self.setupComboBox(self.uiAvailableEntriesCombo, self.model.fieldIndex(self.modelColumnName)) layout.addRow(self.uiAvailableEntriesCombo) self.uiAddBtn = QPushButton("Hinzufügen") if self.uiAvailableEntriesCombo.count() < 1: self.uiAddBtn.setEnabled(False) self.uiAddBtn.clicked.connect(self.addInputToSelection) layout.addRow(self.uiAddBtn) for editor in self.editors: # QMessageBox.information(self, "info", "{}".format((editor["name"]))) if editor["name"] != "ogc_fid": label = QLabel(editor["name"]) # QMessageBox.information(None, "info", "{}".format(editor["type"])) if editor["type"] == QVariant.Int: intVal = QIntValidator() intVal.setBottom(0) editor['lineEdit'].setValidator(intVal) layout.addRow(label, editor['lineEdit']) editor['lineEdit'].textEdited.connect(self.onTextEdited) self.uiSubmitBtn = QPushButton("Speichern") self.uiSubmitBtn.setEnabled(False) self.uiSubmitBtn.clicked.connect(self.saveInputAsQSqlRecord) layout.addRow(self.uiSubmitBtn) self.setLayout(layout) self.setWindowTitle("APIS Input Dialog") self.adjustSize() def onTextEdited(self, text): for editor in self.editors: if len(editor['lineEdit'].text().replace(" ", "")) == 0: self.uiSubmitBtn.setEnabled(False) return self.uiSubmitBtn.setEnabled(True) def addInputToSelection(self): self.setValueToBeAdded(self.uiAvailableEntriesCombo.currentText()) self.accept() def setValueToBeAdded(self, value): self.valueToBeAdded = value def getValueToBeAdded(self): return self.valueToBeAdded def saveInputAsQSqlRecord(self): for editor in self.editors: self.record.setValue(editor["name"], editor['lineEdit'].text()) if not self.record.isEmpty(): result = self.model.insertRowIntoTable(self.record) if result: self.setValueToBeAdded( self.record.field(self.modelColumnName).value()) self.accept() else: QMessageBox.warning( self, "DB Fehler", "Der folgende Feheler ist aufgetreten: {}".format( self.model.lastError().text())) self.reject() else: self.reject() def setupComboBox(self, editor, modelColumn): tv = QTableView() editor.setView(tv) tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) tv.setSelectionMode(QAbstractItemView.SingleSelection) tv.setSelectionBehavior(QAbstractItemView.SelectRows) tv.setAutoScroll(False) editor.setModel(self.model) editor.setModelColumn(modelColumn) editor.setInsertPolicy(QComboBox.NoInsert) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.verticalHeader().setVisible(False) tv.horizontalHeader().setVisible(True) #tv.setMinimumWidth(tv.horizontalHeader().length()) tv.horizontalHeader().setStretchLastSection(True) #tv.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) tv.resizeColumnsToContents() scroll = 0 if editor.count() <= editor.maxVisibleItems( ) else QApplication.style().pixelMetric(QStyle.PM_ScrollBarExtent) tv.setMinimumWidth(tv.horizontalHeader().length() + scroll)
class APISSharding(QDialog, FORM_CLASS): shardingEditsSaved = pyqtSignal(bool) def __init__(self, iface, dbm, parent=None): """Constructor.""" super(APISSharding, self).__init__(parent) self.iface = iface self.dbm = dbm self.setupUi(self) # Initial window size/pos last saved. Use default values for first time if GetWindowSize("sharding"): self.resize(GetWindowSize("sharding")) self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat) self.editMode = False self.addMode = False self.initalLoad = True # Signals/Slot Connections self.rejected.connect(self.onReject) #self.uiButtonBox.rejected.connect(self.onReject) self.uiOkBtn.clicked.connect(self.onAccept) self.uiCancelBtn.clicked.connect(self.cancelEdit) self.uiSaveBtn.clicked.connect(self.saveEdits) mViewPictures = QMenu() aViewPicturesPreview = mViewPictures.addAction( QIcon( os.path.join(QSettings().value("APIS/plugin_dir"), 'ui', 'icons', 'image.png')), "in Vorschau") aViewPicturesPreview.triggered.connect(self.viewPictures) aViewPicturesFolder = mViewPictures.addAction( QIcon( os.path.join(QSettings().value("APIS/plugin_dir"), 'ui', 'icons', 'image.png')), "in Ordner") aViewPicturesFolder.triggered.connect(self.openPictures) self.uiViewPicturesTBtn.setMenu(mViewPictures) self.uiViewPicturesTBtn.clicked.connect( self.uiViewPicturesTBtn.showMenu) mViewSketches = QMenu() aViewSketchesPreview = mViewSketches.addAction( QIcon( os.path.join(QSettings().value("APIS/plugin_dir"), 'ui', 'icons', 'sketch.png')), "in Vorschau") aViewSketchesPreview.triggered.connect(self.viewSketches) aViewSketchesFolder = mViewSketches.addAction( QIcon( os.path.join(QSettings().value("APIS/plugin_dir"), 'ui', 'icons', 'sketch.png')), "in Ordner") aViewSketchesFolder.triggered.connect(self.openSketches) self.uiViewSketchesTBtn.setMenu(mViewSketches) self.uiViewSketchesTBtn.clicked.connect( self.uiViewSketchesTBtn.showMenu) self.initalLoad = False def openSharding(self, siteNumber, shardingNumber): self.initalLoad = True self.siteNumber = siteNumber self.shardingNumber = shardingNumber #QMessageBox.warning(None, self.tr(u"Neu"), self.tr(u"{0}, {1}".format(siteNumber, shardingNumber))) # Setup sharding model self.model = QSqlRelationalTableModel(self, self.dbm.db) self.model.setTable("begehung") self.model.setFilter("fundortnummer='{0}' AND begehung='{1}'".format( self.siteNumber, self.shardingNumber)) res = self.model.select() self.setupMapper() self.mapper.toFirst() self.setKgNameAndCode() self.initalLoad = False def setKgNameAndCode(self): query = QSqlQuery(self.dbm.db) qryStr = u"select CASE WHEN katastralgemeinde IS NULL AND katastralgemeindenummer IS NULL THEN '--' ELSE katastralgemeindenummer || ' - ' || katastralgemeinde END AS kg FROM fundort WHERE fundortnummer = '{0}'".format( self.siteNumber) query.exec_(qryStr) query.first() self.uiCadastralCommunityEdit.setText(query.value(0)) def setupMapper(self): self.mapper = QDataWidgetMapper(self) self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit) self.mapper.setItemDelegate(ShardingDelegate()) self.mapper.setModel(self.model) self.mandatoryEditors = [self.uiShardingDate] # LineEdits & PlainTextEdits self.intValidator = QIntValidator() self.doubleValidator = QDoubleValidator() self.lineEditMaps = { "fundortnummer": { "editor": self.uiSiteNumberEdit }, "begehung": { "editor": self.uiShardingNumberEdit }, "name": { "editor": self.uiNameEdit }, "parzelle": { "editor": self.uiPlotPTxt }, "sichtbarkeit": { "editor": self.uiVisibilityEdit }, "verbleib": { "editor": self.uiWhereaboutsEdit }, "funde": { "editor": self.uiFindsPTxt }, "morphologie": { "editor": self.uiMorphologyPTxt }, "sonstiges": { "editor": self.uiMiscellaneousPTxt } } for key, item in self.lineEditMaps.items(): self.mapper.addMapping(item["editor"], self.model.fieldIndex(key)) if "validator" in item: item["editor"].setValidator(item["validator"]) #item["editor"].textChanged.connect(partial(self.onLineEditChanged, item["editor"])) item["editor"].textChanged.connect(self.onLineEditChanged) # Date and Times self.mapper.addMapping(self.uiShardingDate, self.model.fieldIndex("datum")) # ComboBox without Model self.mapper.addMapping(self.uiShardingTypeCombo, self.model.fieldIndex("begehtyp")) self.uiShardingTypeCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiShardingTypeCombo.setAutoCompletion(True) self.uiShardingTypeCombo.lineEdit().setValidator( InListValidator([ self.uiShardingTypeCombo.itemText(i) for i in range(self.uiShardingTypeCombo.count()) ], self.uiShardingTypeCombo.lineEdit(), None, self)) # ComboBox without Model self.mapper.addMapping(self.uiConditionPlantCoverCombo, self.model.fieldIndex("zustand_bewuchs")) self.uiConditionPlantCoverCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiConditionPlantCoverCombo.setAutoCompletion(True) self.uiConditionPlantCoverCombo.lineEdit().setValidator( InListValidator([ self.uiConditionPlantCoverCombo.itemText(i) for i in range(self.uiConditionPlantCoverCombo.count()) ], self.uiConditionPlantCoverCombo.lineEdit(), None, self)) # ComboBox without Model self.mapper.addMapping(self.uiConditionLightCombo, self.model.fieldIndex("zustand_licht")) self.uiConditionLightCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiConditionLightCombo.setAutoCompletion(True) self.uiConditionLightCombo.lineEdit().setValidator( InListValidator([ self.uiConditionLightCombo.itemText(i) for i in range(self.uiConditionLightCombo.count()) ], self.uiConditionLightCombo.lineEdit(), None, self)) # ComboBox without Model self.mapper.addMapping(self.uiConditionSoilCombo, self.model.fieldIndex("zustand_boden")) self.uiConditionSoilCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiConditionSoilCombo.setAutoCompletion(True) self.uiConditionSoilCombo.lineEdit().setValidator( InListValidator([ self.uiConditionSoilCombo.itemText(i) for i in range(self.uiConditionSoilCombo.count()) ], self.uiConditionSoilCombo.lineEdit(), None, self)) # ComboBox without Model self.mapper.addMapping(self.uiConditionMoistureCombo, self.model.fieldIndex("zustand_feuchtigkeit")) self.uiConditionMoistureCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiConditionMoistureCombo.setAutoCompletion(True) self.uiConditionMoistureCombo.lineEdit().setValidator( InListValidator([ self.uiConditionMoistureCombo.itemText(i) for i in range(self.uiConditionMoistureCombo.count()) ], self.uiConditionMoistureCombo.lineEdit(), None, self)) # ComboBox without Model self.mapper.addMapping(self.uiConditionRainCombo, self.model.fieldIndex("zustand_abgeregnet")) self.uiConditionRainCombo.editTextChanged.connect( self.onLineEditChanged) # FIXME Pyqt5 AutoCompletion #self.uiConditionRainCombo.setAutoCompletion(True) self.uiConditionRainCombo.lineEdit().setValidator( InListValidator([ self.uiConditionRainCombo.itemText(i) for i in range(self.uiConditionRainCombo.count()) ], self.uiConditionRainCombo.lineEdit(), None, self)) def onLineEditChanged(self): sender = self.sender() if not self.editMode and not self.initalLoad: self.startEditMode() if not self.initalLoad: sender.setStyleSheet( "{0} {{background-color: rgb(153, 204, 255);}}".format( sender.metaObject().className())) self.editorsEdited.append(sender) def onAccept(self): ''' Check DB Save options when pressing OK button Update Plugin Status ''' # Save Settings SetWindowSize("sharding", self.size()) self.accept() def onReject(self): ''' Run some actions when the user closes the dialog ''' if self.editMode: res = self.cancelEdit() if res: SetWindowSize("sharding", self.size()) self.close() else: self.show() else: SetWindowSize("sharding", self.size()) self.close() def addNewSharding(self, siteNumber): self.initalLoad = True self.siteNumber = siteNumber # get new sharding number query = QSqlQuery(self.dbm.db) qryStr = "SELECT CASE WHEN max(begehung) IS NULL THEN 1 ELSE max(begehung)+1 END begehungNeu FROM begehung WHERE fundortnummer='{0}'".format( self.siteNumber) query.exec_(qryStr) query.first() self.shardingNumber = query.value(0) self.model = QSqlRelationalTableModel(self, self.dbm.db) self.model.setTable("begehung") self.model.setFilter("fundortnummer='{0}'".format(self.siteNumber)) res = self.model.select() #self.model.submitAll() while (self.model.canFetchMore()): self.model.fetchMore() row = self.model.rowCount() #QMessageBox.information(None, "begehung", "{0}".format(row)) self.model.insertRow(row) #QMessageBox.information(None, "begehung", "{0}".format(self.model.rowCount())) self.setupMapper() self.mapper.toLast() self.addMode = True self.startEditMode() # self.mapper.submit() # self.model.insertRow(row) # self.mapper.setCurrentIndex(row) self.uiSiteNumberEdit.setText(self.siteNumber) self.uiShardingNumberEdit.setText(str(self.shardingNumber)) now = QDate.currentDate() self.uiShardingDate.setDate(now) self.setKgNameAndCode() #QMessageBox.warning(None, self.tr(u"Neu"), self.tr(u"{0}, {1}".format(siteNumber,nn))) self.initalLoad = False def removeNewSharding(self): self.initalLoad = True row = self.mapper.currentIndex() self.model.removeRow(row + 1) self.model.submitAll() while (self.model.canFetchMore()): self.model.fetchMore() self.mapper.toLast() self.initalLoad = False def saveEdits(self): #Check Mandatory fields flag = False for mEditor in self.mandatoryEditors: cName = mEditor.metaObject().className() if cName == 'QDateEdit': value = mEditor.date().toString("yyyy-MM-dd") elif cName == 'QLineEdit': value = mEditor.text() elif cName == 'QComboBox': if mEditor.isEditable(): value = mEditor.lineEdit().text() else: if mEditor.currentIndex == -1: value = '' else: value = '1' if value.strip() == "": flag = True mEditor.setStyleSheet( "{0} {{background-color: rgb(240, 160, 160);}}".format( cName)) if mEditor not in self.editorsEdited: self.editorsEdited.append(mEditor) else: if mEditor in self.editorsEdited: mEditor.setStyleSheet( "{0} {{background-color: rgb(153, 204, 255);}}".format( cName)) #else: #mEditor.setStyleSheet("") if flag: QMessageBox.warning( self, self.tr(u"Benötigte Felder Ausfüllen"), self. tr(u"Füllen Sie bitte alle Felder aus, die mit * gekennzeichnet sind." )) return False #saveToModel currIdx = self.mapper.currentIndex() #QMessageBox.information(None, "begehung", "{0}".format(currIdx)) #now = QDate.currentDate() #self.uiLastChangesDate.setDate(now) self.mapper.submit() self.mapper.setCurrentIndex(currIdx) # emit signal self.shardingEditsSaved.emit(True) self.endEditMode() return True def cancelEdit(self): currIdx = self.mapper.currentIndex() if self.editMode: result = QMessageBox.question( self, self.tr(u"Änderungen wurden vorgenommen!"), self.tr(u"Möchten Sie die Änerungen speichern?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) #save or not save if result == QMessageBox.Yes: res = self.saveEdits() if res: return True else: return False elif result == QMessageBox.No: if self.addMode: #self.close() self.done(1) self.removeNewSharding() self.endEditMode() return True else: self.mapper.setCurrentIndex(currIdx) self.endEditMode() return True def startEditMode(self): self.editMode = True self.uiOkBtn.setEnabled(False) self.uiSaveBtn.setEnabled(True) self.uiCancelBtn.setEnabled(True) self.editorsEdited = [] self.uiShardingDate.setReadOnly(not self.addMode) if self.uiShardingDate.isReadOnly(): self.uiShardingDate.setStyleSheet( "background-color: rgb(218, 218, 218);") else: self.uiShardingDate.setStyleSheet("") def endEditMode(self): self.editMode = False self.addMode = False self.uiOkBtn.setEnabled(True) self.uiSaveBtn.setEnabled(False) self.uiCancelBtn.setEnabled(False) self.uiShardingDate.setReadOnly(not self.addMode) self.uiShardingDate.setStyleSheet( "background-color: rgb(218, 218, 218);") for editor in self.editorsEdited: cName = editor.metaObject().className() if (cName == "QLineEdit" or cName == "QDateEdit") and editor.isReadOnly(): editor.setStyleSheet( "{0} {{background-color: rgb(218, 218, 218);}}".format( cName)) else: editor.setStyleSheet("") self.editorsEdited = [] def viewPictures(self): dirName = self.settings.value("APIS/insp_image_dir") folderNameType = self.settings.value("APIS/insp_image_foto_dir") folderNameSite = self.getFolderNameSite(self.siteNumber) path = dirName + u'\\' + folderNameSite + u'\\' + folderNameType self.loadInImageViewer(path) def openPictures(self): dirName = self.settings.value("APIS/insp_image_dir") folderNameType = self.settings.value("APIS/insp_image_foto_dir") folderNameSite = self.getFolderNameSite(self.siteNumber) path = dirName + u'\\' + folderNameSite + u'\\' + folderNameType if not OpenFileOrFolder(path): QMessageBox.information( self, u"Begehung", u"Das Verzeichnis '{0}' wurde nicht gefunden.".format(path)) def viewSketches(self): dirName = self.settings.value("APIS/insp_image_dir") folderNameType = self.settings.value("APIS/insp_image_sketch_dir") folderNameSite = self.getFolderNameSite(self.siteNumber) path = dirName + u'\\' + folderNameSite + u'\\' + folderNameType self.loadInImageViewer(path) def openSketches(self): dirName = self.settings.value("APIS/insp_image_dir") folderNameType = self.settings.value("APIS/insp_image_sketch_dir") folderNameSite = self.getFolderNameSite(self.siteNumber) path = dirName + u'\\' + folderNameSite + u'\\' + folderNameType if not OpenFileOrFolder(path): QMessageBox.information( None, u"Begehung", u"Das Verzeichnis '{0}' wurde nicht gefunden.".format(path)) def getFolderNameSite(self, siteNumber): query = QSqlQuery(self.dbm.db) #qryStr = u"SELECT trim(katastralgemeinde) || ' ' || trim(katastralgemeindenummer) || '.' || substr('000' || fundortnummer_nn_legacy, -3, 3) AS folderName FROM fundort f WHERE f.fundortnummer='{0}'".format(siteNumber) query.prepare( u"SELECT land || '\\' || CASE WHEN land = 'AUT' THEN replace(replace(replace(replace(lower(trim(katastralgemeinde)), '.',''), '-', ' '), '(', ''), ')', '') || ' ' ELSE '' END || substr('000000' || fundortnummer_nn, -6, 6) AS folderName FROM fundort f WHERE f.fundortnummer='{0}'" .format(siteNumber)) query.exec_() query.first() return query.value(0) def loadInImageViewer(self, path): dir = QDir(path) if dir.exists(): entryList = dir.entryList(['*.jpg'], QDir.Files) if len(entryList) > 0: # load in thumb viewer # QMessageBox.information(None, u"Begehung", u",".join(entryList)) imagePathList = [] for image in entryList: imagePathList.append(path + u'\\' + image) widget = APISThumbViewer() widget.load(imagePathList) widget.show() if widget.exec_(): pass # app.exec_() else: QMessageBox.information( self, u"Begehung", u"Es wurden keine Dateien [*.jpg] für diesen Fundort gefunden." ) else: QMessageBox.information( self, u"Begehung", u"Das Verzeichnis '{0}' wurde nicht gefunden.".format(path))