class BufferSelectToolbar(object):
    def __init__(self, selectTool):
        super(BufferSelectToolbar, self).__init__()
        # references
        self.selectTool = selectTool
        self.result = None
        self.debug = self.selectTool.debug
        self.id = id
        self.config = self.selectTool.config
        self.info = Info(self)
        try:
            self.gtomain = self.selectTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface
            self.canvas = self.iface.mapCanvas()
            # tool data
            self.toolbar_dock = self.config.get("toolbar_dock", 4)
            self.toolbar_height = self.gtomain.toolbar_height
            # widget
            self.toolbar = None
            # load toolbar
            objName = "gtoTB_" + __name__ + str(id)
            self.toolbar = self.gtomain.helper.findToolbar(self.iface, objName)
            if self.toolbar is None:
                if self.debug: self.info.log("load", objName)
                self.toolbar = QToolBar()
                self.toolbar.setObjectName(objName)
                self.toolbar.setWindowTitle(u'GTO Buffer Selection')
                self.toolbar.setAllowedAreas(Qt.BottomToolBarArea
                                             | Qt.TopToolBarArea)
                self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                # set the iconsize=> changed when self.iface.addToolBar :S
                if self.toolbar_height is not None:
                    self.toolbar.setMaximumHeight(self.gtomain.toolbar_height)
                    self.toolbar.setMinimumHeight(self.gtomain.toolbar_height)
            else:
                self.toolbar.clear()
            self.wid = Widget(self)
            self.toolbar.addWidget(self.wid)
            self.wid.setIconSizes(self.iface.iconSize(False))
            self.wid.geometry_changed.connect(self.getGeometry)
            self.toolbar.setHidden(False)
        except Exception as e:
            self.info.err(e)

    # from mActionbufferselectxy
    def setHidden(self, a0):
        self.toolbar.setHidden(a0)

    def setGeometry(self, geo, isValid, isCircle=False, isRectangle=False):
        self.toolbar.setHidden(False)
        if self.debug:
            self.info.log("setGeometry", geo.isEmpty(), isValid, isCircle,
                          isRectangle)
        self.wid.setOriginalGeometry(geo, isValid, isCircle, isRectangle)

    def getGeometry(self, geo):
        self.selectTool.setGeometryToMapTool(geo)
Beispiel #2
0
class run(QObject):  # gtoAction
    def __init__(self, id, gtoTool, config, debug):
        super(run, self).__init__()
        # references
        self.debug = debug
        self.id = id
        self.config = config
        self.info = gtoTool.info

        try:
            self.action = gtoTool.action
            self.action.setCheckable(True)
            self.gtomain = gtoTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface
            self.canvas = self.iface.mapCanvas()
            if not self.config.get("is_widgetaction", False):
                # tool data
                self.toolbar_dock = self.config.get("toolbar_dock", 4)
                # widget
                self.toolbar = None

                # load toolbar
                self.objName = "gtoTB_" + gtoTool.action.objectName() + str(id)
                self.toolbar = self.gtomain.helper.findToolbar(self.iface, self.objName)
                if self.toolbar is None:
                    if self.debug: self.info.log("load", self.objName)
                    self.toolbar = QToolBar()
                    self.toolbar.setObjectName(self.objName)
                    self.toolbar.setWindowTitle(u'GTO Coordinate')
                    self.toolbar.setAllowedAreas(Qt.BottomToolBarArea | Qt.TopToolBarArea)
                    self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                    self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                else:
                    self.toolbar.clear()
                self.wid = GTOPointWidget(self.gtomain, self.toolbar)
                self.toolbar.addWidget(self.wid)
                if self.config.get("spacer", False):
                    spacer = QWidget()
                    spacer.setObjectName('spacer')
                    spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                    spacer.setStyleSheet("QWidget{background: transparent;}")
                    self.toolbar.addWidget(spacer)
                self.wid.set_parent_widget(self)
                self.wid.isActive.connect(self.set_status)  # not always(?) working?
                self.wid.setConfig(self.config)
                self.wid.added()
                self.wid.setMapTool()
                self.toolbar.show()
        except Exception as e:
            self.info.err(e)

    def set_status(self, isActive):
        try:
            self.action.setChecked(isActive)
            self.toolbar.setHidden(not isActive)
        except Exception as e:
            self.info.err(e)
class run(object):
    def __init__(self, id, gtoTool, config, debug):
        super(run, self).__init__()
        try:
            # references
            self.result = None
            self.debug = debug
            self.id = id
            self.config = config
            self.info = gtoTool.info
            self.gtomain = gtoTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface

            # tool data widegt
            self.toolbar_dock = self.config.get("toolbar_dock", None)
            # widget
            self.toolbar = None
            self.wid = Widget(self, self.iface.mainWindow())
            if self.toolbar_dock is not None:
                # load toolbar
                objName = "gtoTB_" + gtoTool.action.objectName()
                self.toolbar = self.gtomain.helper.findToolbar(
                    self.iface, objName)
                if self.toolbar is None:
                    if self.debug: self.info.log("load", objName)
                    self.toolbar = QToolBar()
                    self.toolbar.setObjectName(objName)
                    self.toolbar.setWindowTitle(u'GTO Suche')
                    self.toolbar.setAllowedAreas(Qt.BottomToolBarArea
                                                 | Qt.TopToolBarArea)
                    self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                    self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                else:
                    self.toolbar.clear()
                    self.toolbar.setHidden(False)
            else:
                self.toolbar = self.gtomain.gtotb
            self.toolbar.addWidget(self.wid)
            if self.config.get("show_hide_button", False):
                self.helper.addToolbarClose(self.toolbar)
            self.toolbar.visibilityChanged.connect(self.reset)
        except Exception as e:
            self.info.err(e)

    def reset(self, *args):  # from (gto)toolbar hidden/shown
        try:
            if self.debug: self.info.log("gtoAction reset")
            self.wid.reset()
        except Exception as e:
            self.info.err(e)
Beispiel #4
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__()
        # Parse incoming command line arguments:
        parser = argparse.ArgumentParser()
        parser.add_argument(
            "--config",
            type=str,
            help=
            "Local path to a YAML file (.yml, .yaml) containing configuration settings",
            required=False,
            default="",
        )
        args = parser.parse_args()
        if args.config:
            self.config_file = args.config
        # Logger box:
        logTextBox = QTextEditLogger(self)
        logTextBox.setFormatter(
            logging.Formatter(
                "%(asctime)s - %(module)s - %(levelname)s - %(message)s"))
        logging.getLogger().addHandler(logTextBox)
        # Logging level control:
        logging.getLogger().setLevel(logging.DEBUG)
        loglabel = QLabel()
        loglabel.setText("Log output:")
        loglabel.setBuddy(logTextBox.widget)
        # Main info area container (top of main window).
        self.task_panel = QWidget()
        self.taskLayout = QHBoxLayout()
        # Main control panel container (center of main window).
        self.controls = QWidget()
        self.controlsLayout = QVBoxLayout()
        # Main container.
        container = QWidget()
        containerLayout = QVBoxLayout()
        containerLayout.addWidget(self.task_panel)
        containerLayout.addWidget(self.controls)
        # containerLayout.addWidget(loglabel)
        # containerLayout.addWidget(logTextBox.widget)
        container.setLayout(containerLayout)
        self.setCentralWidget(container)
        # Window title:
        self.setWindowTitle("Sense Record")
        self.setWindowIcon(
            QIcon(
                qta.icon("mdi.circle-slice-8", options=[{
                    "color": "#4CAF50"
                }])))
        # Construct status bar (bottom of MainWindow):
        self.statusBar()
        # Construct Menu bar on MainWindow:
        menubar = self.menuBar()
        # File menu
        fileMenu = menubar.addMenu("&File")
        # File > Load config:
        loadAct = QAction(qta.icon("mdi.folder-cog-outline"),
                          "&Load config file", self)
        loadAct.setShortcut("Ctrl+O")
        loadAct.setStatusTip("Load configuration data from a .yml file")
        loadAct.triggered.connect(self.get_config_file)
        fileMenu.addAction(loadAct)
        # Tasks menu
        self.tasksMenu = menubar.addMenu("&Tasks")
        # View menu
        self.viewMenu = menubar.addMenu("&View")
        self.refreshAct = QAction(qta.icon("mdi.refresh"), "Refresh", self)
        self.refreshAct.setStatusTip("Refresh the controls.")
        self.refreshAct.triggered.connect(self.load_config)
        self.refreshAct.setDisabled(True)
        self.viewMenu.addAction(self.refreshAct)
        # Toolbar
        self.toolbar = QToolBar("Main toolbar")
        self.addToolBar(self.toolbar)
        # Load configuration if present
        if hasattr(self, "config_file"):
            self.load_config()
        else:
            # Config file button and file dialog.
            btn_config = QPushButton(qta.icon("mdi.folder-cog-outline"),
                                     "Select config file ...")
            btn_config.clicked.connect(self.get_config_file)
            self.toolbar.addWidget(
                QLabel("You must select a config file to load controls."))
            self.controlsLayout.addWidget(btn_config)
        # Set the controls (for the heart of the sun):
        self.controls.setLayout(self.controlsLayout)

    def set_controls(self, task_name: str):
        """Generates the labels and controls that appear in the controls area."""

        # Clear the current toolbar:
        self.toolbar.clear()
        # Clear the current task panel:
        self.clear_layout(self.taskLayout)
        # Clear the current controls:
        self.clear_layout(self.controlsLayout)
        # Enable the refresh menu action in the View menu:
        self.refreshAct.setDisabled(False)
        # Load our task from global config:
        task = self.config["tasks"][task_name]
        # Make the toolbar items:
        if "label" in task:
            label_text = task["label"]
        else:
            label_text = task_name
        taskLabel = QLabel(
            chr(0xF10D5) + " " + "<strong>Task: </strong>" + label_text)
        taskLabel.setFont(qta.font("fa", 26))

        self.toolbar.addWidget(taskLabel)
        toolbarSpacer = QWidget(self)  # right-aligns the refresh button
        toolbarSpacer.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        refreshButton = QAction(qta.icon("mdi.refresh"), "Refresh", self)
        refreshButton.setStatusTip("Refresh the controls.")
        refreshButton.triggered.connect(self.load_config)
        self.toolbar.addWidget(toolbarSpacer)
        self.toolbar.addAction(refreshButton)
        # Make the task info panel:
        if "description" in task:
            taskLabel.setToolTip(task["description"])
            taskDescription = QWidget()
            taskDescription.setSizePolicy(QSizePolicy.Maximum,
                                          QSizePolicy.Expanding)
            descriptionLayout = QVBoxLayout()
            descriptionLayout.setAlignment(Qt.AlignTop)
            descriptionLabel = QLabel(task["description"])
            descriptionLabel.setWordWrap(True)
            descriptionHeading = QLabel(
                chr(0xF0EA7) + " " + "<strong>Description: </strong>")
            descriptionHeading.setFont(qta.font("fa", 26))
            descriptionLayout.addWidget(descriptionHeading)
            descriptionLayout.addWidget(descriptionLabel)
            taskDescription.setLayout(descriptionLayout)
            self.taskLayout.addWidget(taskDescription, 6)
        if "sessions" in task:
            taskSessions = QWidget()
            sessionLayout = QVBoxLayout()
            sessionLayout.setAlignment(Qt.AlignTop)
            sessionsHeading = QLabel(
                chr(0xF0ED8) + " " + "<strong>Sessions: </strong>")
            sessionsHeading.setFont(qta.font("fa", 26))
            sessionLayout.addWidget(sessionsHeading)
            for k, v in task["sessions"].items():
                sessionLayout.addWidget(QLabel(v))
            taskSessions.setLayout(sessionLayout)
            self.taskLayout.addWidget(taskSessions, 6)
        else:
            spacer = QWidget(self)
            spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
            self.taskLayout.addWidget(spacer, 6)
        # Refresh the task info panel layout:
        self.task_panel.setLayout(self.taskLayout)
        # Make controls for this task:
        task["key"] = task_name  # Insert task id key to the task dict
        # Construct on/off button controls for each board in our task:
        for key, board in task["boards"].items():
            self.controlsLayout.addWidget(OnOffWidget(board, task))
        self.controls.setLayout(self.controlsLayout)

    def set_tasks_menu(self):
        """Generates the items for the Tasks menu."""

        self.tasksMenu.clear()
        for name, settings in self.config["tasks"].items():
            taskAct = QAction(qta.icon("mdi.clipboard-list-outline"),
                              "&" + name, self)
            taskAct.setStatusTip("Load controls for " + name)
            # https://stackoverflow.com/questions/6784084/how-to-pass-arguments-to-functions-by-the-click-of-button-in-pyqt
            taskAct.triggered.connect(
                lambda state, x=name: self.set_controls(x))
            self.tasksMenu.addAction(taskAct)

    def get_config_file(self):
        """Shows a file browser dialog to set active config file."""

        config_file = QFileDialog.getOpenFileName(
            self, ("Open Config File"), "./", ("YAML files (*.yml *.yaml)"))
        if config_file[0]:
            # Path to the yml:
            self.config_file = config_file[0]
            # Ingest the config from yml:
            self.load_config()

    def load_config(self):
        """Loads data from config file and calls functions
        to update window using new data from config file."""

        if hasattr(self, "config_file"):
            try:
                self.config = process_yaml(self.config_file)
                first_taskname = list(self.config["tasks"].keys())[0]
                self.set_controls(
                    first_taskname
                )  # default to first task when loading config
                self.set_tasks_menu()
                logging.info("Using configuration loaded from " +
                             self.config_file)
                self.statusBar().showMessage(
                    "Active config file: " +
                    os.path.split(self.config_file)[1])
            except Exception as e:
                QMessageBox.critical(self, "Invalid config file!", str(e),
                                     QMessageBox.Ok)
                logging.error(str(e))

    def clear_layout(self, layout):
        """Recursively deletes all widgets in given layout."""

        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
                else:
                    self.clear_layout(item.layout())

    def closeEvent(self, event):
        """
        Overrides inherited closeEvent method to inject a
        confirmation dialog when MainWindow is closed.
        """

        quit_msg = "Are you sure you want to exit?"
        reply = QMessageBox.question(self, "Quit Application", quit_msg,
                                     QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
Beispiel #5
0
class QImageGridViewer(QScrollArea):
    def __init__(self):

        super().__init__()

        self.imageGrids = QImageGrids()
        self.imageGrids.focusChanged.connect(self.focusChangedSlot)

        self.setBackgroundRole(QPalette.Dark)
        self.setWidget(self.imageGrids)
        self.setWidgetResizable(True)

        self._appContext = None

        self.stylesheetPath = 'QImageGridStyle.qss'
        # self.readStyleSheet()

        self.toolbar = QToolBar()
        self.initToolbar()

        self.initMenu()  # makes self.menu

    def count(self):
        return self.imageGrids.count()

    def readStyleSheet(self):
        f = QFile(self.appContext.get_resource(self.stylesheetPath))
        f.open(QFile.ReadOnly | QFile.Text)
        stream = QTextStream(f)
        self.setStyleSheet(stream.readAll())

    def open(self):
        options = QFileDialog.Options()
        fileNames, _ = QFileDialog.getOpenFileNames(
            self,
            'QFileDialog.getOpenFileNames()',
            '',
            'Images (*.png *.jpeg *.jpg *.bmp *.gif)',
            options=options)

        if fileNames:
            filePaths = [Path(name) for name in fileNames]
            self.openFiles(filePaths)

    def openFiles(self, filePaths):

        for filePath in filePaths:

            # don't open the file if a version with "inked" exists
            if inkPath(filePath) in filePaths:
                pass  # print(f'skipped {filePath}')
            elif isInked(filePath):
                self.openFile(filePath, removePathInk(filePath))
            else:
                self.openFile(filePath)

    def openFile(self, fileName, baseFileName=None):
        if baseFileName is None:
            self.imageGrids.add(Path(fileName))
        else:
            self.imageGrids.add(Path(fileName), Path(baseFileName))

    def removeFocusedGrid(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.removeFocusedGrid()

    def reloadFocusedImage(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.reloadFocusedGrid()

    def focusLastGrid(self):
        self.focusGridAtIndex(self.imageGrids.VBoxLayout.count() - 2)

    def focusFirstGrid(self):
        self.focusGridAtIndex(0)

    def focusGridAtIndex(self, index):
        oldGrid = self.imageGrids.getFocusedGrid()

        if oldGrid is None:
            return

        oldGrid.clearFocusItem()

        self.imageGrids._focusItemIndex = index
        newGrid = self.imageGrids.getFocusedGrid()
        newGrid.setFocusItem(0, 0)
        self.imageGrids.emitFocusChanged()

    def keyPressEvent(self, event: QKeyEvent):
        QMainWindow().keyPressEvent(event)

    def ensureFocusedItemVisible(self):
        self.ensureWidgetVisible(
            self.imageGrids.getFocusedGrid().getFocusWidget())

    @pyqtSlot()
    def focusChangedSlot(self):
        self.readStyleSheet()
        self.ensureFocusedItemVisible()

    @pyqtSlot(QImage)
    def changeFocusedImageData(self, newImage):
        grid = self.imageGrids.getFocusedGrid()
        if grid is not None:
            widget = grid.getFocusWidget()
            widget.setImage(newImage)
            self.imageGrids.getFocusedGrid().writeImage()

    def moveFocusDown(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveItemFocusDown()

    def moveFocusUp(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveItemFocusUp()

    def moveFocusLeft(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveItemFocusLeft()

    def moveFocusRight(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveItemFocusRight()

    def moveFocusNext(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveFocusNext()

    def moveFocusPrevious(self):
        if not self.imageGrids.count() == 0:
            self.imageGrids.moveFocusPrevious()

    def sizeHint(self):
        return QSize(150, 400)

    @property
    def appContext(self):
        return self._appContext

    @appContext.setter
    def appContext(self, context):
        self._appContext = context
        self.toolbar.clear()
        self.initToolbar()

    @property
    def rows(self):
        return QImageGrid.clsRows

    @rows.setter
    def rows(self, value):
        QImageGrid.clsRows = value

    @property
    def cols(self):
        return QImageGrid.clsCols

    @cols.setter
    def cols(self, value):
        QImageGrid.clsCols = value

    def createActions(self):
        if self.appContext is None:
            refreshIconFp = './icons/refreshIcon.png'
        else:
            refreshIconFp = self.appContext.get_resource('refreshIcon.png')

        self.itemFocusDownAct = QAction('Down Item',
                                        self,
                                        shortcut=Qt.CTRL + Qt.Key_Down,
                                        triggered=self.moveFocusDown)
        self.itemFocusUpAct = QAction('Up Item',
                                      self,
                                      shortcut=Qt.CTRL + Qt.Key_Up,
                                      triggered=self.moveFocusUp)
        self.itemFocusLeftAct = QAction('Left Item',
                                        self,
                                        shortcut=Qt.CTRL + Qt.Key_Left,
                                        triggered=self.moveFocusLeft)
        self.itemFocusRightAct = QAction('Right Item',
                                         self,
                                         shortcut=Qt.CTRL + Qt.Key_Right,
                                         triggered=self.moveFocusRight)
        self.itemFocusNextAct = QAction('Next Item',
                                        self,
                                        shortcut=Qt.CTRL + Qt.Key_N,
                                        triggered=self.moveFocusNext)
        self.itemFocusPreviousAct = QAction('Previous Item',
                                            self,
                                            shortcut=Qt.CTRL + Qt.Key_P,
                                            triggered=self.moveFocusPrevious)

        self.resetImageAct = QAction(QIcon(refreshIconFp),
                                     'Reset Image',
                                     self,
                                     shortcut=Qt.CTRL + Qt.Key_R,
                                     triggered=self.reloadFocusedImage)

        self.promptGridRowsAct = QAction('Set grid rows',
                                         self,
                                         triggered=self.promptForGridRows)
        self.promptGridColumnsAct = QAction(
            'Set grid columns', self, triggered=self.promptForGridColumns)

        self.removeFocusedGridAct = QAction('Remove current image',
                                            self,
                                            shortcut=Qt.CTRL + Qt.Key_W,
                                            triggered=self.removeFocusedGrid)

    def initMenu(self):
        self.menu = QMenu('&Grids', self)
        self.menu.addAction(self.promptGridRowsAct)
        self.menu.addAction(self.promptGridColumnsAct)
        self.menu.addSeparator()
        self.menu.addAction(self.itemFocusDownAct)
        self.menu.addAction(self.itemFocusUpAct)
        self.menu.addAction(self.itemFocusLeftAct)
        self.menu.addAction(self.itemFocusRightAct)
        self.menu.addSeparator()
        self.menu.addAction(self.itemFocusNextAct)
        self.menu.addAction(self.itemFocusPreviousAct)
        self.menu.addSeparator()
        self.menu.addAction(self.removeFocusedGridAct)

    def initToolbar(self):
        self.createActions()
        self.toolbar.addAction(self.resetImageAct)

    def promptForGridRows(self):
        rows, okPressed = QInputDialog.getInt(self, 'Grid Rows',
                                              'Number of grid rows:',
                                              QImageGrid.clsRows, 1, 20, 1)
        if okPressed:
            QImageGrid.clsRows = rows

    def promptForGridColumns(self):
        cols, okPressed = QInputDialog.getInt(self, 'Grid Columns',
                                              'Number of grid columns:',
                                              QImageGrid.clsCols, 1, 20, 1)
        if okPressed:
            QImageGrid.clsCols = cols
Beispiel #6
0
class QGameCountTracker(QListWidget):
    def __init__(self):
        super().__init__()

        self._appContext = None
        self.addAnimalForm = QGameCountInputForm()
        self.addAnimalForm.animalAdded.connect(self.addAnimalData)
        self.addAnimalForm.animalAdded.connect(self.dump)

        self.currentImageFile = ''
        self.JSONDumpFile = None
        self.summaryFile = None

        self.counts = MultiGameCountTracker()

        self.createActions()

        self.toolbar = QToolBar()
        self.initToolbar()

        self.menu = QMenu('&Tracker', self)
        self.initMenu()

    @property
    def appContext(self):
        return self._appContext

    @appContext.setter
    def appContext(self, context):
        self._appContext = context
        self.toolbar.clear()
        self.menu.clear()
        self.createActions()
        self.initToolbar()
        self.initMenu()

    @pyqtSlot(GameCountData)
    def addAnimalData(self, data):
        self.counts.addData(self.currentImageFile, data)
        self.render()

    def keyReleaseEvent(self, event):
        key = event.key()
        if key == Qt.Key_Delete:
            self.clearCurrentSelectionCountData()
        else:
            super().keyPressEvent(event)

    def load(self, fileName):
        self.JSONDumpFile = fileName
        with open(self.JSONDumpFile, 'r') as f:
            try:
                d = json.load(f)
            except json.decoder.JSONDecodeError:
                print('invalid json file')
            else:
                self.counts = self._decodeJSON(d)
            finally:
                self.render()

    def _decodeJSON(self, d: dict):

        counts = MultiGameCountTracker()

        # first is a dict of filenames paired with a list of animals
        for fileName, countList in d.items():

            # decode the list of animals
            for data in countList:
                gameData = GameCountData(data['Species'], data['Count'],
                                         data['Repeats'])
                counts.addData(fileName, gameData)

        return counts

    def dump(self):
        if self.JSONDumpFile is None:
            self.JSONDumpFile = Path().cwd() / Path('counts.json')

        if self.summaryFile is None:
            self.summaryFile = self.JSONDumpFile.parent / Path(
                'count summary.txt')

        self.JSONDumpFile.touch()
        self.summaryFile.touch()

        with open(self.JSONDumpFile, 'w') as f:
            f.write(self.serialize())

        with open(self.summaryFile, 'w') as f:
            f.write(self.summarize())

    def summarize(self):
        s = self.counts.totalsSummary()
        s += '\n-------------------------\n'
        s += str(self.counts)
        return s

    def displaySummary(self):
        if len(self.counts) == 0:
            summary = (
                'No counts recorded yet!'
                '\nTry recording an animal count with the "Add New Animals" panel'
            )
        else:
            summary = (self.counts.totalsSummaryHTML() +
                       '\n-------------------------\n' + self.counts.toHTML())

        QMessageBox.about(self, 'Count Summary', summary)

    def serialize(self):
        return json.dumps(self.counts,
                          cls=ObjectEncoder,
                          indent=2,
                          sort_keys=True)

    def clearData(self):
        # clears the internal data structure.
        # NOTE: Does NOT automatically rewrite the json file
        self.counts.clear()
        self.render()

    def clearCurrentSelectionCountData(self):
        # TODO clear the data for just the current file AND species
        fileName = self.currentImageFile
        item = self.currentItem()

        if item is not None:
            species = item.species
            self.counts[fileName].removeSpecies(species)
            self.render()

    def render(self):
        self.clear()
        try:
            tracker = self.counts[self.currentImageFile]
        except KeyError:
            pass
        else:
            for track in tracker:

                # add item and save the species for easier access later
                item = QListWidgetItem(str(track), self)
                item.species = track.species

    def createActions(self):
        if self.appContext is None:
            clearFp = './resources/eraserIcon.png'
            infoFp = './resources/infoIcon.png'
        else:
            clearFp = self.appContext.get_resource('eraserIcon.png')
            infoFp = self.appContext.get_resource('infoIcon.png')

        self.clearDataAct = QAction(QIcon(clearFp),
                                    '&Delete All Animal Counts',
                                    self,
                                    triggered=self.clearData)
        self.summarizeAct = QAction(QIcon(infoFp),
                                    '&Summarize',
                                    self,
                                    shortcut=Qt.Key_S,
                                    triggered=self.displaySummary)

    def initToolbar(self):
        self.toolbar.addAction(self.summarizeAct)

    def initMenu(self):
        self.menu.addAction(self.summarizeAct)
        self.menu.addAction(self.clearDataAct)
Beispiel #7
0
class QImagePainter(QSmoothGraphicsView):

    # signals
    imageFlattened = pyqtSignal(QImage)

    def __init__(self):
        super().__init__()

        self.scene = QGraphicsScene(self)
        self.setScene(self.scene)
        self.setRenderHint(QPainter.Antialiasing)

        self.mainPixmapItem = self.scene.addPixmap(QPixmap())

        self._appContext = None

        # policies
        # self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        # self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.toolbar = QToolBar()
        self.initToolbar()

        self._pen = QPen()
        self._pen.setWidth(50)
        self.setDefaultPenColor()

        self._drawStartPos = None
        self._dynamicOval = None
        self._drawnItems = []

        self.updateDragMode()

    @property
    def appContext(self):
        return self._appContext

    @appContext.setter
    def appContext(self, context):
        self._appContext = context
        self.toolbar.clear()
        self.initToolbar()

    def setMainPixmapFromPath(self, imgPath):

        # set image
        image = QImage(str(imgPath))
        pixmap = self.mainPixmapItem.pixmap()
        pixmap.convertFromImage(image)
        self.setMainPixmap(pixmap)

    def setMainPixmap(self, pixmap):
        self.mainPixmapItem.setPixmap(pixmap)

        # set scene rect
        boundingRect = self.mainPixmapItem.boundingRect()
        margin = 0
        boundingRect += QMarginsF(margin, margin, margin, margin)
        self.scene.setSceneRect(boundingRect)

    def saveImage(self, fileName):
        image = self.flattenImage()
        image.save(fileName)

    def flattenImageIfDrawnOn(self):
        if not len(self._drawnItems) == 0:
            self.flattenImage()

    def flattenImage(self):

        # get region of scene
        area = self.mainPixmapItem.boundingRect()

        # create a QImage to render to and fix up a QPainter for it
        image = QImage(area.width(), area.height(),
                       QImage.Format_ARGB32_Premultiplied)
        painter = QPainter(image)

        # render the region of interest to the QImage
        self.scene.render(painter, QRectF(image.rect()), area)
        painter.end()

        # set this flattened image to this view
        pixmap = self.mainPixmapItem.pixmap()
        pixmap.convertFromImage(image)
        self.setMainPixmap(pixmap)

        # clear the drawings from the view
        self.clearDrawnItems()

        # emit flattened image signal
        self.imageFlattened.emit(image)

        # return the flattened image
        return image

    def clearDrawnItems(self):
        for item in self._drawnItems:
            self.scene.removeItem(item)

        self._drawnItems.clear()

    def removeLastDrawnItem(self):
        try:
            item = self._drawnItems.pop()
        except IndexError:
            pass
        else:
            self.scene.removeItem(item)

    def scaleView(self, scaleFactor):
        # print(f'self.width: {self.width()}')
        # print(f'pixmap.width(): {self.scene.map.mainPixmapItem.boundingRect().width()}')
        self.scale(scaleFactor, scaleFactor)

    def centerImage(self):
        self.centerOn(self.mainPixmapItem)

    def bestFitImage(self):
        self.fitInView(self.mainPixmapItem, Qt.KeepAspectRatio)

    def keyPressEvent(self, event: QKeyEvent):
        key = event.key()
        if key == Qt.Key_Space:
            self.bestFitImage()
        else:
            super().keyPressEvent(event)

    def mousePressEvent(self, event):
        self._drawStartPos = None
        if self.ovalModeAct.isChecked():
            if self.mainPixmapItem.isUnderMouse():
                self._drawStartPos = self.mapToScene(event.pos())
                self._dynamicOval = self.scene.addEllipse(
                    QRectF(self._drawStartPos.x(), self._drawStartPos.y(), 1,
                           1), self._pen)
        else:
            super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if self._dynamicOval:
            pos = self.mapToScene(event.pos())
            self._dynamicOval.setRect(
                QRectF(self._drawStartPos.x(), self._drawStartPos.y(),
                       pos.x() - self._drawStartPos.x(),
                       pos.y() - self._drawStartPos.y()))
        else:
            super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if self._dynamicOval:
            self._drawnItems.append(self._dynamicOval)
            self._dynamicOval = None
        else:
            super().mouseReleaseEvent(event)

    def toggleSelectionMode(self):
        if self.selectionModeAct.isChecked():
            self.ovalModeAct.setChecked(False)
        else:
            self.selectionModeAct.setChecked(True)
        self.updateDragMode()

    def toggleOvalMode(self):
        if self.ovalModeAct.isChecked():
            self.selectionModeAct.setChecked(False)
        else:
            self.ovalModeAct.setChecked(True)
        self.updateDragMode()

    def updateDragMode(self):
        if self.selectionModeAct.isChecked():
            self.setDragMode(QGraphicsView.ScrollHandDrag)
        else:
            self.setDragMode(QGraphicsView.NoDrag)

    @property
    def penWidth(self):
        return self._pen.width()

    @penWidth.setter
    def penWidth(self, value):
        self._pen.setWidth(value)

    @property
    def penColor(self):
        return self._pen.color()

    @penColor.setter
    def penColor(self, value):
        self._pen.setColor(QColor(value))

    def setDefaultPenColor(self):
        self.setPenColor(COLORS['Teleric Blue'])

    def promptForPenWidth(self):
        width, okPressed = QInputDialog.getInt(self, 'Pen Width',
                                               'Pen width (px):',
                                               self.penWidth, 1, 100, 1)
        if okPressed:
            self.penWidth = width

    def setResourcePaths(self):
        if self.appContext is None:
            self.selectionModeFp = './icons/selectIcon.png'
            self.ovalModeFp = './icons/ovalIcon.png'
            self.flattenFp = './icons/saveIcon.png'
            self.undoFp = './icons/undoIcon.png'
            self.penFp = './icons/pen.png'
            self.penWidthFp = './icons/penWidth.png'
        else:
            self.selectionModeFp = self.appContext.get_resource(
                'selectIcon.png')
            self.ovalModeFp = self.appContext.get_resource('ovalIcon.png')
            self.flattenFp = self.appContext.get_resource('saveIcon.png')
            self.undoFp = self.appContext.get_resource('undoIcon.png')
            self.penFp = self.appContext.get_resource('pen.png')
            self.penWidthFp = self.appContext.get_resource('penWidth.png')

    def createActions(self):
        self.setResourcePaths()

        self.selectionModeAct = QAction(QIcon(self.selectionModeFp),
                                        'Select (v)',
                                        self,
                                        checkable=True,
                                        checked=True,
                                        shortcut=Qt.Key_V,
                                        triggered=self.toggleSelectionMode)
        self.ovalModeAct = QAction(QIcon(self.ovalModeFp),
                                   'Draw &Oval (o)',
                                   self,
                                   checkable=True,
                                   checked=False,
                                   shortcut=Qt.Key_O,
                                   triggered=self.toggleOvalMode)
        self.flattenAct = QAction(QIcon(self.flattenFp),
                                  'Save',
                                  self,
                                  shortcut=QKeySequence.Save,
                                  triggered=self.flattenImage)
        self.undoAct = QAction(QIcon(self.undoFp),
                               'Undo',
                               self,
                               shortcut=QKeySequence.Undo,
                               triggered=self.removeLastDrawnItem)

        self.setPenWidthAct = QAction(QIcon(self.penWidthFp),
                                      'Set Pen Width',
                                      self,
                                      triggered=self.promptForPenWidth)

    def addPenToolMenu(self):
        penButton = QToolButton(self)
        penButton.setText('Pen')
        penButton.setIcon(QIcon(self.penFp))
        penButton.setPopupMode(QToolButton.InstantPopup)

        self.penMenu = QMenu(penButton)
        self.penMenu.addAction(self.setPenWidthAct)

        self.addPaletteToMenu(self.penMenu)

        penButton.setMenu(self.penMenu)

        self.toolbar.addWidget(penButton)

    def setPenColor(self, color):
        qColor = QColor(color)
        for a in self.penMenu.actions():
            a.setChecked(False)
            try:
                actionColor = QColor(a.color)
            except AttributeError:
                pass
            else:
                if actionColor == qColor:
                    a.setChecked(True)
                    self.penColor = actionColor

    def addPaletteToMenu(self, menu):
        for name, color in COLORS.items():
            paletteIcon = QPaletteIcon(color)
            action = QAction(paletteIcon, name, self, checkable=True)
            action.color = color
            action.triggered.connect(
                lambda checked, color=color: self.setPenColor(color))
            menu.addAction(action)

    def initToolbar(self):
        self.createActions()
        # self.toolbar.addAction(self.flattenAct)
        self.toolbar.addAction(self.undoAct)
        # self.toolbar.addSeparator()
        self.toolbar.addAction(self.selectionModeAct)
        self.toolbar.addAction(self.ovalModeAct)
        self.addPenToolMenu()
Beispiel #8
0
def info(*args):
    print(args)


try:
    tb_name = "mytb_test"
    tb = iface.mainWindow().findChild(QToolBar, tb_name)
    if tb is None:  #create the toolbar
        tb = QToolBar(iface.mainWindow())
        tb.setObjectName(tb_name)
        tb.setWindowTitle("My Toolbar")
        iface.mainWindow().addToolBarBreak()  #toolbar in new line
        iface.addToolBar(tb)
    else:
        tb.clear()
    #add actions to tb
    actionsList = [
        "MyAPp:", "mActionSaveProject", "|", "mActionZoomIn", "mActionZoomOut",
        ["mActionMeasure", "mActionMeasureAngle", "mActionMeasureArea"]
    ]
    for a in actionsList:
        addAction(tb, a)
    #add a hide button
    btnObjectName = 'mClose_' + tb_name
    btn = tb.findChild(QPushButton, btnObjectName)
    if btn is None:
        btnHide = QPushButton()
        btnHide.setObjectName(btnObjectName)
        btnHide.setMaximumWidth(15)
        btnHide.setToolTip('close')
Beispiel #9
0
class _s_IDE(QMainWindow):
###############################################################################
# SIGNALS
#
# goingDown()
###############################################################################
    goingDown = pyqtSignal()
    def __init__(self, start_server=False):
        super(_s_IDE, self).__init__()
        self.setWindowTitle('NINJA-IDE {Ninja-IDE Is Not Just Another IDE}')
        self.setMinimumSize(700, 500)
        #Load the size and the position of the main window
        self.load_window_geometry()
        self.__project_to_open = 0

        #Start server if needed
        self.s_listener = None
        if start_server:
            self.s_listener = QLocalServer()
            self.s_listener.listen("ninja_ide")
            self.s_listener.newConnection.connect(self._process_connection)

        #Profile handler
        self.profile = None
        #Opacity
        self.opacity = settings.MAX_OPACITY

        #Define Actions object before the UI
        self.actions = actions.Actions()
        #StatusBar
        self.status = status_bar.StatusBar(self)
        self.status.hide()
        self.setStatusBar(self.status)
        #Main Widget - Create first than everything else
        self.central = central_widget.CentralWidget(self)
        self.load_ui(self.central)
        self.setCentralWidget(self.central)

        #ToolBar
        self.toolbar = QToolBar(self)
        self.toolbar.setToolTip(_translate("_s_IDE", "Press and Drag to Move"))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.addToolBar(settings.TOOLBAR_AREA, self.toolbar)
        if settings.HIDE_TOOLBAR:
            self.toolbar.hide()

        #Install Shortcuts after the UI has been initialized
        self.actions.install_shortcuts(self)
        self.mainContainer.currentTabChanged[str].connect(self.actions.update_explorer)

        #Menu
        menubar = self.menuBar()
        file_ = menubar.addMenu(_translate("_s_IDE", "&File"))
        edit = menubar.addMenu(_translate("_s_IDE", "&Edit"))
        view = menubar.addMenu(_translate("_s_IDE", "&View"))
        source = menubar.addMenu(_translate("_s_IDE", "&Source"))
        project = menubar.addMenu(_translate("_s_IDE", "&Project"))
        self.pluginsMenu = menubar.addMenu(_translate("_s_IDE", "&Addins"))
        about = menubar.addMenu(_translate("_s_IDE", "Abou&t"))

        #The order of the icons in the toolbar is defined by this calls
        self._menuFile = menu_file.MenuFile(file_, self.toolbar, self)
        self._menuView = menu_view.MenuView(view, self.toolbar, self)
        self._menuEdit = menu_edit.MenuEdit(edit, self.toolbar)
        self._menuSource = menu_source.MenuSource(source)
        self._menuProject = menu_project.MenuProject(project, self.toolbar)
        self._menuPlugins = menu_plugins.MenuPlugins(self.pluginsMenu)
        self._menuAbout = menu_about.MenuAbout(about)

        self.load_toolbar()

        #Plugin Manager
        services = {
            'editor': plugin_services.MainService(),
            'toolbar': plugin_services.ToolbarService(self.toolbar),
            'menuApp': plugin_services.MenuAppService(self.pluginsMenu),
            'explorer': plugin_services.ExplorerService(),
            'misc': plugin_services.MiscContainerService(self.misc)}
        serviceLocator = plugin_manager.ServiceLocator(services)
        self.plugin_manager = plugin_manager.PluginManager(resources.PLUGINS,
            serviceLocator)
        self.plugin_manager.discover()
        #load all plugins!
        self.plugin_manager.load_all()

        #Tray Icon
        self.trayIcon = updates.TrayIconUpdates(self)
        self.trayIcon.show()

        self._menuFile.openFile[str].connect(self.mainContainer.open_file)
        self.mainContainer.fileSaved[str].connect(self.show_status_message)
        self.mainContainer.recentTabsModified[list].connect(self._menuFile.update_recent_files)#'QStringList'
        self.mainContainer.currentTabChanged[str].connect(self.actions.update_migration_tips)
        self.mainContainer.updateFileMetadata.connect(self.actions.update_migration_tips)
        self.mainContainer.migrationAnalyzed.connect(self.actions.update_migration_tips)

    def _process_connection(self):
        connection = self.s_listener.nextPendingConnection()
        connection.waitForReadyRead()
        data = connection.readAll()
        connection.close()
        if data:
            files, projects = str(data).split(ipc.project_delimiter, 1)
            files = [(x.split(':')[0], int(x.split(':')[1]))
                for x in files.split(ipc.file_delimiter)]
            projects = projects.split(ipc.project_delimiter)
            self.load_session_files_projects(files, [], projects, None)

    def load_toolbar(self):
        self.toolbar.clear()
        toolbar_items = {}
        toolbar_items.update(self._menuFile.toolbar_items)
        toolbar_items.update(self._menuView.toolbar_items)
        toolbar_items.update(self._menuEdit.toolbar_items)
        toolbar_items.update(self._menuSource.toolbar_items)
        toolbar_items.update(self._menuProject.toolbar_items)

        for item in settings.TOOLBAR_ITEMS:
            if item == 'separator':
                self.toolbar.addSeparator()
            else:
                tool_item = toolbar_items.get(item, None)
                if tool_item is not None:
                    self.toolbar.addAction(tool_item)
        #load action added by plugins, This is a special case when reload
        #the toolbar after save the preferences widget
        for toolbar_action in settings.get_toolbar_item_for_plugins():
            self.toolbar.addAction(toolbar_action)

    def load_external_plugins(self, paths):
        for path in paths:
            self.plugin_manager.add_plugin_dir(path)
        #load all plugins!
        self.plugin_manager.discover()
        self.plugin_manager.load_all()

    def show_status_message(self, message):
        self.status.showMessage(message, 2000)

    def load_ui(self, centralWidget):
        #Set Application Font for ToolTips
        QToolTip.setFont(QFont(settings.FONT_FAMILY, 10))
        #Create Main Container to manage Tabs
        self.mainContainer = main_container.MainContainer(self)
        self.mainContainer.currentTabChanged[str].connect(self.change_window_title)
        self.mainContainer.locateFunction[str, str, bool].connect(self.actions.locate_function)
        self.mainContainer.navigateCode[bool, int].connect(self.actions.navigate_code_history)
        self.mainContainer.addBackItemNavigation.connect(self.actions.add_back_item_navigation)
        self.mainContainer.updateFileMetadata.connect(self.actions.update_explorer)
        self.mainContainer.updateLocator[str].connect(self.actions.update_explorer)
        self.mainContainer.openPreferences.connect(self._show_preferences)
        self.mainContainer.dontOpenStartPage.connect(self._dont_show_start_page_again)
        self.mainContainer.currentTabChanged[str].connect(self.status.handle_tab_changed)
        # When close the last tab cleanup
        self.mainContainer.allTabsClosed.connect(self._last_tab_closed)
        # Update symbols
        self.mainContainer.updateLocator[str].connect(self.status.explore_file_code)
        #Create Explorer Panel
        self.explorer = explorer_container.ExplorerContainer(self)
        self.central.splitterCentralRotated.connect(self.explorer.rotate_tab_position)
        self.explorer.updateLocator.connect(self.status.explore_code)
        self.explorer.goToDefinition[int].connect(self.actions.editor_go_to_line)
        self.explorer.projectClosed[str].connect(self.actions.close_files_from_project)
        #Create Misc Bottom Container
        self.misc = misc_container.MiscContainer(self)
        self.mainContainer.findOcurrences[str].connect(self.misc.show_find_occurrences)

        centralWidget.insert_central_container(self.mainContainer)
        centralWidget.insert_lateral_container(self.explorer)
        centralWidget.insert_bottom_container(self.misc)
        if self.explorer.count() == 0:
            centralWidget.change_explorer_visibility(force_hide=True)
        self.mainContainer.cursorPositionChange[int, int].connect(self.central.lateralPanel.update_line_col)
        # TODO: Change current symbol on move
        #self.connect(self.mainContainer,
            #SIGNAL("cursorPositionChange(int, int)"),
            #self.explorer.update_current_symbol)
        self.mainContainer.enabledFollowMode[bool].connect(self.central.enable_follow_mode_scrollbar)

        if settings.SHOW_START_PAGE:
            self.mainContainer.show_start_page()

    def _last_tab_closed(self):
        """
        Called when the last tasb is closed
        """
        self.explorer.cleanup_tabs()

    def _show_preferences(self):
        pref = preferences.PreferencesWidget(self.mainContainer)
        pref.show()

    def _dont_show_start_page_again(self):
        settings.SHOW_START_PAGE = False
        qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        qsettings.beginGroup('preferences')
        qsettings.beginGroup('general')
        qsettings.setValue('showStartPage', settings.SHOW_START_PAGE)
        qsettings.endGroup()
        qsettings.endGroup()
        self.mainContainer.actualTab.close_tab()

    def load_session_files_projects(self, filesTab1, filesTab2, projects,
        current_file, recent_files=None):
        self.__project_to_open = len(projects)
        self.explorer.projectOpened[str].connect(self._set_editors_project_data)
        self.explorer.open_session_projects(projects, notIDEStart=False)
        self.mainContainer.open_files(filesTab1, notIDEStart=False)
        self.mainContainer.open_files(filesTab2, mainTab=False,
            notIDEStart=False)
        if current_file:
            self.mainContainer.open_file(current_file, notStart=False)
        if recent_files is not None:
            self._menuFile.update_recent_files(recent_files)

    def _set_editors_project_data(self):
        self.__project_to_open -= 1
        if self.__project_to_open == 0:
            self.explorer.projectOpened[str].disconnect(self._set_editors_project_data)
            self.mainContainer.update_editor_project()

    def open_file(self, filename):
        if filename:
            self.mainContainer.open_file(filename)

    def open_project(self, project):
        if project:
            self.actions.open_project(project)

    def __get_profile(self):
        return self.profile

    def __set_profile(self, profileName):
        self.profile = profileName
        if self.profile is not None:
            self.setWindowTitle('NINJA-IDE (PROFILE: %s)' % self.profile)
        else:
            self.setWindowTitle(
                'NINJA-IDE {Ninja-IDE Is Not Just Another IDE}')

    Profile = property(__get_profile, __set_profile)

    def change_window_title(self, title):
        if self.profile is None:
            self.setWindowTitle('NINJA-IDE - %s' % title)
        else:
            self.setWindowTitle('NINJA-IDE (PROFILE: %s) - %s' % (
                self.profile, title))
        currentEditor = self.mainContainer.get_actual_editor()
        if currentEditor is not None:
            line = currentEditor.textCursor().blockNumber() + 1
            col = currentEditor.textCursor().columnNumber()
            self.central.lateralPanel.update_line_col(line, col)

    def wheelEvent(self, event):
        if event.modifiers() == Qt.ShiftModifier:
            if event.delta() == 120 and self.opacity < settings.MAX_OPACITY:
                self.opacity += 0.1
            elif event.delta() == -120 and self.opacity > settings.MIN_OPACITY:
                self.opacity -= 0.1
            self.setWindowOpacity(self.opacity)
            event.ignore()
        else:
            QMainWindow.wheelEvent(self, event)

    def save_settings(self):
        """Save the settings before the application is closed with QSettings.

        Info saved: Tabs and projects opened, windows state(size and position).
        """
        qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        editor_widget = self.mainContainer.get_actual_editor()
        current_file = ''
        if editor_widget is not None:
            current_file = editor_widget.ID
        if qsettings.value('preferences/general/loadFiles', True, type=bool):
            openedFiles = self.mainContainer.get_opened_documents()
            projects_obj = self.explorer.get_opened_projects()
            projects = [p.path for p in projects_obj]
            qsettings.setValue('openFiles/projects',
                projects)
            if len(openedFiles) > 0:
                qsettings.setValue('openFiles/mainTab', openedFiles[0])
            if len(openedFiles) == 2:
                qsettings.setValue('openFiles/secondaryTab', openedFiles[1])
            qsettings.setValue('openFiles/currentFile', current_file)
            qsettings.setValue('openFiles/recentFiles',
                self.mainContainer._tabMain.get_recent_files_list())
        qsettings.setValue('preferences/editor/bookmarks', settings.BOOKMARKS)
        qsettings.setValue('preferences/editor/breakpoints',
            settings.BREAKPOINTS)
        qsettings.setValue('preferences/general/toolbarArea',
            self.toolBarArea(self.toolbar))
        #Save if the windows state is maximixed
        if(self.isMaximized()):
            qsettings.setValue("window/maximized", True)
        else:
            qsettings.setValue("window/maximized", False)
            #Save the size and position of the mainwindow
            qsettings.setValue("window/size", self.size())
            qsettings.setValue("window/pos", self.pos())
        #Save the size of de splitters
        qsettings.setValue("window/central/areaSize",
            self.central.get_area_sizes())
        qsettings.setValue("window/central/mainSize",
            self.central.get_main_sizes())
        #Save the toolbar visibility
        if not self.toolbar.isVisible() and self.menuBar().isVisible():
            qsettings.setValue("window/hide_toolbar", True)
        else:
            qsettings.setValue("window/hide_toolbar", False)
        #Save Misc state
        qsettings.setValue("window/show_misc", self.misc.isVisible())
        #Save Profiles
        if self.profile is not None:
            self.actions.save_profile(self.profile)
        else:
            qsettings.setValue('ide/profiles', settings.PROFILES)

    def load_window_geometry(self):
        """Load from QSettings the window size of de Ninja IDE"""
        qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        if qsettings.value("window/maximized", True, type=bool):
            self.setWindowState(Qt.WindowMaximized)
        else:
            self.resize(qsettings.value("window/size",
                QSizeF(800, 600).toSize(), type='QSize'))
            self.move(qsettings.value("window/pos",
                QPointF(100, 100).toPoint(), type='QPoint'))

    def closeEvent(self, event):
        if self.s_listener:
            self.s_listener.close()
        if (settings.CONFIRM_EXIT and
                self.mainContainer.check_for_unsaved_tabs()):
            unsaved_files = self.mainContainer.get_unsaved_files()
            txt = '\n'.join(unsaved_files)
            val = QMessageBox.question(self,
                _translate("_s_IDE", "Some changes were not saved"),
                (_translate("_s_IDE", "%s\n\nDo you want to save them?") % txt),
                QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel)
            if val == QMessageBox.Yes:
                #Saves all open files
                self.mainContainer.save_all()
            if val == QMessageBox.Cancel:
                event.ignore()
        self.goingDown.emit()
        self.save_settings()
        completion_daemon.shutdown_daemon()
        #close python documentation server (if running)
        self.mainContainer.close_python_doc()
        #Shutdown PluginManager
        self.plugin_manager.shutdown()

    def notify_plugin_errors(self):
        errors = self.plugin_manager.errors
        if errors:
            plugin_error_dialog = traceback_widget.PluginErrorDialog()
            for err_tuple in errors:
                plugin_error_dialog.add_traceback(err_tuple[0], err_tuple[1])
            #show the dialog
            plugin_error_dialog.exec_()

    def show_python_detection(self):
        suggested = settings.detect_python_path()
        if suggested:
            dialog = python_detect_dialog.PythonDetectDialog(suggested, self)
            dialog.show()