Exemplo n.º 1
0
    def __init__(self):
        start = time.time()
        self.app = QApplication([])
        super().__init__()

        self.tableModel = TableModel('Id', 'Num', 'Str')
        self.tableModel.addRow((-1, 0, 'Test .addItem()'))
        self.tableModel.addRows([(_, random.uniform(-5, 5), f'{_}_str_{_}')
                                 for _ in range(1000)])
        self.sortModel = SortFilterProxyModel(self.tableModel)
        self.sortModel.sortend.connect(self.sortEnd)
        self.rootContext().setContextProperty('sortModel', self.sortModel)

        self.tableModel2 = TableModel('Dt', 'Name', 'LastName')
        self.tableModel2.addRows([(self.rndDt(), self.rndWorld(),
                                   self.rndWorld()) for _ in range(1000)])
        self.sortModel2 = SortFilterProxyModel(self.tableModel2)
        self.sortModel2.sortend.connect(self.sortEnd)
        self.rootContext().setContextProperty('sortModel2', self.sortModel2)

        self.load('main.qml')
        self.footer = self.rootObjects()[0].findChild(QObject, 'footer')
        self.footer.setProperty(
            'text', f'Initialization in {time.time()-start:.2f} sec')
        self.app.exec_()
Exemplo n.º 2
0
    def page(self):
        """Pages query results"""
        if not self.paginator:
            return
        self.model = None
        # if data is not fetched from paginator yet we must recreate model
        # because we dont know beforehead if data will arrive.
        # otherwise we can end up in situation when paginator is already
        # fetched (might be partially), model is None and
        # no new data will arrive in for loop (paginator.feeder)
        # this potential situation leads to empty model in view
        if not self.paginator.fetched:
            self.model = TableModel(columns=self.paginator.headers())
        # let's save current state of the cursor
        savedCursor = self.cursor()
        try:
            # set the cursor to the wait cursor
            self.setCursor(QtCore.Qt.WaitCursor)
            # feed the model
            for row in self.paginator.feeder(self.__is_forward(self.sender)):
                # we must be ensured that model is changed when
                # actual data arrives only
                if not self.model:
                    self.model = TableModel(columns=self.paginator.headers())
                # data
                self.model.input_data.append(row[0])
                # row number
                self.model.rows.append(row[1])
            # return the cursor to the previous state
            self.setCursor(savedCursor)
        except (self.db_provider.Error, self.db_provider.Warning) as err:
            # return the cursor to the previous state
            self.setCursor(savedCursor)
            # unset current page
            self.lblCurrentPage.setText("")
            self.message_box("Error!", str(err), QMessageBox.Critical)
            # clean the model
            self.tbvResults.setModel(None)
            return False

        if not self.model:
            return False

        # clean the model
        self.__update_model_in_view()
        # update last query result time and page number
        self.__update_time_and_page()

        if self.__is_forward(self.sender):
            self.tbvResults.selectRow(0)
        else:
            self.tbvResults.selectRow(self.model.rowCount(None) - 1)
        return True
Exemplo n.º 3
0
    def __init__(self, app, parent=None):
        #GUI Initialisierien
        super(Controller, self).__init__(parent)
        self.view = Ui_Wienwahl()
        self.view.setupUi(self)
        self.app = app

        #Shortcuts erstellen
        self.createShortcuts()

        #Menue verlinken
        self.linkMenu()

        #Init
        self.model = TableModel()
        self.db = Database()
        self.filename = None
        self.view.tableView.setSortingEnabled(True)
        self.undoStack = QUndoStack()
        self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack))
Exemplo n.º 4
0
class Models:
    Bot = TableModel.factory("databot_bot")
    Intent = TableModel.factory("databot_intent")
    Entity = TableModel.factory("databot_entity")
    Variable = TableModel.factory("databot_variable")
    Rule = TableModel.factory("databot_rule")
    User = TableModel.factory("databot_user")
Exemplo n.º 5
0
    def __init__(self, app, parent=None):
        #GUI Initialisierien
        super(Controller, self).__init__(parent)
        self.view = Ui_Wienwahl()
        self.view.setupUi(self)
        self.app = app

        #Shortcuts erstellen
        self.createShortcuts()

        #Menue verlinken
        self.linkMenu()

        #Init
        self.model = TableModel()
        self.db = Database()
        self.filename = None
        self.view.tableView.setSortingEnabled(True)
        self.undoStack = QUndoStack()
        self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack))
Exemplo n.º 6
0
class Main(QQmlApplicationEngine):
    def __init__(self):
        start = time.time()
        self.app = QApplication([])
        super().__init__()

        self.tableModel = TableModel('Id', 'Num', 'Str')
        self.tableModel.addRow((-1, 0, 'Test .addItem()'))
        self.tableModel.addRows([(_, random.uniform(-5, 5), f'{_}_str_{_}')
                                 for _ in range(1000)])
        self.sortModel = SortFilterProxyModel(self.tableModel)
        self.sortModel.sortend.connect(self.sortEnd)
        self.rootContext().setContextProperty('sortModel', self.sortModel)

        self.tableModel2 = TableModel('Dt', 'Name', 'LastName')
        self.tableModel2.addRows([(self.rndDt(), self.rndWorld(),
                                   self.rndWorld()) for _ in range(1000)])
        self.sortModel2 = SortFilterProxyModel(self.tableModel2)
        self.sortModel2.sortend.connect(self.sortEnd)
        self.rootContext().setContextProperty('sortModel2', self.sortModel2)

        self.load('main.qml')
        self.footer = self.rootObjects()[0].findChild(QObject, 'footer')
        self.footer.setProperty(
            'text', f'Initialization in {time.time()-start:.2f} sec')
        self.app.exec_()

    def rndDt(self):
        return datetime.fromtimestamp(random.randint(1, int(time.time())))

    def rndWorld(self):
        chrs = 'abcdefghiklmnopqrstvxyz'
        return chrs[random.randint(0,
                                   len(chrs) - 1)].upper() + ''.join(
                                       random.choice(chrs)
                                       for _ in range(random.randint(4, 10)))

    def sortEnd(self, items, time):
        self.footer.setProperty('text',
                                f'Sorting {items} rows in {time:.2f} sec')
Exemplo n.º 7
0
class MainForm(QWidget, FORM_CLASS):
    def __init__(self, parent=None):
        # initialization
        super().__init__(parent)
        self.setupUi(self)
        self.__add_custom_tableview()
        self.leRowsPerPage.setText("001000")
        self.conn = None
        self.model = None
        self.db_provider = None

        # paginator
        self.paginator = None

        # describe DB providers here
        # order needs to be maintained to ensure that SQLite is the first one
        self.providers = {"SQLite": "sqlite3", "PostgreSQL": "psycopg2"}
        # add items to the list
        self.cmbProvider.addItems(self.providers.keys())

        # connect signals
        self.pbCheck.clicked.connect(self.check_connection)
        self.pbExecute.clicked.connect(self.execute_query)
        self.pbClose.clicked.connect(self.close_all)
        self.leConnection.editingFinished.connect(self.reset_conn)
        self.cmbProvider.currentIndexChanged.connect(self.provider_changed)
        self.pbForth.clicked.connect(self.page)
        self.pbBack.clicked.connect(self.page)

        # signals and slots for CustomTableView
        self.tbvResults.top_reached_signal.connect(self.pbBack.click)
        self.tbvResults.bottom_reached_signal.connect(self.pbForth.click)

    def __add_custom_tableview(self) -> bool:
        """
        Removes standard QTableView, adds custom CustomTableView to the form.
        """
        self.verticalLayout_2.removeWidget(self.tbvResults)
        self.tbvResults.deleteLater()
        self.tbvResults = None
        self.tbvResults = CustomTableView(self.gpbResults)
        self.tbvResults.setFrameShape(QtWidgets.QFrame.Panel)
        self.tbvResults.setObjectName("tbvResults")
        self.tbvResults.horizontalHeader().setVisible(True)
        self.verticalLayout_2.addWidget(self.tbvResults)
        self.verticalLayout_2.insertWidget(0, self.tbvResults)
        return True

    def close_all(self):
        # finish up the connection
        self.reset_conn()
        self.close()

    def keyPressEvent(self, *args, **kwargs):
        """
        Overriding of parent's (Qt) method, that's why camelCase used.
        Ctrl+Enter executes query.
        """
        # check if Ctrl+Enter|Return pressed
        if (args[0].key() == QtCore.Qt.Key_Enter
                or args[0].key() == QtCore.Qt.Key_Return
            ) and args[0].modifiers() == QtCore.Qt.ControlModifier:
            # execute query
            self.execute_query()
        elif args[0].key() == QtCore.Qt.Key_Escape:
            self.pbClose.clicked.emit()
        else:
            # regular reaction
            return QWidget.keyPressEvent(self, *args, **kwargs)

    @pyqtSlot()
    def check_connection(self, user: bool = True) -> bool:
        """Check button handler."""

        try:
            self.conn = self.try_to_connect()
        except (
                ModuleNotFoundError,
                RuntimeError,
                ValueError,
                self.db_provider.Error,
                self.db_provider.Warning,
        ) as err:
            self.message_box(
                "Error!",
                f"Connection can not be established due to: {str(err)}",
                QMessageBox.Critical,
            )
            return False
        else:
            if user:
                self.message_box(
                    "Success!",
                    "Connection established",
                    QMessageBox.Information,
                )
            return True

    def __import_provider(self, provider_name: str):
        """Trying to import module for the provider and return it."""
        return importlib.import_module(str(self.providers[provider_name]))

    def __is_sqlite_db(self) -> bool:
        """Checks if DB provider is SQLite"""
        return self.db_provider.__name__ == "sqlite3"

    def __is_db_in_memory(self, db_type: str = ":memory:") -> bool:
        """
        Checks if database connection is of type :memory:.
        Makes sense for SQLite only.
        """
        return db_type == ":memory:"

    def __is_file(self, path_str: str = "") -> bool:
        """Checks if the path is a file."""
        return os.path.isfile(path_str)

    def __create_sqlite_file(self, file_name: str = ""):
        """
        Ckecks if user wants to create new SQLite file.
        Otherwise rises an exception.
        """
        question = (
            f"The file {file_name} does not exist! Do you want to create it?")
        res = self.message_box(
            "Attention!",
            question,
            QMessageBox.Warning,
            buttons=QMessageBox.Ok | QMessageBox.Cancel,
        )
        if res != QMessageBox.Ok:
            raise RuntimeError("no such file!")

    def try_to_connect(self):
        """
        Connects to the database with the connection string
        provided by the user.
        """
        if self.conn:
            return self.conn

        # it's unknown what type of provider will user choose, so import here
        self.db_provider = self.__import_provider(
            self.cmbProvider.currentData(0))

        db_conn_str = self.leConnection.text().strip()
        if not db_conn_str:
            raise ValueError("no connection string provided!")

        # since SQLite DB is a file we need to check if there is such file
        # or user wants to create new one
        if (self.__is_sqlite_db() and not self.__is_db_in_memory(db_conn_str)
                and not self.__is_file(db_conn_str)):
            # Exception might be risen here
            self.__create_sqlite_file(db_conn_str)

        return self.db_provider.connect(db_conn_str)

    def __is_query_exists(self) -> bool:
        """Checks if query text is present."""
        if self.teQuery.toPlainText().strip():
            return True
        self.message_box("Error!", "No query provided", QMessageBox.Critical)
        return False

    @pyqtSlot()
    def execute_query(self):
        """Handles 'Execute' button."""
        if not self.check_connection(False) or not self.__is_query_exists():
            return False

        # let's try to create paginator object and execute query inside of it
        try:
            self.paginator = QueryPaginator(
                rows_num=int(self.leRowsPerPage.displayText().strip()),
                connection=self.conn,
                query=self.teQuery.toPlainText().strip(),
            )
        except (
                ValueError,
                self.db_provider.Error,
                self.db_provider.Warning,
        ) as err:
            self.lblCurrentPage.setText("")
            self.message_box("Error!", str(err), QMessageBox.Critical)
            return False

        # model is created when forth or back button pressed
        # in order to create model we must emit signal
        self.pbForth.clicked.emit()

    def __is_forward(self, sender) -> bool:
        """Checks if direction is forward"""
        if sender().objectName() == BACK_BUTTON_NAME:
            return False
        return True

    @pyqtSlot()
    def page(self):
        """Pages query results"""
        if not self.paginator:
            return
        self.model = None
        # if data is not fetched from paginator yet we must recreate model
        # because we dont know beforehead if data will arrive.
        # otherwise we can end up in situation when paginator is already
        # fetched (might be partially), model is None and
        # no new data will arrive in for loop (paginator.feeder)
        # this potential situation leads to empty model in view
        if not self.paginator.fetched:
            self.model = TableModel(columns=self.paginator.headers())
        # let's save current state of the cursor
        savedCursor = self.cursor()
        try:
            # set the cursor to the wait cursor
            self.setCursor(QtCore.Qt.WaitCursor)
            # feed the model
            for row in self.paginator.feeder(self.__is_forward(self.sender)):
                # we must be ensured that model is changed when
                # actual data arrives only
                if not self.model:
                    self.model = TableModel(columns=self.paginator.headers())
                # data
                self.model.input_data.append(row[0])
                # row number
                self.model.rows.append(row[1])
            # return the cursor to the previous state
            self.setCursor(savedCursor)
        except (self.db_provider.Error, self.db_provider.Warning) as err:
            # return the cursor to the previous state
            self.setCursor(savedCursor)
            # unset current page
            self.lblCurrentPage.setText("")
            self.message_box("Error!", str(err), QMessageBox.Critical)
            # clean the model
            self.tbvResults.setModel(None)
            return False

        if not self.model:
            return False

        # clean the model
        self.__update_model_in_view()
        # update last query result time and page number
        self.__update_time_and_page()

        if self.__is_forward(self.sender):
            self.tbvResults.selectRow(0)
        else:
            self.tbvResults.selectRow(self.model.rowCount(None) - 1)
        return True

    def __update_model_in_view(self):
        """Updates model in view."""
        self.tbvResults.setModel(None)
        self.tbvResults.setModel(self.model)
        self.tbvResults.selectRow(0)

    def __update_time_and_page(self):
        """Updates execution time and page number"""
        self.lblUpdateTime.setText(
            datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        self.lblCurrentPage.setText(str(self.paginator.current_page))

    @pyqtSlot()
    def reset_conn(self):
        """Resets connection"""
        if self.conn:
            self.conn.close()
            self.conn = None

    @pyqtSlot(int)
    def provider_changed(self, index):
        """Handles provider change in the providers list box. Resets conn."""
        self.reset_conn()

    def message_box(self, text, informative, icon, buttons=QMessageBox.Ok):
        """Wraps up the QMessageBox"""
        msg = QMessageBox(self)
        msg.setStandardButtons(buttons)
        msg.setDefaultButton(QMessageBox.Ok)
        msg.setText(text)
        msg.setInformativeText(informative)
        msg.setIcon(icon)
        return msg.exec_()
Exemplo n.º 8
0
        self.process.setText(_translate("MainWindow", "Process"))


if __name__ == "__main__":
    import sys
    import pandas as pd

    # test data
    df = pd.DataFrame({
        'a': ['Mary', 'Jim', 'John'],
        'b': [100, 200, 300],
        'c': ['a', 'b', 'c']
    })

    # Instanziazione app e mainwindow
    app = QtWidgets.QApplication(sys.argv)
    tablemodel = TableModel(df)
    mainwindow = MainWindow(tablemodel)

    # Visualizzazione mainwindow
    #mainwindow.show()

    #inizializzazione schermata inziale
    mainwindow.openFirstWindow()

    #altro...
    tablemodel.provastampa()

    #chiusura programma
    sys.exit(app.exec_())
Exemplo n.º 9
0
class Controller(QMainWindow):
    def __init__(self, app, parent=None):
        #GUI Initialisierien
        super(Controller, self).__init__(parent)
        self.view = Ui_Wienwahl()
        self.view.setupUi(self)
        self.app = app

        #Shortcuts erstellen
        self.createShortcuts()

        #Menue verlinken
        self.linkMenu()

        #Init
        self.model = TableModel()
        self.db = Database()
        self.filename = None
        self.view.tableView.setSortingEnabled(True)
        self.undoStack = QUndoStack()
        self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack))

    def createShortcuts(self):
        QShortcut(QKeySequence("CTRL+Q"), self, self.exit)
        QShortcut(QKeySequence("CTRL+C"), self, self.copy)
        QShortcut(QKeySequence("CTRL+V"), self, self.paste)
        QShortcut(QKeySequence("CTRL+Z"), self, self.undo)
        QShortcut(QKeySequence("CTRL+Y"), self, self.redo)
        QShortcut(QKeySequence("CTRL+X"), self, self.cut)

    def linkMenu(self):
        self.view.actionExit.triggered.connect(self.exit)
        self.view.actionOpen.triggered.connect(self.open)
        self.view.actionNew.triggered.connect(self.new)
        self.view.actionSave.triggered.connect(self.save)
        self.view.actionSaveAs.triggered.connect(self.saveAs)
        self.view.actionAddNewRow.triggered.connect(self.addNewRow)
        self.view.actionDuplicateRow.triggered.connect(self.duplicateRow)
        self.view.actionDeleteRow.triggered.connect(self.deleteRow)
        self.view.actionSaveToDB.triggered.connect(self.saveToDB)
        self.view.actionLoadFromDB.triggered.connect(self.loadFromDB)
        self.view.actionGenerateProjection.triggered.connect(
            self.generateProjection)
        self.view.actionUndo.triggered.connect(self.undo)
        self.view.actionRedo.triggered.connect(self.redo)
        self.view.actionCopy.triggered.connect(self.copy)
        self.view.actionPaste.triggered.connect(self.paste)
        self.view.actionCut.triggered.connect(self.cut)

    def open(self):
        self.view.statusBar.showMessage("Opening file...", 2000)
        self.fileName = QFileDialog.getOpenFileName(self, "Open CSV",
                                                    QDir.homePath(),
                                                    "CSV Files (*.csv)")
        csv = CSVManager.importCSV(self, self.fileName[0])
        self.model.update(csv[0], csv[1])
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)

    def new(self):
        self.view.statusBar.showMessage("Creating new file...", 750)
        csvheader = [["#"], ["Col1"], ["Col2"]]
        csvdata = [["1", "Data1", "Data2"]]
        self.model.update(csvheader, csvdata)
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)

    def save(self):
        self.view.statusBar.showMessage("Saving to file...", 2000)
        if self.fileName is None:
            self.fileName = QFileDialog.getSaveFileName(
                self, "Save CSV", QDir.homePath(), "CSV Files (*.csv)")
        CSVManager.exportCSV(self, self.fileName[0],
                             self.model.getDataForExport())

    def saveAs(self):
        self.view.statusBar.showMessage("Saving to file...", 2000)
        self.fileName = QFileDialog.getSaveFileName(self, "Save CSV",
                                                    QDir.homePath(),
                                                    "CSV Files (*.csv)")
        CSVManager.exportCSV(self, self.fileName[0],
                             self.model.getDataForExport())

    def exit(self):
        self.view.statusBar.showMessage("Exiting...", 2000)
        sys.exit()

    def addNewRow(self):
        self.view.statusBar.showMessage("Adding new row...", 1000)
        self.model.insertRow()

    def duplicateRow(self):
        self.view.statusBar.showMessage("Duplicating rows...", 1000)
        selected = self.view.tableView.selectedIndexes()
        self.model.duplicateRow(selected)

    def deleteRow(self):
        self.view.statusBar.showMessage("Deleting rows...", 1000)
        selected = self.view.tableView.selectedIndexes()
        self.model.deleteRow(selected)

    def copy(self):
        if len(self.view.tableView.selectionModel().selectedIndexes()) != 0:
            clipboard = QApplication.clipboard()
            selected_index = self.view.tableView.selectionModel(
            ).selectedIndexes()[0]
            selected_text = str(self.model.data(selected_index))
            clipboard.setText(selected_text)

    def paste(self):
        if len(self.view.tableView.selectionModel().selectedIndexes()) != 0:
            clipboard = QApplication.clipboard()
            index = self.view.tableView.selectionModel().selectedIndexes()[0]
            command = EditCommand(self.model, index)
            command.newValue(str(clipboard.text()))

            self.undoStack.beginMacro("Paste")
            self.undoStack.push(command)
            self.undoStack.endMacro()
            self.view.tableView.reset()

    def cut(self):
        self.copy()
        index = self.view.tableView.selectionModel().selectedIndexes()[0]
        command = EditCommand(self.model, index)
        command.newValue("")
        self.undoStack.beginMacro("Cut")
        self.undoStack.push(command)
        self.undoStack.endMacro()
        self.view.tableView.reset()

    def undo(self):
        print()
        self.undoStack.undo()
        self.view.tableView.reset()

    def redo(self):
        self.undoStack.redo()
        self.view.tableView.reset()

    def saveToDB(self):
        export = self.model.getDataForExport()
        export = [export[0]] + export[1]
        self.db.save_to_db(export, self.view.statusBar)

    def loadFromDB(self):
        data = self.db.read_from_db(self.view.statusBar)
        self.model.update(data[0], data[1:])
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)

    def generateProjection(self):
        pro = self.db.generateProjection(self.view.statusBar)
        if pro is not False:
            pro_header = [["Partei"], ["Stimmen in %"]]
            self.model.update(pro_header, pro)
            self.view.tableView.reset()
            self.view.tableView.repaint()
            self.view.tableView.setModel(self.model)
Exemplo n.º 10
0
            QMessageBox.warning(self, 'Error', 'Empty username or password!',
                                QMessageBox.Ok)
            return
        userRegister = getLogFromDb(log, passwd)
        if userRegister is not None:
            QMessageBox.warning(self, 'Error',
                                'Error, username exists enter another one.',
                                QMessageBox.Ok)
            return
        addNewUser(log, passwd)
        model.layoutChanged.emit()
        self.refreshView()
        QMessageBox.information(self, 'Success', f'Account created {log}!',
                                QMessageBox.Ok)

    def save(self):
        saveTasks(model.datatable)
        model.layoutChanged.emit()
        tasks = readData(self.user)
        model.update(tasks)
        self.refreshView()


if __name__ == '__main__':
    app = QApplication([])
    connect()
    model = tm.TableModel()
    window = ToDo()
    window.show()
    sys.exit(app.exec_())
Exemplo n.º 11
0
class Controller(QMainWindow):
    def __init__(self, app, parent=None):
        #GUI Initialisierien
        super(Controller, self).__init__(parent)
        self.view = Ui_Wienwahl()
        self.view.setupUi(self)
        self.app = app

        #Shortcuts erstellen
        self.createShortcuts()

        #Menue verlinken
        self.linkMenu()

        #Init
        self.model = TableModel()
        self.db = Database()
        self.filename = None
        self.view.tableView.setSortingEnabled(True)
        self.undoStack = QUndoStack()
        self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack))

    def createShortcuts(self):
        QShortcut(QKeySequence("CTRL+Q"), self, self.exit)
        QShortcut(QKeySequence("CTRL+C"), self, self.copy)
        QShortcut(QKeySequence("CTRL+V"), self, self.paste)
        QShortcut(QKeySequence("CTRL+Z"), self, self.undo)
        QShortcut(QKeySequence("CTRL+Y"), self, self.redo)
        QShortcut(QKeySequence("CTRL+X"), self, self.cut)

    def linkMenu(self):
        self.view.actionExit.triggered.connect(self.exit)
        self.view.actionOpen.triggered.connect(self.open)
        self.view.actionNew.triggered.connect(self.new)
        self.view.actionSave.triggered.connect(self.save)
        self.view.actionSaveAs.triggered.connect(self.saveAs)
        self.view.actionAddNewRow.triggered.connect(self.addNewRow)
        self.view.actionDuplicateRow.triggered.connect(self.duplicateRow)
        self.view.actionDeleteRow.triggered.connect(self.deleteRow)
        self.view.actionSaveToDB.triggered.connect(self.saveToDB)
        self.view.actionLoadFromDB.triggered.connect(self.loadFromDB)
        self.view.actionGenerateProjection.triggered.connect(self.generateProjection)
        self.view.actionUndo.triggered.connect(self.undo)
        self.view.actionRedo.triggered.connect(self.redo)
        self.view.actionCopy.triggered.connect(self.copy)
        self.view.actionPaste.triggered.connect(self.paste)
        self.view.actionCut.triggered.connect(self.cut)

    def open(self):
        self.view.statusBar.showMessage("Opening file...", 2000)
        self.fileName = QFileDialog.getOpenFileName(self,"Open CSV", QDir.homePath(), "CSV Files (*.csv)")
        csv = CSVManager.importCSV(self, self.fileName[0])
        self.model.update(csv[0],csv[1])
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)


    def new(self):
        self.view.statusBar.showMessage("Creating new file...", 750)
        csvheader = [["#"],["Col1"],["Col2"]]
        csvdata = [["1","Data1","Data2"]]
        self.model.update(csvheader, csvdata)
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)

    def save(self):
        self.view.statusBar.showMessage("Saving to file...", 2000)
        if self.fileName is None:
            self.fileName = QFileDialog.getSaveFileName(self,"Save CSV", QDir.homePath(), "CSV Files (*.csv)")
        CSVManager.exportCSV(self, self.fileName[0], self.model.getDataForExport())

    def saveAs(self):
        self.view.statusBar.showMessage("Saving to file...", 2000)
        self.fileName = QFileDialog.getSaveFileName(self,"Save CSV", QDir.homePath(), "CSV Files (*.csv)")
        CSVManager.exportCSV(self, self.fileName[0], self.model.getDataForExport())

    def exit(self):
        self.view.statusBar.showMessage("Exiting...", 2000)
        sys.exit()

    def addNewRow(self):
        self.view.statusBar.showMessage("Adding new row...", 1000)
        self.model.insertRow()

    def duplicateRow(self):
        self.view.statusBar.showMessage("Duplicating rows...", 1000)
        selected = self.view.tableView.selectedIndexes()
        self.model.duplicateRow(selected)

    def deleteRow(self):
        self.view.statusBar.showMessage("Deleting rows...", 1000)
        selected = self.view.tableView.selectedIndexes()
        self.model.deleteRow(selected)

    def copy(self):
        if len(self.view.tableView.selectionModel().selectedIndexes()) != 0:
            clipboard = QApplication.clipboard()
            selected_index = self.view.tableView.selectionModel().selectedIndexes()[0]
            selected_text = str(self.model.data(selected_index))
            clipboard.setText(selected_text)

    def paste(self):
        if len(self.view.tableView.selectionModel().selectedIndexes()) != 0:
            clipboard = QApplication.clipboard()
            index = self.view.tableView.selectionModel().selectedIndexes()[0]
            command = EditCommand(self.model, index)
            command.newValue(str(clipboard.text()))

            self.undoStack.beginMacro("Paste")
            self.undoStack.push(command)
            self.undoStack.endMacro()
            self.view.tableView.reset()

    def cut(self):
        self.copy()
        index = self.view.tableView.selectionModel().selectedIndexes()[0]
        command = EditCommand(self.model, index)
        command.newValue("")
        self.undoStack.beginMacro("Cut")
        self.undoStack.push(command)
        self.undoStack.endMacro()
        self.view.tableView.reset()

    def undo(self):
        print()
        self.undoStack.undo()
        self.view.tableView.reset()

    def redo(self):
         self.undoStack.redo()
         self.view.tableView.reset()

    def saveToDB(self):
        export = self.model.getDataForExport()
        export = [export[0]]+export[1]
        self.db.save_to_db(export, self.view.statusBar)

    def loadFromDB(self):
        data = self.db.read_from_db(self.view.statusBar)
        self.model.update(data[0], data[1:])
        self.view.tableView.reset()
        self.view.tableView.repaint()
        self.view.tableView.setModel(self.model)

    def generateProjection(self):
        pro = self.db.generateProjection(self.view.statusBar)
        if pro is not False:
            pro_header = [["Partei"],["Stimmen in %"]]
            self.model.update(pro_header, pro)
            self.view.tableView.reset()
            self.view.tableView.repaint()
            self.view.tableView.setModel(self.model)