Example #1
0
 def selectionChanged(self, selected, deselected):
     """QAbstractItemView slot
     """
     debug_print('SummaryView.selectionChanged')
     self._updated(
         self.model().rowCount(), self.selectionModel().selectedIndexes()
     )
Example #2
0
 def dataChanged(self, topLeft, bottomRight, roles=[]):
     """QAbstractItemView virtual
     """
     debug_print('SummaryView.dataChanged')
     self._updated(
         self.model().rowCount(), self.selectionModel().selectedIndexes()
     )
    def mouseMoveEvent(self, event):
        """QGraphicsItem virtual
        """
        debug_print('ResizeHandle.mouseMoveEvent')

        # Vector difference between the mouse's position and current position,
        # both in client coordinates
        parent = self.parentItem()
        v = event.pos() - self.mapFromItem(parent, self.pos())
        if v.isNull():
            debug_print('v.isNull')
        else:
            # Compute adjustments to parent item's rect
            dx1 = dy1 = dx2 = dy2 = 0.0
            if Qt.TopLeftCorner == self._corner:
                dx1, dy1 = v.x(), v.y()
            elif Qt.TopRightCorner == self._corner:
                dx2, dy1 = v.x(), v.y()
            elif Qt.BottomLeftCorner == self._corner:
                dx1, dy2 = v.x(), v.y()
            else:
                dx2, dy2 = v.x(), v.y()

            rect = parent.rect().adjusted(dx1, dy1, dx2, dy2)

            if not rect.isValid():
                # A valid rectangle has a width() > 0 and height() > 0
                # rect will be invalid if the user has attempted to drag the box
                # inside out - prevent this
                pass
            else:
                parent.prepareGeometryChange()
                parent.setRect(rect)
Example #4
0
    def reset(self):
        "QAbstractItemView virtual"
        debug_print('MetadataView.reset')
        super(MetadataView, self).reset()

        # Clear the controls
        self._populate_controls()
    def zoom_to_items(self, items):
        """Centres view on the centre of the items and, if view is set to
        'fit to view', sets the zoom level to encompass items.
        Emits viewport_changed.
        """
        united = unite_rects(i.sceneBoundingRect() for i in items)
        if 'whole_scene' == self.zoom_mode:
            debug_print('Ensuring [{0}] items visible'.format(len(items)))
            self.ensureVisible(united)
            self.viewport_changed.emit(self.normalised_scene_rect())
        else:
            debug_print('Showing [{0}] items'.format(len(items)))
            # Add some padding around the selection
            padding = 20
            if 'follow_selection' == self.zoom_mode:
                # Update zoom
                united.adjust(-padding, -padding, 2 * padding, 2 * padding)
                self.fitInView(united, Qt.KeepAspectRatio)

                if self.absolute_zoom > self.MAXIMUM_ZOOM:
                    # new_absolute_zoom() emits viewport_changed
                    self.new_absolute_zoom(self.MAXIMUM_ZOOM)
                else:
                    self.viewport_changed.emit(self.normalised_scene_rect())
            else:
                # zoom_mode == fixed
                self.ensureVisible(united, xMargin=padding, yMargin=padding)
 def setRect(self, rect):
     """QGraphicsRectItem function
     """
     debug_print('BoxItem.setRect')
     super(BoxItem, self).setRect(rect)
     self._set_z_index()
     self._layout_children()
Example #7
0
    def add_path(self, path):
        "Adds path to recent documents"
        recent = self.read_paths()

        # Make the path absolute, resolving any symlinks.
        path = self._resolved_if_possible(Path(path))

        # Remove the existing occurrence of path, if present.
        # A linear scan is acceptable here because the list will always
        # be very short
        try:
            recent.remove(path)
        except ValueError:
            # path is not currently in recent
            pass

        # Prepend the path
        recent.insert(0, str(path))

        # Limit to MAX_RECENT_DOCS
        recent = recent[:self.MAX_RECENT_DOCS]

        debug_print('Writing {0} recent document paths'.format(len(recent)))

        settings = QSettings()
        settings.beginWriteArray(self.KEY, len(recent))
        try:
            for index, path in enumerate(recent):
                settings.setArrayIndex(index)
                settings.setValue('path', str(path))
        finally:
            settings.endArray()
Example #8
0
    def mouseMoveEvent(self, event):
        """QGraphicsItem virtual
        """
        debug_print('ResizeHandle.mouseMoveEvent')

        # Vector difference between the mouse's position and current position,
        # both in client coordinates
        parent = self.parentItem()
        v = event.pos() - self.mapFromItem(parent, self.pos())
        if v.isNull():
            debug_print('v.isNull')
        else:
            # Compute adjustments to parent item's rect
            dx1 = dy1 = dx2 = dy2 = 0.0
            if Qt.TopLeftCorner == self._corner:
                dx1, dy1 = v.x(), v.y()
            elif Qt.TopRightCorner == self._corner:
                dx2, dy1 = v.x(), v.y()
            elif Qt.BottomLeftCorner == self._corner:
                dx1, dy2 = v.x(), v.y()
            else:
                dx2, dy2 = v.x(), v.y()

            rect = parent.rect().adjusted(dx1, dy1, dx2, dy2)

            if not rect.isValid():
                # A valid rectangle has a width() > 0 and height() > 0
                # rect will be invalid if the user has attempted to drag the box
                # inside out - prevent this
                pass
            else:
                parent.prepareGeometryChange()
                parent.setRect(rect)
 def load(self, path):
     "Loads the UserTemplate in path"
     debug_print('UserTemplateChoice.load [{0}]'.format(path))
     self._current = self._load(path)
     QSettings().setValue(self.PATH_KEY, str(path))
     QSettings().setValue(self.DIRECTORY_KEY, str(Path(path).parent))
     self.template_changed.emit()
Example #10
0
    def from_document(self, document):
        """Load data from document
        """
        # Load the new data
        # Document promises that either the thumbnail or scanned image will be
        # available
        if document.thumbnail.available:
            debug_print('Model will work on thumbnail')
            image_array = document.thumbnail.array
        else:
            debug_print('Model will work on full-res scan')
            image_array = document.scanned.array

        pixmap = QPixmap.fromImage(qimage_of_bgr(image_array))
        if pixmap.isNull():
            raise ValueError('Unable to create QPixmap')
        else:
            data = self._boxes_from_items(
                document.items, pixmap.width(), pixmap.height()
            )

            # Inform views
            self.beginResetModel()
            self._data, self._image_array, self._pixmap = data, image_array, pixmap
            self.endResetModel()
Example #11
0
    def keyPressEvent(self, event):
        """QGraphicsScene virtual
        """
        debug_print('BoxesScene.keyPressEvent')

        key = event.key()

        # Mapping from cursor key to adjustment (dx1, dy1, dx2, dy2)
        cursors = {
            Qt.Key_Up:    ( 0.0,-1.0, 0.0,-1.0),
            Qt.Key_Right: ( 1.0, 0.0, 1.0, 0.0),
            Qt.Key_Down:  ( 0.0, 1.0, 0.0, 1.0),
            Qt.Key_Left:  (-1.0, 0.0,-1.0, 0.0),
        }

        if key in cursors:
            event.accept()
            dx1, dy1, dx2, dy2 = cursors[key]
            modifiers = event.modifiers()

            if Qt.ShiftModifier & modifiers and not Qt.AltModifier & modifiers:
                # Adjust the bottom-right corner
                dx1 = dy1 = 0.0
            elif not Qt.ShiftModifier & modifiers and Qt.AltModifier & modifiers:
                # Adjust the top-left corner
                dx2 = dy2 = 0.0

            if event.isAutoRepeat():
                # Larger steps when key is being held down
                multiplier = 4
                dx1, dy1, dx2, dy2 = [v * multiplier for v in (dx1, dy1, dx2, dy2)]
            self.adjust_selected(dx1, dy1, dx2, dy2)
        else:
            super(BoxesScene, self).keyPressEvent(event)
Example #12
0
    def keyPressEvent(self, event):
        """QGraphicsScene virtual
        """
        debug_print('BoxesScene.keyPressEvent')

        key = event.key()

        # Mapping from cursor key to adjustment (dx1, dy1, dx2, dy2)
        cursors = {
            Qt.Key_Up:    ( 0.0,-1.0, 0.0,-1.0),
            Qt.Key_Right: ( 1.0, 0.0, 1.0, 0.0),
            Qt.Key_Down:  ( 0.0, 1.0, 0.0, 1.0),
            Qt.Key_Left:  (-1.0, 0.0,-1.0, 0.0),
        }

        if key in cursors:
            event.accept()
            dx1, dy1, dx2, dy2 = cursors[key]
            modifiers = event.modifiers()

            if Qt.ShiftModifier & modifiers and not Qt.AltModifier & modifiers:
                # Adjust the bottom-right corner
                dx1 = dy1 = 0.0
            elif not Qt.ShiftModifier & modifiers and Qt.AltModifier & modifiers:
                # Adjust the top-left corner
                dx2 = dy2 = 0.0

            if event.isAutoRepeat():
                # Larger steps when key is being held down
                multiplier = 4
                dx1, dy1, dx2, dy2 = [v * multiplier for v in (dx1, dy1, dx2, dy2)]
            self.adjust_selected(dx1, dy1, dx2, dy2)
        else:
            super(BoxesScene, self).keyPressEvent(event)
Example #13
0
 def _set_message(self, message):
     """Slot for self.new_message
     """
     debug_print("WorkerThread._set_message [{0}]".format(message))
     # Must only be called from the main thread
     assert (self.thread() == QtCore.QThread.currentThread())
     self._progress_box.setLabelText(message)
Example #14
0
 def setRect(self, rect):
     """QGraphicsRectItem function
     """
     debug_print('BoxItem.setRect')
     super(BoxItem, self).setRect(rect)
     self._set_z_index()
     self._layout_children()
Example #15
0
    def add_path(self, path):
        "Adds path to recent documents"
        recent = self.read_paths()

        # Make the path absolute, resolving any symlinks.
        path = self._resolved_if_possible(Path(path))

        # Remove the existing occurrence of path, if present.
        # A linear scan is acceptable here because the list will always
        # be very short
        try:
            recent.remove(path)
        except ValueError:
            # path is not currently in recent
            pass

        # Prepend the path
        recent.insert(0, str(path))

        # Limit to MAX_RECENT_DOCS
        recent = recent[:self.MAX_RECENT_DOCS]

        debug_print('Writing {0} recent document paths'.format(len(recent)))

        settings = QSettings()
        settings.beginWriteArray(self.KEY, len(recent))
        try:
            for index, path in enumerate(recent):
                settings.setArrayIndex(index)
                settings.setValue('path', str(path))
        finally:
            settings.endArray()
    def mouseReleaseEvent(self, event):
        """QGraphicsItem virtual
        """
        debug_print('ResizeHandle.mouseReleaseEvent')

        # Redraw parent and corners
        self.parentItem().update()
Example #17
0
    def new_absolute_zoom(self, factor):
        """Sets a new absolute zoom
        """
        f = factor
        scene_rect = self.scene().sceneRect()  # Scene
        view_rect = self.viewport().rect()  # Available space
        # The size of the scene if the new transform is applied
        t_scene_rect = QtGui.QTransform.fromScale(f, f).mapRect(scene_rect)

        if (t_scene_rect.width() < view_rect.width()
                and t_scene_rect.height() < view_rect.height()):
            # The user wants to zoom out so that the image is smaller than the
            # view
            self.zoom_home()
        else:
            f = min(self.MAXIMUM_ZOOM, f)
            msg = 'Change absolute zoom from [{0}] to [{1}]'
            debug_print(msg.format(self.absolute_zoom, f))

            self.setTransform(QtGui.QTransform.fromScale(f, f))
            self.fit_to_view = False

            selected = self.scene().selectedItems()
            if selected:
                # Centre on selected items
                #self.ensureVisible(unite_rects([i.rect() for i in selected]))
                self.centerOn(
                    unite_rects([i.rect() for i in selected]).center())
Example #18
0
    def wheelEvent(self, event):
        """QGraphicsView virtual
        """

        if Qt.ControlModifier == event.modifiers(
        ) and not self.scene().is_empty:
            event.accept()
            # Wheel event delta is in units of 1/8 of a degree
            degrees = 8 * event.delta()

            # Compute a relative scale factor
            # Multiplier determined by experimenting with a mac trackpad and a
            # cheap Logitech wheel mouse
            multiplier = 0.0005
            f = 1.0 + degrees * multiplier
            if 0 < f < 2:
                debug_print(
                    'BoxesView.wheelEvent delta degrees [{0}] factor [{1}]'.
                    format(degrees, f))
                self.new_relative_zoom(f)
            else:
                pass
                # Extremely large wheel delta
        else:
            super(BoxesView, self).wheelEvent(event)
Example #19
0
    def selectionChanged(self, selected, deselected):
        """QAbstractItemView virtual
        """
        # Tell the scene about the new selection
        # TODO LH Use a timer to implement a delayed refresh
        if not self.handling_selection_update:
            # TODO Context for this
            debug_print('GraphicsItemView.selectionChanged')
            self.handling_selection_update = True
            try:
                current = set(self.scene.selectedItems())
                new = set(self._rows[i.row()]
                          for i in self.selectionModel().selectedIndexes())

                for item in new.difference(current):
                    item.setSelected(True)
                    item.update()

                for item in current.difference(new):
                    item.setSelected(False)
                    item.update()

                if 1 == len(new):
                    rect = new.pop().rect()
                    for view in self.scene.views():
                        view.centerOn(rect.center())
                elif 1 < len(new):
                    # Ensure that the selected items are visible
                    rect = unite_rects([i.rect() for i in new])
                    debug_print('GraphicsItemView will make visible', rect)
                    new.pop().ensureVisible(rect)
            finally:
                self.handling_selection_update = False
Example #20
0
    def _close_group(self, main_layout, group_name, group_layout):
        """Closes the the existing group, used during controls creation
        """
        debug_print('FormContainer._close_group close group', group_name)

        # The widget that holds this group's controls
        controls_widget = QWidget()
        controls_widget.setLayout(group_layout)

        if group_name:
            # Group controls start out hidden
            controls_widget.setVisible(False)

            # The group box, which contains the label to toggle the controls
            # and the controls themselves
            group_box_layout = QVBoxLayout()
            group_box_layout.addWidget(
                ToggleWidgetLabel(group_name,
                                  controls_widget,
                                  initially_visible=False))
            group_box_layout.addWidget(controls_widget)
            group_box_layout.setContentsMargins(
                0,  # left
                0,  # top
                0,  # right
                0  # bottom
            )
            group_box = QGroupBox()
            group_box.setLayout(group_box_layout)

            # Add the group box to the main layout
            main_layout.addRow(group_box)
        else:
            # current group has no name and therefore no toggle group
            main_layout.addRow(controls_widget)
Example #21
0
    def mouseReleaseEvent(self, event):
        """QGraphicsItem virtual
        """
        debug_print('ResizeHandle.mouseReleaseEvent')

        # Redraw parent and corners
        self.parentItem().update()
 def load(self, path):
     "Loads the UserTemplate in path"
     debug_print('UserTemplateChoice.load [{0}]'.format(path))
     self._current = self._load(path)
     QSettings().setValue(self.PATH_KEY, str(path))
     QSettings().setValue(self.DIRECTORY_KEY, str(Path(path).parent))
     self.template_changed.emit()
Example #23
0
    def _close_group(self, main_layout, group_name, group_layout):
        """Closes the the existing group, used during controls creation
        """
        debug_print('FormContainer._close_group close group', group_name)

        # The widget that holds this group's controls
        controls_widget = QWidget()
        controls_widget.setLayout(group_layout)

        if group_name:
            # Group controls start out hidden
            controls_widget.setVisible(False)

            # The group box, which contains the label to toggle the controls
            # and the controls themselves
            group_box_layout = QVBoxLayout()
            group_box_layout.addWidget(ToggleWidgetLabel(
                group_name, controls_widget, initially_visible=False
            ))
            group_box_layout.addWidget(controls_widget)
            group_box_layout.setContentsMargins(
                0,  # left
                0,  # top
                0,  # right
                0   # bottom
            )
            group_box = QGroupBox()
            group_box.setLayout(group_box_layout)

            # Add the group box to the main layout
            main_layout.addRow(group_box)
        else:
            # current group has no name and therefore no toggle group
            main_layout.addRow(controls_widget)
Example #24
0
 def _set_message(self, message):
     """Slot for self.new_message
     """
     debug_print("WorkerThread._set_message [{0}]".format(message))
     # Must only be called from the main thread
     assert(self.thread() == QtCore.QThread.currentThread())
     self._progress_box.setLabelText(message)
Example #25
0
    def reset(self):
        "QAbstractItemView virtual"
        debug_print('MetadataView.reset')
        super(MetadataView, self).reset()

        # Clear the controls
        self._populate_controls()
Example #26
0
    def zoom_to_items(self, items):
        """Centres view on the centre of the items and, if view is set to
        'fit to view', sets the zoom level to encompass items.
        Emits viewport_changed.
        """
        united = unite_rects(i.sceneBoundingRect() for i in items)
        if 'whole_scene' == self.zoom_mode:
            debug_print('Ensuring [{0}] items visible'.format(len(items)))
            self.ensureVisible(united)
            self.viewport_changed.emit(self.normalised_scene_rect())
        else:
            debug_print('Showing [{0}] items'.format(len(items)))
            # Add some padding around the selection
            padding = 20
            if 'follow_selection' == self.zoom_mode:
                # Update zoom
                united.adjust(-padding, -padding, 2 * padding, 2 * padding)
                self.fitInView(united, Qt.KeepAspectRatio)

                if self.absolute_zoom > self.MAXIMUM_ZOOM:
                    # new_absolute_zoom() emits viewport_changed
                    self.new_absolute_zoom(self.MAXIMUM_ZOOM)
                else:
                    self.viewport_changed.emit(self.normalised_scene_rect())
            else:
                # zoom_mode == fixed
                self.ensureVisible(united, xMargin=padding, yMargin=padding)
    def selectionChanged(self, selected, deselected):
        """QAbstractItemView virtual
        """
        # Tell the scene about the new selection
        # TODO LH Use a timer to implement a delayed refresh
        if not self.handling_selection_update:
            # TODO Context for this
            debug_print('GraphicsItemView.selectionChanged')
            self.handling_selection_update = True
            try:
                current = set(self.scene.selectedItems())
                new = set(self._rows[i.row()] for i in self.selectionModel().selectedIndexes())

                for item in new.difference(current):
                    item.setSelected(True)
                    item.update()

                for item in current.difference(new):
                    item.setSelected(False)
                    item.update()

                if new:
                    for view in self.scene.views():
                        view.zoom_to_items(new)
            finally:
                self.handling_selection_update = False
Example #28
0
    def close_document(self):
        """Closes the document and returns True if not modified or if modified
        and user does not cancel. Does not close the document and returns False
        if modified and users cancels.
        """
        debug_print('MainWindow.close_document')
        if self.model.modified:
            # Ask the user if they work like to save before closing
            res = QMessageBox.question(
                self, 'Save document?', 'Save the document before closing?',
                (QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel),
                QMessageBox.Yes)

            if QMessageBox.Yes == res:
                self.save_document()

            # Answering Yes or No means the document will be closed
            close = QMessageBox.Cancel != res
        else:
            # The document is not modified so it is OK to close it
            close = True

        if close:
            self.empty_document()

        return close
Example #29
0
    def keyPressEvent(self, event):
        """QGraphicsScene virtual
        """
        debug_print('BoxesScene.keyPressEvent')

        key = event.key()

        # Mapping from cursor key to adjustment (dx1, dy1, dx2, dy2)
        cursors = { Qt.Key_Up:    ( 0.0,-1.0, 0.0,-1.0),
                    Qt.Key_Right: ( 1.0, 0.0, 1.0, 0.0),
                    Qt.Key_Down:  ( 0.0, 1.0, 0.0, 1.0),
                    Qt.Key_Left:  (-1.0, 0.0,-1.0, 0.0),
                  }

        if key in cursors.keys():
            event.accept()
            dx1, dy1, dx2, dy2 = cursors[key]
            mod = event.modifiers()
            if Qt.ShiftModifier == mod:
                # Shift - move just the bottom-right corner
                dx1 = dy1 = 0.0
            elif Qt.ControlModifier == mod:
                # Control - move just the top-left corner
                dx2 = dy2 = 0.0

            self.adjust_selected(dx1, dy1, dx2, dy2)
        else:
            super(BoxesScene, self).keyPressEvent(event)
Example #30
0
    def save_crops(self):
        """Saves cropped specimen images
        """
        debug_print('MainWindow.save_crops')
        res = QMessageBox.Yes
        existing_crops = self.document.crops_dir.is_dir()

        if existing_crops:
            msg = 'Overwrite the existing cropped specimen images?'
            res = QMessageBox.question(self, 'Write cropped specimen images?',
                                       msg, QMessageBox.No, QMessageBox.Yes)

        if QMessageBox.Yes == res:

            def save_crops(progress):
                progress('Loading full-resolution scanned image')
                self.document.scanned.array

                progress('Saving crops')
                self.document.save_crops(progress)

            def completed(operation):
                QMessageBox.information(self, "Crops saved", msg)

            self.model.to_document(self.document)
            msg = "{0} crops saved in {1}"
            msg = msg.format(self.document.n_items, self.document.crops_dir)
            self.run_in_worker(save_crops, 'Save crops', completed)
Example #31
0
    def insertRows(self, row, count, parent=QModelIndex()):
        """QAbstractItemModel virtual
        """
        debug_print('Model.insertRows row [{0}] count [{1}]'.format(row, count))

        if row < 0 or row > len(self._data) or count < 1:
            raise ValueError('Bad row [{0}] or count [{1}]'.format(row, count))
        else:
            upper = row + count - 1
            self.beginInsertRows(QModelIndex(), row, upper)

            # Create list of new rows. Cannot use [{whatever}] * count because
            # this will create the same dict instance repeated 'count' times,
            # not 'count' different dict instances
            new_rows = [None] * count
            for i in range(0, count):
                new_rows[i] = {
                    "fields": {},
                    "rect": QRect(0, 0, 0, 0),
                    "rotation": 0
                }

            self._data[row:row] = new_rows
            self.set_modified(True)
            self.endInsertRows()
            self.dataChanged.emit(self.index(row, 0), self.index(upper, 0))

            return True
def export_csv(dir, overwrite_existing, template):
    dir = Path(dir)
    export = DocumentExport(UserTemplate.load(template) if template else DWC)
    for p in dir.glob('*' + InselectDocument.EXTENSION):
        try:
            debug_print('Loading [{0}]'.format(p))
            doc = InselectDocument.load(p)
            validation = export.validation_problems(doc)
            csv_path = export.csv_path(doc)
            if validation.any_problems:
                print(
                    'Not exporting metadata for [{0}] because there are '
                    'validation problems'.format(p)
                )
                for msg in format_validation_problems(validation):
                    print(msg)
            elif not overwrite_existing and csv_path.is_file():
                print('CSV file [{0}] exists - skipping'.format(csv_path))
            else:
                print('Writing CSV for [{0}]'.format(p))
                export.export_csv(doc)
        except KeyboardInterrupt:
            raise
        except Exception:
            print('Error saving CSV from [{0}]'.format(p))
            traceback.print_exc()
 def create_and_use(self, boxes, path):
     """Creates a new CookieCutter file that contains boxes, writes in to
     path and sets it to be the current choice
     """
     debug_print('CookieCutterChoice.create_and_use to [{0}]'.format(path))
     cookie_cutter = CookieCutter('', boxes)
     cookie_cutter.save(path)
     self.load(path)
 def changed(self):
     "Slot for UserTemplateChoice.template_changed"
     debug_print('UserTemplateWidget.changed')
     choice = user_template_choice()
     self.setText(choice.current.name)
     self._default_action.setEnabled(not choice.current_is_default)
     self._refresh_action.setEnabled(not choice.current_is_default)
     self._reveal_template_action.setEnabled(not choice.current_is_default)
Example #35
0
 def dragEnterEvent(self, event):
     """QWidget virtual
     """
     debug_print('MainWindow.dragEnterEvent')
     if self._accept_drag_drop(event):
         event.acceptProposedAction()
     else:
         super(MainWindow, self).dragEnterEvent(event)
Example #36
0
 def append_point_of_interest(self, pos):
     """Appends pos (a QPoint relative to the top-left of this box) to the
     list of points of interest
     """
     debug_print('New point of interest at [{0}]'.format(pos))
     self._pois.append(Reticle(pos - self.boundingRect().topLeft(), self))
     self._pois[-1].layout(self.boundingRect())
     self._pois[-1].setFlags(QGraphicsItem.ItemIgnoresTransformations)
Example #37
0
    def selectionChanged(self, selected, deselected):
        """QAbstractItemView slot
        """
        debug_print('SpecimenView.selectionChanged')

        # Grid view unless exactly one item selected
        if self.expanded and 1 != len(self.selectionModel().selectedIndexes()):
            self.show_grid()
 def changed(self):
     "Slot for UserTemplateChoice.template_changed"
     debug_print('UserTemplateWidget.changed')
     choice = user_template_choice()
     self.setText(choice.current.name)
     self._default_action.setEnabled(not choice.current_is_default)
     self._refresh_action.setEnabled(not choice.current_is_default)
     self._reveal_template_action.setEnabled(not choice.current_is_default)
Example #39
0
 def mouseReleaseEvent(self, event):
     """QGraphicsRectItem virtual
     """
     debug_print('BoxItem.mouseReleaseEvent')
     super(BoxItem, self).mouseReleaseEvent(event)
     self.setCursor(Qt.OpenHandCursor)
     self._set_z_index()
     self.update()
Example #40
0
 def user_template_changed(self):
     """Informs the model that the user's choice of metadata template has
     changed. Informs all views.
     """
     debug_print('Model.user_template_changed')
     if self._data:
         self.dataChanged.emit(self.index(0, 0),
                               self.index(self.rowCount()-1, 0))
Example #41
0
 def rowsAboutToBeRemoved(self, parent, start, end):
     """QAbstractItemView slot
     """
     debug_print('SummaryView.rowsAboutToBeRemoved')
     self._updated(
         self.model().rowCount() - (end - start),
         self.selectionModel().selectedIndexes()
     )
Example #42
0
 def hoverLeaveEvent(self, event):
     """QGraphicsRectItem virtual
     """
     debug_print('BoxItem.hoverLeaveEvent')
     super(BoxItem, self).hoverLeaveEvent(event)
     self._set_handles_visible(False)
     self._set_z_index()
     self.update()
Example #43
0
 def append_point_of_interest(self, pos):
     """Appends pos (a QPoint relative to the top-left of this box) to the
     list of points of interest
     """
     debug_print('New point of interest at [{0}]'.format(pos))
     self._pois.append(Reticle(pos - self.boundingRect().topLeft(), self))
     self._pois[-1].layout(self.boundingRect())
     self._pois[-1].setFlags(QGraphicsItem.ItemIgnoresTransformations)
Example #44
0
    def reset(self):
        """QAbstractItemView virtual
        """
        debug_print('MetadataView.reset')
        super(MetadataView, self).reset()

        # Clear the controls
        self.selectionChanged([], [])
Example #45
0
 def mouseReleaseEvent(self, event):
     """QGraphicsRectItem virtual
     """
     debug_print('BoxItem.mouseReleaseEvent')
     super(BoxItem, self).mouseReleaseEvent(event)
     self.setCursor(Qt.OpenHandCursor)
     self._set_z_index()
     self.update()
Example #46
0
 def hoverLeaveEvent(self, event):
     """QGraphicsRectItem virtual
     """
     debug_print('BoxItem.hoverLeaveEvent')
     super(BoxItem, self).hoverLeaveEvent(event)
     self._set_handles_visible(False)
     self._set_z_index()
     self.update()
Example #47
0
 def _user_selected_item(self):
     """The user changed the selected item
     """
     debug_print('FieldComboBox._user_selected_item', self._field)
     value = self.itemData(self.currentIndex())
     new = {self._field: value}
     for i in self.selected:
         i.model().setData(i, new, MetadataRole)
 def load(self, path):
     """Loads the CookieCutter in path, updates settings and emits
     cookie_cutter_changed
     """
     debug_print('CookieCutterChoice.load [{0}]'.format(path))
     self._current = self._load(path)
     QSettings().setValue(self.PATH_KEY, str(path))
     QSettings().setValue(self.DIRECTORY_KEY, str(Path(path).parent))
     self.cookie_cutter_changed.emit()
Example #49
0
 def toggle_expanded(self, index):
     """Selects 'index' and toggles the expanded state
     """
     debug_print('ObjectView.toggle_expanded')
     self.selectionModel().select(index, QItemSelectionModel.Select)
     if self.expanded:
         self.show_grid()
     else:
         self.show_expanded()
 def __init__(self):
     super(UserTemplateChoice, self).__init__()
     self._current = self.DEFAULT
     previous = QSettings().value(self.PATH_KEY)
     if previous:
         try:
             self._current = self._load(previous)
         except Exception:
             debug_print('Error loading user template [{0}]'.format(previous))
Example #51
0
    def selectionChanged(self, selected, deselected):
        "QAbstractItemView slot"
        debug_print('MetadataView.selectionChanged')

        # If one of our controls has focus, update the model before refreshing
        # the UI
        if QtWidgets.qApp.focusWidget() in self._form_container.controls:
            QtWidgets.qApp.focusWidget().update_model()
        self._populate_controls()
Example #52
0
 def toggle_expanded(self, index):
     """Selects 'index' and toggles the expanded state
     """
     debug_print('ObjectView.toggle_expanded')
     self.selectionModel().select(index, QItemSelectionModel.Select)
     if self.expanded_action.isChecked():
         self.grid_action.trigger()
     else:
         self.expanded_action.trigger()
Example #53
0
    def selectionChanged(self, selected, deselected):
        "QAbstractItemView slot"
        debug_print('MetadataView.selectionChanged')

        # If one of our controls has focus, update the model before refreshing
        # the UI
        if QtWidgets.qApp.focusWidget() in self._form_container.controls:
            QtWidgets.qApp.focusWidget().update_model()
        self._populate_controls()
Example #54
0
    def selectionChanged(self, selected, deselected):
        """QAbstractItemView slot
        """
        debug_print('ObjectView.selectionChanged')

        # Grid view unless exactly one item selected
        if self.expanded and 1 != len(self.selectionModel().selectedIndexes()):
            self.show_grid()

        super(ObjectView, self).selectionChanged(selected, deselected)
 def show_alternative_pixmap(self, pixmap):
     """Show or clear an alternative pixmap in place of the document's usual
     pixmap. pixmaps should either be a QPixmap of the same dimensions as the
     documents pixmap (which is shown) or None (which clears any existing
     alternative pixmap)
     """
     debug_print('show_alternative_pixmap', pixmap)
     model = self.model()
     pixmap = pixmap if pixmap else model.data(QModelIndex(), PixmapRole)
     self.scene.set_pixmap(pixmap)