Example #1
0
class DBViewWindow(QWidget, Ui_DB_View_Form):
    def __init__(self, database_name):
        super().__init__()
        # uic.loadUi('db_view.ui', self)
        self.setupUi(self)
        # self.db_name = database_name
        # # Подключение БД к таблице отображения
        # # Подключение через QSqlRelationalTableModel
        # self.db = QSqlDatabase.addDatabase('QSQLITE')
        # self.db.setDatabaseName(self.db_name)
        # self.db.open()
        self.model = QSqlRelationalTableModel(self)
        self.model.setTable('goods')
        self.model.setRelation(
            5, QSqlRelation('statuses', 'id_status', 'status_name'))
        self.model.setRelation(
            6, QSqlRelation('goods_types', 'id_goods_type', 'goods_type_name'))
        self.model.setRelation(
            7,
            QSqlRelation('goods_subtypes', 'id_goods_subtype',
                         'goods_subtype_name'))
        self.model.setRelation(
            8, QSqlRelation('location', 'id_location', 'location_name'))
        self.model.setRelation(
            9, QSqlRelation('responsibles', 'id_responsible', 'FIO'))
        self.refresh()
        self.tableView.doubleClicked.connect(self.table_clicked)
        # self.tableView.clicked.connect()
        self.refreshBtn.clicked.connect(self.refresh)
        self.save_all_btn.clicked.connect(self.submitall)

    def table_clicked(self):
        row = self.tableView.currentIndex().row()
        if row != -1:
            self.tableView.selectRow(row)
        index = self.tableView.currentIndex()
        self.edit_form = EditForm(index, self.model)
        self.edit_form.show()

    # Предположительно на выходе будет закрываться БД
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.db.close()
        super().__exit__()

    def refresh(self):
        self.model.select()
        self.tableView.setModel(self.model)
        self.tableView.setItemDelegate(QSqlRelationalDelegate(self.tableView))

    def submitall(self):
        if not self.model.submitAll():
            print(self.model.lastError())
        else:
            self.refresh()
Example #2
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self) -> None:
        super().__init__()

        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.dbpath = DEFAULT_DATABASE_PATH
        self.qmainwindow = QtWidgets.QMainWindow()

        # define buttons vehaviour
        self.button_actions: Dict[str, QtWidgets.QAction] = {}
        self.define_buttons()

        # UI variables
        self.label = QtWidgets.QLabel()
        self.combo_box = QtWidgets.QComboBox()
        self.table_model = QSqlRelationalTableModel()
        self.table_view = QtWidgets.QTableView()

        # create window and show it
        self.draw()
        self.qmainwindow.show()

    def draw(self) -> None:
        self.qmainwindow.setObjectName("MainWindow")
        self.qmainwindow.resize(800, 600)
        self.qmainwindow.setWindowTitle("Database manager")

        widget = QtWidgets.QWidget(self.qmainwindow)
        widget.setObjectName("widget")
        self.qmainwindow.setCentralWidget(widget)

        self.toolbar = self.qmainwindow.addToolBar("ToolBar")
        for _, action in self.button_actions.items():
            self.toolbar.addAction(action)

        _ = QtWidgets.QLabel(widget)
        _.setGeometry(
            QtCore.QRect(QtCore.QPoint(10, 10), QtCore.QSize(105, 16)))
        _.setText("Database path: ")
        self.label = QtWidgets.QLabel(widget)
        self.label.setGeometry(
            QtCore.QRect(QtCore.QPoint(110, 10), QtCore.QSize(750, 16)))
        self.label.setText(self.dbpath)

        _ = QtWidgets.QLabel(widget)
        _.setGeometry(
            QtCore.QRect(QtCore.QPoint(10, 30), QtCore.QSize(105, 16)))
        _.setText("Choosen table: ")
        self.combo_box = QtWidgets.QComboBox(self.qmainwindow)
        self.combo_box.setGeometry(
            QtCore.QRect(QtCore.QPoint(100, 55), QtCore.QSize(200, 16)))
        self.combo_box.currentIndexChanged.connect(self.update_table)

        _ = QtWidgets.QLabel(widget)
        _.setGeometry(
            QtCore.QRect(QtCore.QPoint(10, 65), QtCore.QSize(105, 16)))
        _.setText("Table")

        self.table_view = QtWidgets.QTableView(self.qmainwindow)
        self.table_view.setObjectName("tableView")
        self.table_view.setGeometry(
            QtCore.QRect(QtCore.QPoint(10, 115), QtCore.QSize(780, 475)))
        self.table_view.setShowGrid(False)

    def define_buttons(self) -> None:
        def _exit_action() -> None:
            QtWidgets.qApp.quit()

        def _show_dialog() -> None:
            self.dbpath, _ = QtWidgets.QFileDialog.getOpenFileName(
                self, "Open file")
            self.label.setText(self.dbpath)

        def _load_database() -> None:
            self.db.setDatabaseName(self.dbpath)
            self.db.open()

            # update selectors
            self.combo_box.clear()
            for tbl in self.db.tables():
                self.combo_box.addItem(tbl)
            self.update_table()

        def _save_database() -> None:
            self.table_model.submitAll()

        def _insert_row() -> None:
            self.table_model.insertRows(self.table_model.rowCount(), 1)

        def _remove_row() -> None:
            for idx in self.table_view.selectedIndexes():
                self.table_model.removeRows(idx.row(), 1)

        self.button_actions.update(
            {"exit": QtWidgets.QAction("Exit", self.qmainwindow)})
        self.button_actions["exit"].triggered.connect(_exit_action)

        self.button_actions.update({
            "dbpath":
            QtWidgets.QAction("Set database path", self.qmainwindow)
        })
        self.button_actions["dbpath"].triggered.connect(_show_dialog)

        self.button_actions.update(
            {"load": QtWidgets.QAction("Load database", self.qmainwindow)})
        self.button_actions["load"].triggered.connect(_load_database)

        self.button_actions.update(
            {"save": QtWidgets.QAction("Save database", self.qmainwindow)})
        self.button_actions["save"].triggered.connect(_save_database)

        self.button_actions.update(
            {"insert": QtWidgets.QAction("Insert row", self.qmainwindow)})
        self.button_actions["insert"].triggered.connect(_insert_row)

        self.button_actions.update(
            {"remove": QtWidgets.QAction("Remove row", self.qmainwindow)})
        self.button_actions["remove"].triggered.connect(_remove_row)

    def update_table(self) -> None:
        self.table_model = QSqlRelationalTableModel()

        tablename = self.combo_box.currentText()
        self.table_model.setTable(tablename)

        # foreign key logic
        if tablename == "goods":
            self.table_model.setRelation(2,
                                         QSqlRelation("units", "id", "unit"))
            self.table_model.setRelation(
                3, QSqlRelation("categories", "id", "name"))
        elif tablename == "employees":
            self.table_model.setRelation(
                2, QSqlRelation("positions", "id", "position"))
        elif tablename == "vendors":
            self.table_model.setRelation(
                2, QSqlRelation("ownerships", "id", "ownership"))

        self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)

        self.table_view.setModel(self.table_model)
        self.table_view.setItemDelegate(QSqlRelationalDelegate(
            self.table_view))

        # define header width
        self.table_view.horizontalHeader().setStretchLastSection(False)
        self.table_view.resizeColumnsToContents()
        self.table_view.horizontalHeader().setMinimumSectionSize(50)
        self.table_view.horizontalHeader().setStretchLastSection(True)
Example #3
0
class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Собираем окно
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.db_path = r'database/database.sqlite3'
        self.ui.path_db.setText(self.db_path)

        # Собираем кнопки
        self.save_db = QAction(QIcon('icon/save.png'), 'Save', self)
        self.open_db_file = QAction(QIcon('icon/open-db.png'), 'Open', self)
        self.add_row = QAction(QIcon('icon/add.png'), 'Add row', self)
        self.del_row = QAction(QIcon('icon/del.png'), ' Del row', self)
        self.ui.toolBar.addAction(self.save_db)
        self.ui.toolBar.addAction(self.open_db_file)
        self.ui.toolBar.addAction(self.add_row)
        self.ui.toolBar.addAction(self.del_row)
        self.db = None
        self.table_model = None
        # Подключаемся к БД
        self.open_db()
        # действуем по триггерам
        self.add_row.triggered.connect(self.add_row_action)
        self.del_row.triggered.connect(self.del_row_action)
        self.save_db.triggered.connect(self.save_change_db)
        self.open_db_file.triggered.connect(self.open_db_file_action)
        self.ui.comboBox.currentIndexChanged.connect(self.show_table)

    def open_db(self):
        # Подключение к БД
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(self.db_path)
        self.db.open()
        self.get_tables_name()
        self.show_table()

    def get_tables_name(self):
        self.ui.comboBox.clear()
        for table_name in self.db.tables():
            self.ui.comboBox.addItem(table_name)

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()
        table = self.ui.comboBox.currentText()
        if table == 'goods':
            self.create_goods_table_model()
        elif table == 'employees':
            self.create_employees_table_model()
        else:
            self.table_model.setTable(table)
            self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableView
        view.setModel(self.table_model)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def create_goods_table_model(self):
        self.table_model.setTable('goods')
        self.table_model.setRelation(2, QSqlRelation('units', 'unit_id', 'unit'))
        self.table_model.setRelation(3, QSqlRelation('categories', 'category_id', 'category_name'))
        self.table_model.select()

    def create_employees_table_model(self):
        self.table_model.setTable('employees')
        self.table_model.setRelation(2, QSqlRelation('positions', 'position_id', 'position'))
        self.table_model.select()

    def add_row_action(self):
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def del_row_action(self):
        rs = list(map(lambda x: x.row(), self.ui.tableView.selectedIndexes()))
        print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)

    def open_db_file_action(self):
        self.db_path = QFileDialog.getOpenFileName(self, "Open file")[0]
        self.ui.path_db.setText(self.db_path)
        self.db.close()
        self.open_db()

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Изменения сохранены')
        else:
            self.ui.statusbar.showMessage(f'{self.table_model.lastError().text()}')
Example #4
0
class PhoneLogDlg(QDialog):

    FIRST, PREV, NEXT, LAST = range(4)

    def __init__(self, parent=None):
        super(PhoneLogDlg, self).__init__(parent)

        callerLabel = QLabel("&Caller:")
        self.callerEdit = QLineEdit()
        callerLabel.setBuddy(self.callerEdit)
        today = QDate.currentDate()
        startLabel = QLabel("&Start:")
        self.startDateTime = QDateTimeEdit()
        startLabel.setBuddy(self.startDateTime)
        self.startDateTime.setDateRange(today, today)
        self.startDateTime.setDisplayFormat(DATETIME_FORMAT)
        endLabel = QLabel("&End:")
        self.endDateTime = QDateTimeEdit()
        endLabel.setBuddy(self.endDateTime)
        self.endDateTime.setDateRange(today, today)
        self.endDateTime.setDisplayFormat(DATETIME_FORMAT)
        topicLabel = QLabel("&Topic:")
        topicEdit = QLineEdit()
        topicLabel.setBuddy(topicEdit)
        outcomeLabel = QLabel("&Outcome:")
        self.outcomeComboBox = QComboBox()
        outcomeLabel.setBuddy(self.outcomeComboBox)
        firstButton = QPushButton()
        firstButton.setIcon(QIcon(":/first.png"))
        prevButton = QPushButton()
        prevButton.setIcon(QIcon(":/prev.png"))
        nextButton = QPushButton()
        nextButton.setIcon(QIcon(":/next.png"))
        lastButton = QPushButton()
        lastButton.setIcon(QIcon(":/last.png"))
        addButton = QPushButton("&Add")
        addButton.setIcon(QIcon(":/add.png"))
        deleteButton = QPushButton("&Delete")
        deleteButton.setIcon(QIcon(":/delete.png"))
        quitButton = QPushButton("&Quit")
        quitButton.setIcon(QIcon(":/quit.png"))
        if not MAC:
            addButton.setFocusPolicy(Qt.NoFocus)
            deleteButton.setFocusPolicy(Qt.NoFocus)

        fieldLayout = QGridLayout()
        fieldLayout.addWidget(callerLabel, 0, 0)
        fieldLayout.addWidget(self.callerEdit, 0, 1, 1, 3)
        fieldLayout.addWidget(startLabel, 1, 0)
        fieldLayout.addWidget(self.startDateTime, 1, 1)
        fieldLayout.addWidget(endLabel, 1, 2)
        fieldLayout.addWidget(self.endDateTime, 1, 3)
        fieldLayout.addWidget(topicLabel, 2, 0)
        fieldLayout.addWidget(topicEdit, 2, 1, 1, 3)
        fieldLayout.addWidget(outcomeLabel, 3, 0)
        fieldLayout.addWidget(self.outcomeComboBox, 3, 1, 1, 3)
        navigationLayout = QHBoxLayout()
        navigationLayout.addWidget(firstButton)
        navigationLayout.addWidget(prevButton)
        navigationLayout.addWidget(nextButton)
        navigationLayout.addWidget(lastButton)
        fieldLayout.addLayout(navigationLayout, 4, 0, 1, 2)
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(addButton)
        buttonLayout.addWidget(deleteButton)
        buttonLayout.addStretch()
        buttonLayout.addWidget(quitButton)
        layout = QHBoxLayout()
        layout.addLayout(fieldLayout)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        self.model = QSqlRelationalTableModel(self)
        self.model.setTable("calls")
        self.model.setRelation(OUTCOMEID, QSqlRelation("outcomes", "id",
                                                       "name"))
        self.model.setSort(STARTTIME, Qt.AscendingOrder)
        self.model.select()

        self.mapper = QDataWidgetMapper(self)
        self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
        self.mapper.setModel(self.model)
        self.mapper.setItemDelegate(QSqlRelationalDelegate(self))
        self.mapper.addMapping(self.callerEdit, CALLER)
        self.mapper.addMapping(self.startDateTime, STARTTIME)
        self.mapper.addMapping(self.endDateTime, ENDTIME)
        self.mapper.addMapping(topicEdit, TOPIC)
        relationModel = self.model.relationModel(OUTCOMEID)
        self.outcomeComboBox.setModel(relationModel)
        self.outcomeComboBox.setModelColumn(relationModel.fieldIndex("name"))
        self.mapper.addMapping(self.outcomeComboBox, OUTCOMEID)
        self.mapper.toFirst()

        firstButton.clicked.connect(lambda: self.saveRecord(PhoneLogDlg.FIRST))
        prevButton.clicked.connect(lambda: self.saveRecord(PhoneLogDlg.PREV))
        nextButton.clicked.connect(lambda: self.saveRecord(PhoneLogDlg.NEXT))
        lastButton.clicked.connect(lambda: self.saveRecord(PhoneLogDlg.LAST))
        addButton.clicked.connect(self.addRecord)
        deleteButton.clicked.connect(self.deleteRecord)
        quitButton.clicked.connect(self.done)
        self.setWindowTitle("Phone Log")

    def done(self, result=None):
        self.mapper.submit()
        QDialog.done(self, True)

    def addRecord(self):
        row = self.model.rowCount()
        self.mapper.submit()
        self.model.insertRow(row)
        self.mapper.setCurrentIndex(row)
        now = QDateTime.currentDateTime()
        self.startDateTime.setDateTime(now)
        self.endDateTime.setDateTime(now)
        self.outcomeComboBox.setCurrentIndex(
            self.outcomeComboBox.findText("Unresolved"))
        self.callerEdit.setFocus()

    def deleteRecord(self):
        caller = self.callerEdit.text()
        starttime = self.startDateTime.dateTime().toString(DATETIME_FORMAT)
        if (QMessageBox.question(
                self, "Delete",
                "Delete call made by<br>{0} on {1}?".format(caller, starttime),
                QMessageBox.Yes | QMessageBox.No) == QMessageBox.No):
            return
        row = self.mapper.currentIndex()
        self.model.removeRow(row)
        self.model.submitAll()
        self.model.select()
        if row + 1 >= self.model.rowCount():
            row = self.model.rowCount() - 1
        self.mapper.setCurrentIndex(row)

    def saveRecord(self, where):
        row = self.mapper.currentIndex()
        self.mapper.submit()
        if where == PhoneLogDlg.FIRST:
            row = 0
        elif where == PhoneLogDlg.PREV:
            row = 0 if row <= 1 else row - 1
        elif where == PhoneLogDlg.NEXT:
            row += 1
            if row >= self.model.rowCount():
                row = self.model.rowCount() - 1
        elif where == PhoneLogDlg.LAST:
            row = self.model.rowCount() - 1
        self.mapper.setCurrentIndex(row)
Example #5
0
class QmyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)  #调用父类构造函数,创建窗体
        self.ui = Ui_MainWindow()  #创建UI对象
        self.ui.setupUi(self)  #构造UI界面

        self.setCentralWidget(self.ui.tableView)

        #   tableView显示属性设置
        self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(100)

##  ==============自定义功能函数============

    def __getFieldNames(self):  ##获取所有字段名称
        emptyRec = self.tabModel.record()  #获取空记录,只有字段名
        self.fldNum = {}  #字段名与序号的字典
        for i in range(emptyRec.count()):
            fieldName = emptyRec.fieldName(i)
            self.fldNum.setdefault(fieldName)
            self.fldNum[fieldName] = i
        print(self.fldNum)

    def __openTable(self):  ##打开数据表
        self.tabModel = QSqlRelationalTableModel(self, self.DB)  #数据表

        self.tabModel.setTable("studInfo")  #设置数据表
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit
                                      )  #数据保存方式,OnManualSubmit , OnRowChange
        self.tabModel.setSort(self.tabModel.fieldIndex("studID"),
                              Qt.AscendingOrder)  #排序

        if (self.tabModel.select() == False):  #查询数据失败
            QMessageBox.critical(
                self, "错误信息",
                "打开数据表错误,错误信息\n" + self.tabModel.lastError().text())
            return

        self.__getFieldNames()  #获取字段名和序号

        ##字段显示名
        self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号")
        self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal,
                                    "学院")
        self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal,
                                    "专业")

        ##    设置代码字段的查询关系数据表
        self.tabModel.setRelation(self.fldNum["departID"],
                                  QSqlRelation("departments", "departID",
                                               "department"))  #学院
        self.tabModel.setRelation(self.fldNum["majorID"],
                                  QSqlRelation("majors", "majorID",
                                               "major"))  #专业

        self.selModel = QItemSelectionModel(self.tabModel)  #关联选择模型

        ##selModel当前项变化时触发currentChanged信号
        self.selModel.currentChanged.connect(self.do_currentChanged)
        ##选择行变化时
        ##      self.selModel.currentRowChanged.connect(self.do_currentRowChanged)

        self.ui.tableView.setModel(self.tabModel)  #设置数据模型
        self.ui.tableView.setSelectionModel(self.selModel)  #设置选择模型

        delgate = QSqlRelationalDelegate(self.ui.tableView)
        self.ui.tableView.setItemDelegate(delgate)  #为关系型字段设置缺省代理组件

        self.tabModel.select()  #必须重新查询数据
        ##更新actions和界面组件的使能状态
        self.ui.actOpenDB.setEnabled(False)

        self.ui.actRecAppend.setEnabled(True)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actFields.setEnabled(True)

##  ==========由connectSlotsByName() 自动连接的槽函数==================

    @pyqtSlot()
    def on_actOpenDB_triggered(self):
        dbFilename, flt = QFileDialog.getOpenFileName(
            self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)")
        if (dbFilename == ''):
            return

        #打开数据库
        self.DB = QSqlDatabase.addDatabase("QSQLITE")  #添加 SQL LITE数据库驱动
        self.DB.setDatabaseName(dbFilename)  #设置数据库名称
        ##    DB.setHostName()
        ##    DB.setUserName()
        ##    DB.setPassword()
        if self.DB.open():  #打开数据库
            self.__openTable()  #打开数据表
        else:
            QMessageBox.warning(self, "错误", "打开数据库失败")

    @pyqtSlot()  ##保存修改
    def on_actSubmit_triggered(self):
        res = self.tabModel.submitAll()
        if (res == False):
            QMessageBox.information(
                self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text())
        else:
            self.ui.actSubmit.setEnabled(False)
            self.ui.actRevert.setEnabled(False)

    @pyqtSlot()  ##取消修改
    def on_actRevert_triggered(self):
        self.tabModel.revertAll()
        self.ui.actSubmit.setEnabled(False)
        self.ui.actRevert.setEnabled(False)

    @pyqtSlot()  ##添加记录
    def on_actRecAppend_triggered(self):
        self.tabModel.insertRow(self.tabModel.rowCount(),
                                QModelIndex())  #在末尾添加一个记录
        curIndex = self.tabModel.index(self.tabModel.rowCount() - 1,
                                       1)  #创建最后一行的ModelIndex
        self.selModel.clearSelection()  #清空选择项
        self.selModel.setCurrentIndex(
            curIndex, QItemSelectionModel.Select)  #设置刚插入的行为当前选择行

    @pyqtSlot()  ##插入记录
    def on_actRecInsert_triggered(self):
        curIndex = self.ui.tableView.currentIndex()  #QModelIndex
        self.tabModel.insertRow(curIndex.row(), QModelIndex())
        self.selModel.clearSelection()  #清除已有选择
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

    @pyqtSlot()  ##删除记录
    def on_actRecDelete_triggered(self):
        curIndex = self.selModel.currentIndex()  #获取当前选择单元格的模型索引
        self.tabModel.removeRow(curIndex.row())  #删除最后一行

    @pyqtSlot()  ##显示字段列表
    def on_actFields_triggered(self):
        emptyRec = self.tabModel.record()  #获取空记录,只有字段名
        str = ''
        for i in range(emptyRec.count()):
            str = str + emptyRec.fieldName(i) + '\n'
        QMessageBox.information(self, "所有字段名", str)

##  =============自定义槽函数===============================

    def do_currentChanged(self, current, previous):  ##更新actPost和actCancel 的状态
        self.ui.actSubmit.setEnabled(self.tabModel.isDirty())  #有未保存修改时可用
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())
class NormaOdk(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.skrot = QShortcut(QKeySequence(Qt.Key_Return), self)
        self.naglowki = {
            'iddetale': 'ID',
            'nr_detalu': 'Detal',
            'maszyna': 'Maszyna',
            "ilosc_m": 'Ilość maszyn',
            'ilosc_szt': 'Ilość sztuk na operację',
            'nazwa_op': 'Nazwa operacji',
            'nr_op': 'Nr operacji',
            'tm': 'Czas Tm [s]',
            'tp': 'Czas Tp [s]',
            'tj': 'Czas Tj [h]',
            'norma': 'Norma [szt.]',
            'uwagi': 'Uwagi',
            'id_uzytkownika': 'Użytkownik'
        }
        self.proxy = QSortFilterProxyModel(self)
        self.parent = parent
        self.formularz = QGroupBox("Normy")
        self.lbl_w = QLabel("Wyszukaj")
        self.edit_w = QLineEdit(self)
        self.table = QTableView(self)
        self.btn_odswiez = QPushButton("Odśwież bazę")
        sciezka = czy_istnieje()
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(sciezka)
        if self.db.open():
            print('Otworzono bazę danych')
        self.model = QSqlRelationalTableModel(self, self.db)
        self.initUI()

    def initUI(self):
        # Zainicjowanie tabeli zawsze przed wszystkim
        self.tabela()

        # lista wybieralna
        with open('./resources/Maszyny i operacje.json', 'r',
                  encoding='utf-8') as file:
            plik_json = json.load(file)
        masz = plik_json['Maszyny']
        operacje = plik_json['Operacje']
        self.table.setItemDelegateForColumn(2, ComboDelegate(self, masz))
        self.table.setItemDelegateForColumn(6, ComboDelegate(self, operacje))
        for row in range(0, self.model.rowCount()):
            self.table.openPersistentEditor(self.model.index(row, 2))
            self.table.openPersistentEditor(self.model.index(row, 6))

        # Zatwierdzenie
        ok_button = QPushButton("Dodaj")
        cancel_button = QPushButton("Cofnij")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(self.btn_odswiez)
        hbox.addWidget(ok_button)
        hbox.addWidget(cancel_button)

        # Layouty
        layout_v = QVBoxLayout()
        layout_h = QHBoxLayout()

        # Tabela
        self.proxy.setSourceModel(self.model)
        self.table.setModel(self.proxy)

        # przyporządkowanie
        layout_h.addWidget(self.lbl_w)
        layout_h.addWidget(self.edit_w)
        layout_v.addLayout(layout_h)
        layout_v.addWidget(self.table)
        self.formularz.setLayout(layout_v)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        # export
        # self.export()
        # Funkcje
        cancel_button.clicked.connect(self.anulowanie)
        ok_button.clicked.connect(self.dodaj)
        self.edit_w.textChanged.connect(self.wyszukiwanie)
        self.btn_odswiez.clicked.connect(self.refresh_db)
        self.skrot.activated.connect(self.refresh_db)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def prawoklik(self):
        menu = QMenu(self)
        if self.model.rowCount():
            akcja = QAction('Usuń wiersz', self)
            akcja.triggered.connect(self.usun_wiersz)
            menu.addAction(akcja)
            menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        ok = QMessageBox.question(self, 'Potwierdzenie',
                                  'Czy na pewno chcesz usunąć pozycję?',
                                  QMessageBox.Ok, QMessageBox.Cancel)
        if ok == QMessageBox.Ok:
            selected = self.table.currentIndex()
            self.model.removeRow(selected.row())
            self.model.submitAll()
            self.model.select()

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    @pyqtSlot()
    def uzupelniene(self):
        # Pobranie tp, tm z bazy
        query = 'SELECT iddetale, tm, tp, ilosc_m, ilosc_szt FROM detale'
        dane_db = multipolaczenie(query)
        for i in range(len(dane_db)):
            # if dane_db[i][1] and dane_db[i][2]:
            tm = dane_db[i][1]
            tp1 = dane_db[i][2]
            ilosc_m = dane_db[i][3]
            ilosc_szt = dane_db[i][4]
            if not ilosc_m:
                ilosc_m = 1
                zm = 1
            else:
                zm = 0.95
            if not ilosc_szt:
                ilosc_szt = 1
            if isinstance(tm, int) and isinstance(tp1, int):
                tw = tm + tp1
            else:
                tw = 0
            tp2 = tw * 0.05
            tj = (tw + tp2) * 1.1
            tjh = tj / 3600

            if tj != 0:
                norma = 8 / tj * 3600 * ilosc_m * zm * ilosc_szt
            else:
                norma = 0
            print(round(norma))
            # update bazy
            query = 'UPDATE "detale" SET "tj" = ' + str(round(
                tjh, 5)) + ', "norma" = ' + str(
                    round(norma)) + ' WHERE "iddetale" = ' + str(dane_db[i][0])
            update_bazy(query)
            # query = 'UPDATE "detale" SET "norma" = ' + str(round(norma)) +
            # ' WHERE "iddetale" = ' + str(dane_db[i][0]) update_bazy(query)

    @pyqtSlot()
    def refresh_db(self):
        try:
            self.uzupelniene()
        except:
            pass
        # Odświeżenie tabeli
        self.model.select()

    def tabela(self):
        self.model.setTable('detale')
        self.model.setRelation(
            12, QSqlRelation('uzytkownicy', 'iduzytkownicy', 'nazwa_uz'))
        # Za zmianę w bazie odpowiada OnFieldChange
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal,
                                     self.naglowki[nazwa_kolumn])
        self.model.select()

        # Odpowiada za edycję pojednynczym kliknieciem
        '''
        Constant    Value   Description
        QAbstractItemView::NoEditTriggers   0   No editing possible.
        QAbstractItemView::CurrentChanged   1   Editing start whenever current item changes.
        QAbstractItemView::DoubleClicked    2   Editing starts when an item is double clicked.
        QAbstractItemView::SelectedClicked  4   Editing starts when clicking on an already selected item.
        QAbstractItemView::EditKeyPressed   8   Editing starts when the platform edit key has been pressed over an item.
        QAbstractItemView::AnyKeyPressed    16  Editing starts when any key is pressed over an item.
        QAbstractItemView::AllEditTriggers  31  Editing starts for all above actions.
        '''
        if self.odczyt():
            self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.resizeColumnsToContents()
        self.table.setModel(self.model)
        self.table.setAlternatingRowColors(True)
        self.table.resizeColumnsToContents()

        # self.table.doubleClicked.connect(self.klikniecie)

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)

    def odczyt(self):
        id = str(self.parent.id_user[0])
        query = 'SELECT odczyt FROM uzytkownicy WHERE iduzytkownicy=' + id
        return polaczenie(query)[0]

    def dodaj(self):
        poz, masz, op, tm, tp, ok = MultiDialog().getMultidialog(self)
        print(poz, masz, op, tm, tp, ok)
        id = self.parent.id_user[0]
        if ok and poz:
            query = "INSERT INTO detale(nr_detalu,maszyna,nazwa_op,tm,tp," \
                    "id_uzytkownika) VALUES ('" + poz + "','" + masz + "','" + op + "','" + tm + "','" + tp + "','" + str(
                id) + "');"
            print(query)
            polaczenie(query)
            if tm and tp:
                try:
                    self.uzupelniene()
                except:
                    pass
            self.model.select()
            self.parent.statusBar().showMessage("Dodano nową pozycję", 10000)
        else:
            print("Nie wpisano pozycji")
Example #7
0
class APISFilm(QDialog, FORM_CLASS):

    FIRST, PREV, NEXT, LAST = range(4)
    OBLIQUE, VERTICAL = range(2)

    def __init__(self, iface, dbm, imageRegistry, apisLayer, parent=None):
        """Constructor."""
        super(APISFilm, self).__init__(parent)

        self.iface = iface
        self.dbm = dbm
        self.imageRegistry = imageRegistry
        self.apisLayer = apisLayer

        self.parent = parent

        self.setupUi(self)

        # Initial window size/pos last saved. Use default values for first time
        if GetWindowSize("film"):
            self.resize(GetWindowSize("film"))
        if GetWindowPos("film"):
            self.move(GetWindowPos("film"))

        self.printingOptionsDlg = None

        self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat)

        self.editMode = False
        self.addMode = False
        self.initalLoad = True

        #self.uiInitalEntryQgsDate.setCalendarPopup(False)
        #self.uiLastChangesQgsDate.setCalendarPopup(False)

        # Signals/Slot Connections
        self.rejected.connect(self.onReject)
        self.uiOkBtn.clicked.connect(self.onAccept)
        self.uiCancelBtn.clicked.connect(self.cancelEdit)
        self.uiSaveBtn.clicked.connect(self.saveEdits)

        self.uiFilmSelectionBtn.clicked.connect(self.openFilmSelectionDialog)

        self.uiNewFilmBtn.clicked.connect(self.openNewFilmDialog)
        self.uiSearchFilmBtn.clicked.connect(self.openSearchFilmDialog)
        self.uiEditWeatherBtn.clicked.connect(self.openEditWeatherDialog)

        self.uiExportPdfBtn.clicked.connect(self.exportDetailsPdf)

        self.uiShowFlightPathBtn.clicked.connect(lambda: self.openFlightPathDialog([self.uiCurrentFilmNumberEdit.text()]))

        # For LaLe Mode
        if self.settings.value("APIS/disable_site_and_findspot", "0") != "1":
            self.uiListSitesOfFilmBtn.setEnabled(True)
            self.uiListSitesOfFilmBtn.clicked.connect(self.openSiteSelectionListDialog)
        else:
            self.uiListSitesOfFilmBtn.setEnabled(False)

        self.uiListImagesOfFilmBtn.clicked.connect(self.openImageSelectionListDialog)
        self.uiExtractGpsFromImagesBtn.clicked.connect(self.extractGpsFromImages)

        self.uiWeatherCodeEdit.textChanged.connect(self.generateWeatherCode)
        self.uiFilmModeCombo.currentIndexChanged.connect(self.onFilmModeChanged)

        self.uiEditProjectTableBtn.clicked.connect(lambda: self.openSystemTableEditorDialog("projekt", self.uiProjectSelectionCombo))
        self.uiEditCopyrightTableBtn.clicked.connect(lambda: self.openSystemTableEditorDialog("copyright", self.uiCopyrightCombo))
        # self.uiEditProjectTableBtn.clicked.connect(lambda: VersionToCome())
        # self.uiEditCopyrightTableBtn.clicked.connect(lambda: VersionToCome())

        # init Project Btn
        self.uiAddProjectBtn.clicked.connect(self.addProject)
        self.uiRemoveProjectBtn.clicked.connect(self.removeProject)

        # Setup Sub-Dialogs
        self.filmSelectionDlg = APISFilmNumberSelection(self)
        self.newFilmDlg = APISFilmNew(parent=self)
        self.searchFilmDlg = APISFilmSearch(self.dbm, self)  # (self.iface, self.dbm)
        self.editWeatherDlg = APISWeather(self.iface, self.dbm, self)
        self.flightPathDlg = APISFlightPath(self.iface, self.dbm, self.apisLayer, self)
        self.siteSelectionListDlg = APISSiteSelectionList(self.iface, self.dbm, self.imageRegistry, self.apisLayer, self)
        self.imageSelectionListDlg = APISImageSelectionList(self.iface, self.dbm, self.imageRegistry,  self.apisLayer, parent=self)
        self.systemTableEditorDlg = None

        # Setup film model
        self.model = QSqlRelationalTableModel(self, self.dbm.db)
        self.model.setTable("film")
        self.model.select()

        while (self.model.canFetchMore()):
            self.model.fetchMore()

        self.setupMapper()
        self.setupComboBox(self.uiProjectSelectionCombo, "projekt", 0, None)

        self.setupComboBox(self.newFilmDlg.uiProducerCombo, "hersteller", 2, None)

        self.setupNavigation()

        self.mapper.toFirst()

        self.initalLoad = False

    def setupMapper(self):
        self.mapper = QDataWidgetMapper(self)

        self.mapper.currentIndexChanged.connect(self.onCurrentIndexChanged)

        self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
        self.mapper.setItemDelegate(FilmDelegate())

        self.mapper.setModel(self.model)

        self.mandatoryEditors = [self.uiImageCountEdit, self.uiCameraCombo, self.uiFilmMakeCombo, self.uiFilmModeCombo]
        self.disableEditorsIfOblique = [self.uiCameraNumberEdit, self.uiCalibratedFocalLengthEdit]
        # LineEdits & PlainTextEdits
        self.intValidator = QIntValidator()
        self.doubleValidator = QDoubleValidator()
        self.lineEditMaps = {
            "filmnummer": {
                "editor": self.uiCurrentFilmNumberEdit
            },
            "hersteller": {
                "editor": self.uiProducerEdit
            },
            "anzahl_bilder": {
                "editor": self.uiImageCountEdit,
                "validator": self.intValidator
            },
            "militaernummer": {
                "editor": self.uiMilitaryNumberEdit
            },
            "militaernummer_alt": {
                "editor": self.uiOldMilitaryNumberEdit
            },
            "form1": {
                "editor": self.uiFormat1Edit
            },
            "form2": {
                "editor": self.uiFormat2Edit
            },
            "kalibrierungsnummer": {
                "editor": self.uiCameraNumberEdit
            },
            "kammerkonstante": {
                "editor": self.uiCalibratedFocalLengthEdit,
                "validator": self.doubleValidator
            },
            "kassettennummer": {
                "editor": self.uiCassetteEdit
            },
            "art_ausarbeitung": {
                "editor": self.uiFilmMakeEdit
            },
            "fotograf": {
                "editor": self.uiPhotographerEdit
            },
            "pilot": {
                "editor": self.uiPilotEdit
            },
            "flugzeug": {
                "editor": self.uiAirplaneEdit
            },
            "abflug_flughafen": {
                "editor": self.uiDepartureAirportEdit
            },
            "ankunft_flughafen": {
                "editor": self.uiArrivalAirportEdit
            },
            "flugzeit": {
                "editor": self.uiFlightDurationEdit
            },
            "wetter": {
                "editor": self.uiWeatherCodeEdit
            },
            "kommentar": {
                "editor": self.uiCommentsPTxt
            }
        }
        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)
        #Text
        #self.mapper.addMapping(self.uiCommentsPTxt, self.model.fieldIndex("kommentar"))

        # Date and Times
        self.mapper.addMapping(self.uiFlightDate, self.model.fieldIndex("flugdatum"))
        #self.mapper.addMapping(self.uiFlightQgsDate, self.model.fieldIndex("flugdatum"))
        self.mapper.addMapping(self.uiInitalEntryDate, self.model.fieldIndex("datum_ersteintrag"))
        #self.mapper.addMapping(self.uiInitalEntryQgsDate, self.model.fieldIndex("datum_ersteintrag"))
        self.mapper.addMapping(self.uiLastChangesDate, self.model.fieldIndex("datum_aenderung"))
        #self.mapper.addMapping(self.uiLastChangesQgsDate, self.model.fieldIndex("datum_aenderung"))

        self.mapper.addMapping(self.uiDepartureTime, self.model.fieldIndex("abflug_zeit"))
        self.mapper.addMapping(self.uiArrivalTime, self.model.fieldIndex("ankunft_zeit"))
        self.uiDepartureTime.timeChanged.connect(self.onFlightTimeChanged)
        self.uiArrivalTime.timeChanged.connect(self.onFlightTimeChanged)

        # ComboBox without Model
        self.mapper.addMapping(self.uiFilmModeCombo, self.model.fieldIndex("weise"))
        self.uiFilmModeCombo.editTextChanged.connect(self.onLineEditChanged)
        completer = QCompleter(self.uiFilmModeCombo.model())
        self.uiFilmModeCombo.setCompleter(completer)
        self.uiFilmModeCombo.lineEdit().setValidator(InListValidator([self.uiFilmModeCombo.itemText(i) for i in range(self.uiFilmModeCombo.count())], self.uiFilmModeCombo.lineEdit(), None, self))

        # ComboBox with Model
        self.comboBoxMaps = {
            "archiv": {
                "editor": self.uiArchiveCombo,
                "table": "hersteller",
                "modelcolumn": 2,
                "depend": None
            },
            "kamera": {
                "editor": self.uiCameraCombo,
                "table": "kamera",
                "modelcolumn": 0,
                "depend": [{"form1": self.uiFormat1Edit}, {"form2": self.uiFormat2Edit}]
            },
            "filmfabrikat": {
                "editor": self.uiFilmMakeCombo,
                "table": "film_fabrikat",
                "modelcolumn": 0,
                "depend": [{"art": self.uiFilmMakeEdit}]
            },
            "target": {
                "editor": self.uiTargetCombo,
                "table": "target",
                "modelcolumn": 0,
                "depend": None
            },
            "copyright": {
                "editor": self.uiCopyrightCombo,
                "table": "copyright",
                "modelcolumn": 0,
                "depend": None
            }
        }
        for key, item in self.comboBoxMaps.items():
            self.mapper.addMapping(item["editor"], self.model.fieldIndex(key))
            self.setupComboBox(item["editor"], item["table"], item["modelcolumn"], item["depend"])
            item["editor"].editTextChanged.connect(self.onLineEditChanged)

        self.mapper.addMapping(self.uiProjectList, self.model.fieldIndex("projekt"))

    def fixComboBoxDropDownListSizeAdjustemnt(self, cb):
        scroll = 0 if cb.count() <= cb.maxVisibleItems() else QApplication.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        iconWidth = cb.iconSize().width()
        max = 0

        for i in range(cb.count()):
            width = cb.view().fontMetrics().width(cb.itemText(i))
            if max < width:
                max = width

        QMessageBox.information(self, "info", "scroll: {0}, max: {1}, icon: {2}".format(scroll, max, iconWidth))

        #cb.view().setMinimumWidth(scroll + max)

    def setupComboBox(self, editor, table, modelColumn, depend):
        model = QSqlRelationalTableModel(self, self.dbm.db)
        model.setTable(table)
        model.removeColumn(0)
        model.select()

        tv = QTableView()
        editor.setView(tv)

        tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        tv.setSelectionMode(QAbstractItemView.SingleSelection)
        tv.setSelectionBehavior(QAbstractItemView.SelectRows)
        tv.setAutoScroll(False)

        editor.setModel(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)
        #self.fixComboBoxDropDownListSizeAdjustemnt(editor)

        #editor.resize(tv.horizontalHeader().sizeHint())

        completer = QCompleter(editor.model())
        editor.setCompleter(completer)
        #editor.setAutoCompletion(True)
        editor.lineEdit().setValidator(InListValidator([editor.itemText(i) for i in range(editor.count())], editor.lineEdit(), depend, self))

        if depend:
            editor.currentIndexChanged.connect(partial(self.updateDepends, editor, depend))

    def updateDepends(self, editor, depend):
        for dep in depend:
            for key, value in dep.items():
                idx = editor.model().createIndex(editor.currentIndex(), editor.model().fieldIndex(key))
                value.setText(str(editor.model().data(idx)))
                #QMessageBox.warning(None, "Test", str(idx))

    def setupNavigation(self):
        self.uiFirstFilmBtn.clicked.connect(partial(self.loadRecordByNavigation, APISFilm.FIRST))
        self.uiPreviousFilmBtn.clicked.connect(partial(self.loadRecordByNavigation, APISFilm.PREV))
        self.uiNextFilmBtn.clicked.connect(partial(self.loadRecordByNavigation, APISFilm.NEXT))
        self.uiLastFilmBtn.clicked.connect(partial(self.loadRecordByNavigation, APISFilm.LAST))

        self.uiTotalFilmCountLbl.setText(str(self.model.rowCount()))
        self.intRecordValidator = QIntValidator(1, self.model.rowCount())
        self.uiCurrentFilmCountEdit.setValidator(self.intRecordValidator)
        self.uiCurrentFilmCountEdit.setText(str(self.mapper.currentIndex() + 1))
        self.uiCurrentFilmCountEdit.editingFinished.connect(lambda: self.loadRecordById(int(self.uiCurrentFilmCountEdit.text()) - 1))
        # QMessageBox.warning(None, "Test", str(self.mapper.itemDelegate()))

    def enableItemsInLayout(self, layout, enable):
        for i in range(layout.count()):
            if layout.itemAt(i).widget():
                layout.itemAt(i).widget().setEnabled(enable)

    def loadRecordByNavigation(self, mode):
        #self.mapper.submit()
        #self.submitChanges()
        self.initalLoad = True
        if mode == APISFilm.FIRST:
            self.mapper.toFirst()
        elif mode == APISFilm.PREV:
            self.mapper.toPrevious()
        elif mode == APISFilm.NEXT:
            self.mapper.toNext()
        elif mode == APISFilm.LAST:
            self.mapper.toLast()
        self.initalLoad = False

    def loadRecordById(self, id):
        #self.submitChanges
        self.initalLoad = True
        self.mapper.setCurrentIndex(id)
        self.initalLoad = False

    def loadRecordByKeyAttribute(self, attribute, value):
        #self.model.setFilter(attribute + " = '" + value + "'")
        #self.model.select()
        # self.mapper.toFirst()

        query = QSqlQuery(self.dbm.db)
        #qryStr = "select {0} from film where {0} = '{1}' limit 1".format(attribute, value)
        #qryStr = "SELECT rowid FROM film WHERE {0} = '{1}' limit 1".format(attribute, value)
        qryStr = "SELECT" \
                 "  (SELECT COUNT(*)" \
                 "       FROM film AS t2" \
                 "       WHERE t2.rowid < t1.rowid" \
                 "      ) + (" \
                 "         SELECT COUNT(*)" \
                 "         FROM film AS t3" \
                 "        WHERE t3.rowid = t1.rowid AND t3.rowid < t1.rowid" \
                 "      ) AS rowNum" \
                 "   FROM film AS t1" \
                 "   WHERE {0} = '{1}'" \
                 "   ORDER BY t1.rowid ASC".format(attribute, value)

        query.exec_(qryStr)

        #QMessageBox.warning(None, "Test", str(query.size()) + ',' + str(query.numRowsAffected()))

        query.first()
        fn = query.value(0)

        if fn is not None:
            self.loadRecordById(fn)
            return True
        else:
            # Film does not exist
            QMessageBox.warning(None, "Film Nummer", str("Der Film mit der Nummer {0} existiert nicht!".format(value)))
            return False

        #self.model.setFilter('')
        #self.model.select()
        #while (self.model.canFetchMore()):
            #self.model.fetchMore()

    def submitChanges(self):
        self.mapper.submit()

    def onCurrentIndexChanged(self):
        self.uiCurrentFilmCountEdit.setText(str(self.mapper.currentIndex() + 1))
        self.onFilmModeChanged()

    def onFlightTimeChanged(self):
        dTime = self.uiDepartureTime.time()
        aTime = self.uiArrivalTime.time()
        flightDuration = dTime.secsTo(aTime)
        self.uiFlightDurationEdit.setText(str(flightDuration / 60))

    def disableIfOblique(self, isOblique):
        for editor in self.disableEditorsIfOblique:
            editor.setDisabled(isOblique)

    def onFilmModeChanged(self):
        if self.uiFilmModeCombo.currentText() == u'schräg':
            self.disableIfOblique(True)
        else:
            self.disableIfOblique(False)

    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 onComboBoxChanged(self, editor):
        pass

    def addProject(self):
        editor = self.uiProjectList
        value = self.uiProjectSelectionCombo.currentText()
        notInList = True
        for row in range(editor.count()):
            if value == editor.item(row).data(0):
                notInList = False
                break
        if notInList:
            editor.addItem(value)
            editor.sortItems()
            if not self.editMode and not self.initalLoad:
                self.startEditMode()
            if not self.initalLoad:
                editor.setStyleSheet("{0} {{background-color: rgb(153, 204, 255);}}".format(editor.metaObject().className()))
                self.editorsEdited.append(editor)

    def removeProject(self):
        editor = self.uiProjectList
        editor.takeItem(self.uiProjectList.currentRow())
        if not self.editMode and not self.initalLoad:
            self.startEditMode()
        if not self.initalLoad:
            editor.setStyleSheet("{0} {{background-color: rgb(153, 204, 255);}}".format(editor.metaObject().className()))
            self.editorsEdited.append(editor)

    def onAccept(self):
        '''
        Check DB
        Save options when pressing OK button
        Update Plugin Status
        '''
        self.accept()

    def onReject(self):
        '''
        Run some actions when
        the user closes the dialog
        '''
        if self.editMode:
            res = self.cancelEdit()
            if res:
                self.close()
            else:
                self.show()
        else:
            self.close()

    def closeEvent(self, e):
        # Write window size and position to QSettings
        if self.editMode:
            self.onReject()
        else:
            SetWindowSizeAndPos("film", self.size(), self.pos())
            e.accept()

    def extractGpsFromImages(self):
        key = self.uiCurrentFilmNumberEdit.text()
        e2p = Exif2Points(self.iface, key)
        layer = e2p.run()
        if layer:
            self.apisLayer.requestShapeFile(layer, groupName="Flugwege", addToCanvas=True)

    def exportDetailsPdf(self):
        if self.printingOptionsDlg is None:
            self.printingOptionsDlg = APISPrintingOptions(self)
            self.printingOptionsDlg.setWindowTitle("Druck Optionen: Film")
            self.printingOptionsDlg.configure(False, False, visPersonalDataChk=True)

        self.printingOptionsDlg.show()

        if self.printingOptionsDlg.exec_():
            printPersonalData = self.printingOptionsDlg.printPersonalData()
            APISPrinterQueue([{'type': APISTemplatePrinter.FILM, 'idList': [self.uiCurrentFilmNumberEdit.text()], 'options': {'personalData': printPersonalData}}],
                             OutputMode.MergeNone,
                             openFile=self.printingOptionsDlg.uiOpenFilesChk.isChecked(),
                             openFolder=self.printingOptionsDlg.uiOpenFolderChk.isChecked(),
                             dbm=self.dbm,
                             parent=self)

    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()

            #QMessageBox.warning(None, "FilmNumber", u"{0}, rows: {1}".format(self.searchFilmDlg.generateSearchQuery(), model.rowCount()))

            # Get Search String/Query
            #if not self.loadRecordByKeyAttribute("filmnummer", self.filmSelectionDlg.filmNumber()):
                #self.openFilmSelectionDialog()

    def openFilmSelectionDialog(self):
        """Run method that performs all the real work"""
        self.filmSelectionDlg.show()
        self.filmSelectionDlg.uiFilmNumberEdit.setFocus()
        if self.filmSelectionDlg.exec_():
            if not self.loadRecordByKeyAttribute("filmnummer", self.filmSelectionDlg.filmNumber()):
                self.openFilmSelectionDialog()

    def openNewFilmDialog(self):
        """Run method that performs all the real work"""
        self.newFilmDlg.show()
        if self.newFilmDlg.exec_():
            self.addNewFilm(self.newFilmDlg.flightDate(), self.newFilmDlg.useLastEntry(), self.newFilmDlg.producer(), self.newFilmDlg.producerCode())

    def openEditWeatherDialog(self):
        self.editWeatherDlg.setWeatherCode(self.uiWeatherCodeEdit.text())
        self.editWeatherDlg.show()

        if self.editWeatherDlg.exec_():
            self.uiWeatherCodeEdit.setText(self.editWeatherDlg.weatherCode())
            #self.uiWeatherPTxt.setPlainText(self.editWeatherDlg.weatherDescription())

    def generateWeatherCode(self):
        weatherDescription = self._generateWeatherCode(self.uiWeatherCodeEdit.text())
        self.uiWeatherPTxt.setPlainText(weatherDescription)

    def _generateWeatherCode(self, weatherCode):
        categories = ["Low Cloud Amount", "Visibility Kilometres", "Low Cloud Height", "Weather", "Remarks Mission", "Remarks Weather"]
        query = QSqlQuery(self.dbm.db)
        pos = 0
        help = 0
        weatherDescription = ""
        for c in weatherCode:
            qryStr = "select description from wetter where category = '{0}' and code = '{1}' limit 1".format(categories[pos - help], c)
            query.exec_(qryStr)
            query.first()
            fn = query.value(0)
            if pos <= 5:
                weatherDescription += categories[pos] + ': ' + fn
                if pos < 5:
                    weatherDescription += '\n'
            else:
                weatherDescription += '; ' + fn

            if pos >= 5:
                help += 1
            pos += 1
        return weatherDescription

    def openSystemTableEditorDialog(self, table, updateEditor):
        if self.dbm:
            self.systemTableEditorDlg = APISAdvancedInputDialog(self.dbm, table, False, parent=self)

            if self.systemTableEditorDlg.tableExists:
                if self.systemTableEditorDlg.exec_():
                    # See if OK was pressed
                    # rec = self.systemTableEditorDlg.getRecord()
                    # Update updateEditor
                    # self.setupComboBox(self.uiProjectSelectionCombo, "projekt", 0, None)
                    self.updateComboBox(updateEditor)

            else:
                QMessageBox.warning(self, "Tabelle nicht vorhanden", "Die Tabelle {0} ist in der APIS Datenbank nicht vorhanden".format(table))

        else:
            QMessageBox.warning(self, "Warning Database", "Die APIS Datenbank konnte nicht gefunden werden.")

    def updateComboBox(self, updateEditor):
        updateEditor.model().select()
        tv = updateEditor.view()
        tv.resizeRowsToContents()
        tv.resizeColumnsToContents()
        scroll = 0 if updateEditor.count() <= updateEditor.maxVisibleItems() else QApplication.style().pixelMetric(
            QStyle.PM_ScrollBarExtent)
        tv.setMinimumWidth(tv.horizontalHeader().length() + scroll)
        updateEditor.setCurrentIndex(updateEditor.count() - 1)
        if updateEditor.validator():
            updateEditor.lineEdit().setValidator(
                InListValidator([updateEditor.itemText(i) for i in range(updateEditor.count())],
                                updateEditor.lineEdit(), None, self))

    def openFlightPathDialog(self, filmList, toClose=None):
        self.flightPathDlg.viewFilms(filmList)  # DEBUG
        self.flightPathDlg.show()

        if self.flightPathDlg.exec_():
            #TODO load Data in TOC, Close Windows
            if toClose:
                toClose.close()
            self.close()

    def openSiteSelectionListDialog(self):
        if self.uiFilmModeCombo.currentIndex() == APISFilm.VERTICAL:
            fromTable = "luftbild_senk_fp"
        elif self.uiFilmModeCombo.currentIndex() == APISFilm.OBLIQUE:
            fromTable = "luftbild_schraeg_fp"

        query = QSqlQuery(self.dbm.db)
        query.prepare("SELECT fundortnummer, flurname, katastralgemeinde, fundgewinnung, sicherheit FROM fundort WHERE fundortnummer IN (SELECT DISTINCT fo.fundortnummer FROM fundort fo, {0} WHERE fo.geometry IS NOT NULL AND {0}.geometry IS NOT NULL AND {0}.filmnummer = '{1}' AND Intersects({0}.geometry, fo.geometry) AND fo.ROWID IN (SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'fundort' AND search_frame = {0}.geometry)) ORDER BY katastralgemeindenummer, land, fundortnummer_nn".format(fromTable, self.uiCurrentFilmNumberEdit.text()))
        query.exec_()
        info = u"gefunden, die vom Film {0} abgedeckt/geschnitten werden.".format(self.uiCurrentFilmNumberEdit.text())
        res = self.siteSelectionListDlg.loadSiteListBySpatialQuery(query, info)
        if res:
            self.siteSelectionListDlg.show()
            if self.siteSelectionListDlg.exec_():
                pass

    def openImageSelectionListDialog(self):
        if self.uiFilmModeCombo.currentIndex() == APISFilm.VERTICAL:
            fromTable = 'luftbild_senk_cp'
            spatialIndicator = 'massstab'
        elif self.uiFilmModeCombo.currentIndex() == APISFilm.OBLIQUE:
            fromTable = 'luftbild_schraeg_cp'
            spatialIndicator = 'radius'

        query = QSqlQuery(self.dbm.db)
        query.prepare("SELECT cp.bildnummer AS bildnummer, cp.filmnummer AS filmnummer, cp.{2} AS mst_radius, f.weise AS weise, f.art_ausarbeitung AS art FROM {0} AS cp, film AS f WHERE cp.filmnummer = '{1}' AND f.filmnummer = '{1}'".format(fromTable, self.uiCurrentFilmNumberEdit.text(), spatialIndicator))
        query.exec_()
        res = self.imageSelectionListDlg.loadImageListBySqlQuery(query)
        if res:
            self.imageSelectionListDlg.show()
            if self.imageSelectionListDlg.exec_():
                pass

    def addNewFilm(self, flightDate, useLastEntry, producer, producerCode):
        self.initalLoad = True
        self.addMode = True
        self.startEditMode()
        row = self.model.rowCount()
        self.mapper.submit()
        while (self.model.canFetchMore()):
            self.model.fetchMore()

        self.model.insertRow(row)

        if useLastEntry:
            #copy last row
            for c in range(1, self.model.columnCount()):
                value = self.model.data(self.model.createIndex(row - 1, c))
                self.model.setData(self.model.createIndex(row, c), value)
                editor = self.mapper.mappedWidgetAt(c)

                if editor and not (value == 'NULL' or value == ''):
                    cName = editor.metaObject().className()
                    if (cName == "QLineEdit" or cName == "QDateEdit") and editor.isReadOnly():
                        pass
                    else:
                        editor.setStyleSheet("{0} {{background-color: rgb(153, 204, 255);}}".format(editor.metaObject().className()))
                        self.editorsEdited.append(editor)

        self.mapper.setCurrentIndex(row)

        self.uiTotalFilmCountLbl.setText(str(self.model.rowCount()))
        self.uiFlightDate.setDate(flightDate)
        #self.uiFlightQgsDate.setDate(flightDate)
        self.uiProducerEdit.setText(producer)
        self.uiArchiveCombo.lineEdit().setText(producer)
        if not useLastEntry:
            self.uiWeatherCodeEdit.setText("9990X")

        #now = QDateTime.currentDateTime()
        now = QDate.currentDate()
        self.uiInitalEntryDate.setDate(now)
        #self.uiInitalEntryQgsDate.setDateTime(now)
        self.uiLastChangesDate.setDate(now)
        #self.uiLastChangesQgsDate.setDateTime(now)
        self.uiFilmModeCombo.setEnabled(True)

        #Filmnummer
        hh = producerCode
        yyyy = flightDate.toString("yyyy")
        mm = flightDate.toString("MM")

        query = QSqlQuery(self.dbm.db)
        qryStr = "select max(filmnummer_nn) from film where filmnummer_hh_jjjj_mm = '{0}{1}{2}' limit 1".format(hh, yyyy, mm)
        query.exec_(qryStr)
        query.first()
        fn = query.value(0)

        if isinstance(fn, int):
            nn = str(fn + 1).zfill(2)
        else:
            nn = "01"
        self.uiCurrentFilmNumberEdit.setText("{0}{1}{2}{3}".format(hh, yyyy, mm, nn))

        self.initalLoad = False

    def removeNewFilm(self):
        self.initalLoad = True
        row = self.mapper.currentIndex()
        self.model.removeRow(row)
        self.model.submitAll()
        while (self.model.canFetchMore()):
            self.model.fetchMore()
        self.uiTotalFilmCountLbl.setText(str(self.model.rowCount()))
        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 == 'QLineEdit':
                value = mEditor.text()
            elif cName == 'QComboBox':
                value = mEditor.lineEdit().text()
            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()
        #now = QDateTime.currentDateTime()
        now = QDate.currentDate()
        self.uiLastChangesDate.setDate(now)
        #self.uiLastChangesQgsDate.setDateTime(now)

        res = self.mapper.submit()

        if not res:
            sqlError = self.mapper.model().lastError()
            QMessageBox.information(self, "Submit", u"Error: {0}, {1}".format(res, sqlError.text()))

        while (self.model.canFetchMore()):
            self.model.fetchMore()

        self.mapper.setCurrentIndex(currIdx)
        self.endEditMode()
        return True

    def cancelEdit(self):
        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.removeNewFilm()

                self.mapper.setCurrentIndex(self.mapper.currentIndex())
                self.endEditMode()
                return True

    def startEditMode(self):
        self.editMode = True
        self.enableItemsInLayout(self.uiTopHorizontalLayout, False)
        self.enableItemsInLayout(self.uiBottomHorizontalLayout, False)
        self.uiOkBtn.setEnabled(False)
        self.uiSaveBtn.setEnabled(True)
        self.uiCancelBtn.setEnabled(True)
        self.editorsEdited = []

    def endEditMode(self):
        self.editMode = False
        self.addMode = False
        self.enableItemsInLayout(self.uiTopHorizontalLayout, True)
        self.enableItemsInLayout(self.uiBottomHorizontalLayout, True)
        self.uiOkBtn.setEnabled(True)
        self.uiSaveBtn.setEnabled(False)
        self.uiCancelBtn.setEnabled(False)
        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 = []

        self.uiFilmModeCombo.setEnabled(False)

    def showEvent(self, evnt):
        # QMessageBox.information(self, "info", "db requires update: {0}".format(self.dbm.dbRequiresUpdate))

        if self.dbm.dbRequiresUpdate:
            self.initalLoad = True
            for editor in [self.uiArchiveCombo, self.uiCameraCombo, self.uiFilmMakeCombo, self.uiCopyrightCombo, self.uiProjectSelectionCombo, self.newFilmDlg.uiProducerCombo]:
                self.updateComboBox(editor)
            currIdx = self.mapper.currentIndex()
            self.model.select()
            while (self.model.canFetchMore()):
                self.model.fetchMore()
            self.mapper.setCurrentIndex(currIdx)
            self.dbm.dbRequiresUpdate = False
            self.initalLoad = False
Example #8
0
class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.db_path = r'database\sklad_db.sqlite3'
        self.ui.path_db.setText(self.db_path)

        self.save_db = QAction(QIcon('icon/save.png'), 'Сохранить', self)
        self.find_db_file = QAction(QIcon('icon/open_db.png'), 'Открыть БД',
                                    self)
        self.add_rec = QAction(QIcon('icon/add.png'), 'Добавить запись', self)
        self.del_rec = QAction(QIcon('icon/del.png'), 'Удалить запись', self)
        self.ui.toolBar.addAction(self.save_db)
        self.ui.toolBar.addAction(self.find_db_file)
        self.ui.toolBar.addAction(self.add_rec)
        self.ui.toolBar.addAction(self.del_rec)
        self.db = None
        self.table_model = None

        self.open_db()

        self.add_rec.triggered.connect(self.add_record_action)
        self.del_rec.triggered.connect(self.del_record_action)
        self.save_db.triggered.connect(self.save_change_db)
        self.find_db_file.triggered.connect(self.find_db_file_action)
        self.ui.comboBox.currentIndexChanged.connect(self.show_table)

    def open_db(self):
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(self.db_path)
        self.db.open()
        self.get_table_name()
        self.show_table()

    def get_table_name(self):
        self.ui.comboBox.clear()
        table_name_ru = None
        for table_name in self.db.tables():
            if table_name == 'goods':
                table_name_ru = 'Товары'
            elif table_name == 'categories':
                table_name_ru = 'Категории'
            elif table_name == 'units':
                table_name_ru = 'Единица измерения'
            elif table_name == 'employees':
                table_name_ru = 'Персонал'
            elif table_name == 'positions':
                table_name_ru = 'Должности'
            elif table_name == 'vendors':
                table_name_ru = 'Поставщики'
            self.ui.comboBox.addItem(table_name_ru)

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()
        table = self.ui.comboBox.currentText()
        if table == 'Товары':
            self.create_goods_table_model()
        elif table == 'Персонал':
            self.create_employees_table_model()
        else:
            if table == 'Единица измерения':
                table = 'units'
            elif table == 'Категории':
                table = 'categories'
            elif table == 'Должности':
                table = 'positions'
            elif table == 'Поставщики':
                table = 'vendors'
            self.table_model.setTable(table)
            self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableView
        view.setModel(self.table_model)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def create_goods_table_model(self):
        self.table_model.setTable('goods')
        self.table_model.setRelation(2, QSqlRelation('units', 'unit_id',
                                                     'unit'))
        self.table_model.setRelation(
            3, QSqlRelation('categories', 'category_id', 'category_name'))
        self.table_model.select()

    def create_employees_table_model(self):
        self.table_model.setTable('employees')
        self.table_model.setRelation(
            2, QSqlRelation('positions', 'position_id', 'position'))
        self.table_model.select()

    def add_record_action(self):
        self.ui.statusbar.clearMessage()
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def del_record_action(self):
        self.ui.statusbar.clearMessage()
        rs = list(map(lambda x: x.row(), self.ui.tableView.selectedIndexes()))
        #print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)

    def find_db_file_action(self):
        self.db_path = QFileDialog.getOpenFileName(self, "Open file")[0]
        self.ui.path_db.setText(self.db_path)
        self.db.close()
        self.open_db()

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Изменения сохранены')
        else:
            self.ui.statusbar.showMessage(
                f'{self.table_model.lastError().text()}')
Example #9
0
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_()
Example #10
0
class QmyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setCentralWidget(self.ui.tableView)

        self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(100)

    def __getFieldNames(self):
        emptyRec = self.tabModel.record()
        self.fldNum = {}
        for i in range(emptyRec.count()):
            fieldName = emptyRec.fieldName(i)
            self.fldNum.setdefault(fieldName)
            self.fldNum[fieldName] = i
        print(self.fldNum)

    def __openTable(self):
        self.tabModel = QSqlRelationalTableModel(self, self.DB)
        self.tabModel.setTable("studInfo")
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.tabModel.setSort(self.tabModel.fieldIndex("studID"),
                              Qt.AscendingOrder)

        if (self.tabModel.select() == False):
            QMessageBox.critical(
                self, "错误信息",
                "打开数据表错误,错误信息\n" + self.tabModel.lastError().text())
            return

        self.__getFieldNames()
        self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号")
        self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal,
                                    "学院")
        self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal,
                                    "专业")

        self.tabModel.setRelation(
            self.fldNum["departID"],
            QSqlRelation("departments", "departID", "department"))
        self.tabModel.setRelation(self.fldNum["majorID"],
                                  QSqlRelation("majors", "majorID", "major"))

        self.selModel = QItemSelectionModel(self.tabModel)
        self.selModel.currentChanged.connect(self.do_currentChanged)

        self.ui.tableView.setModel(self.tabModel)
        self.ui.tableView.setSelectionModel(self.selModel)

        delgate = QSqlRelationalDelegate(self.ui.tableView)
        self.ui.tableView.setItemDelegate(delgate)

        self.tabModel.select()

        self.ui.actOpenDB.setEnabled(False)
        self.ui.actRecAppend.setEnabled(True)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actFields.setEnabled(True)

    @pyqtSlot()
    def on_actOpenDB_triggered(self):
        dbFilename, flt = QFileDialog.getOpenFileName(
            self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)")
        if (dbFilename == ''):
            return
        self.DB = QSqlDatabase.addDatabase("QSQLITE")
        self.DB.setDatabaseName(dbFilename)
        if self.DB.open():
            self.__openTable()
        else:
            QMessageBox.warning(self, "错误", "打开数据库失败了")

    @pyqtSlot()
    def on_actSubmit_triggered(self):
        res = self.tabModel.submitAll()
        if (res == False):
            QMessageBox.information(
                self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text())
        else:
            self.ui.actSubmit.setEnabled(False)
            self.ui.actRevert.setEnabled(False)

    @pyqtSlot()
    def on_actRevert_triggered(self):
        self.tabModel.revertAll()
        self.ui.actSubmit.setEnabled(False)
        self.ui.actRevert.setEnabled(False)

    @pyqtSlot()
    def on_actRecInsert_triggered(self):
        curIndex = self.ui.tableView.currentIndex()
        self.tabModel.insertRow(curIndex.row(), QModelIndex())
        self.selModel.clearSelection()
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

    @pyqtSlot()
    def on_actRecDelete_triggered(self):
        curIndex = self.selModel.currentIndex()
        self.tabModel.removeRow(curIndex.row())

    @pyqtSlot()
    def on_actFields_triggered(self):
        emptyRec = self.tabModel.record()
        str = ''
        for i in range(emptyRec.count()):
            str = str + emptyRec.fieldName(i) + '\n'
        QMessageBox.information(self, "所有字段名", str)

    def do_currentChanged(self, current, previous):
        self.ui.actSubmit.setEnabled(self.tabModel.isDirty())
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())
class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = mainform.Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.db_path = r'db/db_test.sqlite3'
        self.ui.lbl_full_path_db.setText(self.db_path)
        self.ui.btn_db_open.clicked.connect(self.db_file_open)
        self.ui.btn_add.clicked.connect(self.db_add)
        self.ui.btn_add.setEnabled(False)
        self.ui.btn_del.clicked.connect(self.db_del)
        self.ui.btn_del.setEnabled(False)
        self.ui.save_changes.clicked.connect(self.save_change_db)
        self.ui.save_changes.setEnabled(False)
        self.ui.mnu_exit.triggered.connect(self.close)
        self.ui.tablelist.setEnabled(False)
        self.db = None
        self.db_model = None
        self.open_db()
        self.ui.tablelist.currentIndexChanged.connect(self.show_table)

    def open_db(self):
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(self.db_path)
        self.db.open()
        self.get_tables_name()
        # self.show_table()

    def get_tables_name(self):
        self.ui.tablelist.clear()
        for table_name in self.db.tables():
            self.ui.tablelist.addItem(table_name)

    def db_file_open(self):
        self.db_path = QFileDialog.getOpenFileName(self, "Open file")[0]
        self.ui.lbl_full_path_db.setText(self.db_path)
        self.db.close()
        self.open_db()
        self.ui.tablelist.setEnabled(True)
        self.ui.btn_add.setEnabled(True)
        self.ui.btn_del.setEnabled(True)
        self.ui.save_changes.setEnabled(True)
        self.ui.btn_db_open.setEnabled(False)

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()
        table = self.ui.tablelist.currentText()
        if table == 'goods':
            self.create_goods_table_model()
        elif table == 'employees':
            self.create_employees_table_model()
        elif table == 'units':
            self.create_units_table_model()
        elif table == 'vendors':
            self.create_vendors_table_model()
        elif table == 'positions':
            self.create_positions_table_model()
        elif table == 'categories':
            self.create_categories_table_model()
        else:
            self.table_model.setTable(table)
            self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableView
        view.setModel(self.table_model)
        view.hideColumn(0)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def db_add(self):
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def db_del(self):
        rs = list(map(lambda x: x.row(), self.ui.tableView.selectedIndexes()))
        print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)

    def create_goods_table_model(self):
        self.table_model.setTable('goods')
        self.table_model.setRelation(
            2, QSqlRelation('units', 'unit_id', 'unit_name'))
        self.table_model.setRelation(
            3, QSqlRelation('categories', 'category_id', 'category_name'))
        self.table_model.setRelation(
            4, QSqlRelation('vendors', 'vendor_id', 'vendor_name'))
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal,
                                       'Название продукта')
        self.table_model.setHeaderData(2, QtCore.Qt.Horizontal,
                                       'Единица измерения')
        self.table_model.setHeaderData(3, QtCore.Qt.Horizontal,
                                       'Категория продукта')
        self.table_model.setHeaderData(4, QtCore.Qt.Horizontal, 'Поставщик')
        self.table_model.select()

    def create_units_table_model(self):
        self.table_model.setTable('units')
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal,
                                       'Единица измерения')
        self.table_model.select()

    def create_employees_table_model(self):
        self.table_model.setTable('employees')
        self.table_model.setRelation(
            2, QSqlRelation('positions', 'position_id', 'position_name'))
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal,
                                       'ФИО сотрудника')
        self.table_model.setHeaderData(2, QtCore.Qt.Horizontal, 'Должность')
        self.table_model.select()

    def create_positions_table_model(self):
        self.table_model.setTable('positions')
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal, 'Должность')
        self.table_model.select()

    def create_vendors_table_model(self):
        self.table_model.setTable('vendors')
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal, 'Наименование')
        self.table_model.setHeaderData(2, QtCore.Qt.Horizontal,
                                       'Форма собственности')
        self.table_model.setHeaderData(3, QtCore.Qt.Horizontal, 'Адрес')
        self.table_model.setHeaderData(4, QtCore.Qt.Horizontal, 'Телефон')
        self.table_model.setHeaderData(5, QtCore.Qt.Horizontal,
                                       'Электронная почта')
        self.table_model.select()

    def create_categories_table_model(self):
        self.table_model.setTable('categories')
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal,
                                       'Название категории')
        self.table_model.setHeaderData(2, QtCore.Qt.Horizontal,
                                       'Описание категории')
        self.table_model.select()

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Изменения сохранены')
        else:
            self.ui.statusbar.showMessage(
                f'{self.table_model.lastError().text()}')
Example #12
0
class Client:
    def __init__(self):
        # init GUI
        self.table_name = None
        app = QtWidgets.QApplication(sys.argv)
        MainWindow = QtWidgets.QMainWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(MainWindow)
        MainWindow.show()

        # parameters
        self.db_path = None

        self.db = None

        # events
        self.ui.openDbPushButton.clicked.connect(self.open_database)
        self.ui.saveDbPushButton.clicked.connect(self.save_change_db)
        self.ui.addRowPushButton.clicked.connect(self.add_row)
        self.ui.deleteRowPushButton.clicked.connect(self.del_row)

        self.ui.tablesListView.itemDoubleClicked.connect(self.change_table)

        sys.exit(app.exec_())

    def open_database_dialog(self):
        try:
            self.db_path = QFileDialog.getOpenFileName(self.ui.MainWindow, "Open file", '.')[0]
            print(self.db_path)
            self.ui.path_db.setText(self.db_path)
            self.db.close()
        except Exception as e:
            pass

    def open_database(self):
        try:
            self.open_database_dialog()
            self.db = QSqlDatabase.addDatabase('QSQLITE')
            self.db.setDatabaseName(self.db_path)
            self.db.open()
            self.get_tables_name()
            self.show_table()
        except Exception as err:
            print(err)

    def get_tables_name(self):
        self.ui.tablesListView.clear()
        for table_name in self.db.tables():
            self.ui.tablesListView.addItem(table_name)

    def change_table(self, name):
        self.table_name = self.ui.tablesListView.currentItem().text()
        self.show_table()

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()

        if self.table_name:
            table = self.table_name
        else:
            table = [str(self.ui.tablesListView.item(i).text()) for i in range(self.ui.tablesListView.count())][0]

        self.table_model.setTable(table)
        self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableViewerTableView
        view.setModel(self.table_model)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def add_row(self):
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Changes were saved')
        else:
            self.ui.statusbar.showMessage(f'{self.table_model.lastError().text()}')

    def del_row(self):
        rs = list(map(lambda x: x.row(), self.ui.tableViewerTableView.selectedIndexes()))
        print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)
        self.ui.statusbar.showMessage("Row was deleted")
Example #13
0
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))