Exemplo n.º 1
0
 def testArrowContact(self, indices, x, y):
     if type(indices) != list: indices = [indices]
     for index in indices:
         if index >= len(self.attributes) or index < 0:
             continue
         int_x = self.transform(xBottom, index)
         bottom = self.transform(
             yLeft,
             self.selection_conditions.get(self.attributes[index],
                                           [0, 1])[0])
         bottom_rect = QRect(int_x - self.bottom_pixmap.width() / 2, bottom,
                             self.bottom_pixmap.width(),
                             self.bottom_pixmap.height())
         if bottom_rect.contains(QPoint(x, y)):
             return 1, (index, 0)
         top = self.transform(
             yLeft,
             self.selection_conditions.get(self.attributes[index],
                                           [0, 1])[1])
         top_rect = QRect(int_x - self.top_pixmap.width() / 2,
                          top - self.top_pixmap.height(),
                          self.top_pixmap.width(), self.top_pixmap.height())
         if top_rect.contains(QPoint(x, y)):
             return 1, (index, 1)
     return 0, (0, 0)
Exemplo n.º 2
0
    def mouseMoveEvent(self, event):
        '''Overrides QWidget's mouseMoveEvent. Handles resizing
        and dragging operations on selection'''
        # pylint: disable=C0103
        sel_rect = self._selection_rect
        if self._resize_start:
            resize_end = event.pos() / self._zoom
            sel_rect.setBottomRight(sel_rect.bottomRight() +
                                    (resize_end - self._resize_start))
            self._resize_start = resize_end
            self.make_selection_square()
            self.update()
        elif self._drag_start is not None:
            drag_end = event.pos() / self._zoom
            sel_rect.translate(drag_end - self._drag_start)
            self._drag_start = drag_end
            self.update()

        # cursor shape:
        mouse_pos = event.pos() / self._zoom
        if (not sel_rect.isNull()) and sel_rect.contains(mouse_pos, True):
            handle_rect = QRect(sel_rect.bottomRight(), self._handle_size)
            if handle_rect.contains(mouse_pos):
                self.setCursor(Qt.SizeFDiagCursor)
            else:
                self.setCursor(Qt.OpenHandCursor)

        else:
            self.setCursor(Qt.CrossCursor)
    def __autoScrollAdvance(self):
        """Advance the auto scroll
        """
        pos = QCursor.pos()
        pos = self.mapFromGlobal(pos)
        margin = self.__autoScrollMargin

        vvalue = self.verticalScrollBar().value()
        hvalue = self.horizontalScrollBar().value()

        vrect = QRect(0, 0, self.width(), self.height())

        # What should be the speed
        advance = 10

        # We only do auto scroll if the mouse is inside the view.
        if vrect.contains(pos):
            if pos.x() < vrect.left() + margin:
                self.horizontalScrollBar().setValue(hvalue - advance)
            if pos.y() < vrect.top() + margin:
                self.verticalScrollBar().setValue(vvalue - advance)
            if pos.x() > vrect.right() - margin:
                self.horizontalScrollBar().setValue(hvalue + advance)
            if pos.y() > vrect.bottom() - margin:
                self.verticalScrollBar().setValue(vvalue + advance)

            if self.verticalScrollBar().value() == vvalue and \
                    self.horizontalScrollBar().value() == hvalue:
                self.__stopAutoScroll()
        else:
            self.__stopAutoScroll()

        log.debug("Auto scroll advance")
    def mouseReleaseEvent(self, event):
        """ 
        Обрабатываем нажатие на иконку 'Интересно/Скучно' как нажатие на обычный чекбокс
        
        Решение достаточно грубое, но в данной ситуации вполне себе работает. Перехватывать нужно 
        отпускание мыши, потому что в QAbstractItemView редактирование запускается именно по 
        отпусканию. 
        
        """

        if event.pos().x() < settings.entryIconWidth():
            item = self.itemAt(event.pos())
            item.setSelected(True)
            rect = self.visualItemRect(item)
            iconRect = QRect(rect.left(),
                             rect.top(),
                             settings.entryIconWidth(),
                             settings.entryIconHeight())
            if iconRect.contains(event.pos()):
                if item.checkState() == Qt.Checked:
                    item.setCheckState(Qt.Unchecked)
                else:
                    item.setCheckState(Qt.Checked)
        else:
            QListWidget.mousePressEvent(self, event)
Exemplo n.º 5
0
 def mouseMoveEvent (self, event):
     '''Overrides QWidget's mouseMoveEvent. Handles resizing
     and dragging operations on selection'''
     # pylint: disable=C0103
     sel_rect = self._selection_rect
     if self._resize_start:
         resize_end = event.pos() / self._zoom
         sel_rect.setBottomRight(sel_rect.bottomRight() +
                                 (resize_end - self._resize_start))
         self._resize_start = resize_end
         self.make_selection_square()
         self.update()
     elif self._drag_start is not None:
         drag_end = event.pos() / self._zoom
         sel_rect.translate(drag_end - self._drag_start)
         self._drag_start = drag_end
         self.update()
         
     # cursor shape:
     mouse_pos = event.pos() / self._zoom
     if (not sel_rect.isNull()) and sel_rect.contains(mouse_pos, True):
         handle_rect = QRect(sel_rect.bottomRight(), self._handle_size)
         if handle_rect.contains(mouse_pos):
             self.setCursor(Qt.SizeFDiagCursor)
         else:
             self.setCursor(Qt.OpenHandCursor)
             
     else:
         self.setCursor(Qt.CrossCursor)
Exemplo n.º 6
0
 def _dropEvent(self, partition, pos):
     for block in self._accepted_blocks:
         bpos = self.parentWidget().mapToGlobal(block.pos())
         bpos = QRect(bpos, block.size())
         if bpos.contains(pos):
             print 'Partition "%s" from "%s" dropped on the block "%s"' % \
                     (partition.text(), partition.parentWidget()._name, block._name)
             for _partition in block._partitions:
                 bpos = _partition.parentWidget().mapToGlobal(_partition.pos())
                 rect =  QRect(bpos, _partition.size())
                 if rect.contains(pos, proper = True):
                     print 'Partition "%s" dropped on the partition "%s (%s-%s)"' % \
                             (partition.text(), _partition.text(), _partition._fs_type, _partition._size)
                     if _partition._fs_type == FREE and _partition._size >= partition._size:
                         print 'It is ok to create a new partition !'
                         block.updatePartition(_partition, partition)
                         self.deletePartition(partition, fillFree = True)
                         break
Exemplo n.º 7
0
 def testArrowContact(self, indices, x, y):
     if type(indices) != list: indices = [indices]
     for index in indices:
         if index >= len(self.attributes) or index < 0:
             continue
         int_x = self.transform(xBottom, index)
         bottom = self.transform(yLeft,
                                 self.selection_conditions.get(self.attributes[index], [0, 1])[0])
         bottom_rect = QRect(int_x - self.bottom_pixmap.width() / 2, bottom, self.bottom_pixmap.width(),
                             self.bottom_pixmap.height())
         if bottom_rect.contains(QPoint(x, y)):
             return 1, (index, 0)
         top = self.transform(yLeft,
                              self.selection_conditions.get(self.attributes[index], [0, 1])[1])
         top_rect = QRect(int_x - self.top_pixmap.width() / 2, top - self.top_pixmap.height(),
                          self.top_pixmap.width(),
                          self.top_pixmap.height())
         if top_rect.contains(QPoint(x, y)):
             return 1, (index, 1)
     return 0, (0, 0)
Exemplo n.º 8
0
 def mousePressEvent(self, event):
 
     if event.button() != Qt.LeftButton:
         return
     
     size = self.height() / 2.0
     rect = QRect(self.width() - size, size * 0.5, size, size)
     
     if rect.contains(event.pos()):
         self.clear()
         self.valid = True
         event.accept()
Exemplo n.º 9
0
    def mouseMoveEvent(self, event):
        if self._interaction.moving:
            mouse_position = event.globalPos()
            offset = mouse_position - self._interaction.mouse_last_position
            if self.parent() is not None:
                parent_rect = self.parent().rect()
                old_geometry = self.geometry()
                new_geometry = old_geometry.translated(offset)
                if new_geometry.left() < 0:
                    new_geometry.moveLeft(0)
                if new_geometry.top() < 0:
                    new_geometry.moveTop(0)
                if new_geometry.right() > parent_rect.right():
                    new_geometry.moveRight(parent_rect.right())
                if new_geometry.bottom() > parent_rect.bottom():
                    new_geometry.moveBottom(parent_rect.bottom())
                offset = new_geometry.topLeft() - old_geometry.topLeft()
            self.move(self.pos() + offset)
            self._interaction.mouse_last_position += offset
        elif self._interaction.resizing:
            mouse_position = event.globalPos()
            delta_y = mouse_position.y() - self._interaction.mouse_last_position.y()
            geometry = self.geometry()

            if self._interaction.resize_corner is self.TopLeftCorner:
                delta_x = -(self.width_for_height(geometry.height() - delta_y) - geometry.width())
                geometry.setTopLeft(geometry.topLeft() + QPoint(delta_x, delta_y))
            elif self._interaction.resize_corner is self.TopRightCorner:
                delta_x =  (self.width_for_height(geometry.height() - delta_y) - geometry.width())
                geometry.setTopRight(geometry.topRight() + QPoint(delta_x, delta_y))
            elif self._interaction.resize_corner is self.BottomLeftCorner:
                delta_x = -(self.width_for_height(geometry.height() + delta_y) - geometry.width())
                geometry.setBottomLeft(geometry.bottomLeft() + QPoint(delta_x, delta_y))
            else:
                delta_x =  (self.width_for_height(geometry.height() + delta_y) - geometry.width())
                geometry.setBottomRight(geometry.bottomRight() + QPoint(delta_x, delta_y))

            if self.minimumHeight() <= geometry.height() <= self.maximumHeight() and (self.parent() is None or self.parent().rect().contains(geometry)):
                self.setGeometry(geometry)
                self._interaction.mouse_last_position = mouse_position
        elif self.interactive:
            mouse_position = event.pos()
            topbar_rect = QRect(0, 0, self.width(), 10)

            if self.rect().adjusted(0, 10, 0, -10).contains(mouse_position):
                self.setCursor(Qt.ArrowCursor)
            elif topbar_rect.contains(mouse_position):
                self.setCursor(self.cursors.resize_top)
            else:
                self.setCursor(self.cursors.resize_bottom)
Exemplo n.º 10
0
 def replace(self):
     log.trace("Icon is %r", self._icon)
     self._icon_geometry = rect = self._icon.geometry()
     log.trace("IconRect is : %s,%s | %s,%s", rect.x(), rect.y(),
               rect.width(), rect.height())
     from PyQt4.QtGui import QApplication, QCursor
     from PyQt4.QtCore import QRect
     desktop = QApplication.desktop()
     log.trace("Screen id is %d", desktop.screenNumber(rect.topLeft()))
     desk = desktop.screenGeometry(desktop.screenNumber(rect.topLeft()))
     log.trace("ScreenRect is : %s,%s | %s,%s", desk.x(), desk.y(),
               desk.width(), desk.height())
     pos = QCursor.pos()
     log.trace("Cursor is : %s,%s", pos.x(), pos.y())
     # Make our calculation on a offset screen to 0/0
     rect = QRect(rect.x() - desk.x(),
                  rect.y() - desk.y(), rect.width(), rect.height())
     pos.setX(pos.x() - desk.x())
     pos.setY(pos.y() - desk.y())
     if not rect.contains(pos) or (rect.x() == 0 and rect.y() == 0):
         # Avoid any modulo 0
         if rect.width() == 0 or rect.height() == 0:
             rect = QRect(pos.x(), pos.y(), rect.width(), rect.height())
         else:
             rect = QRect(pos.x() - pos.x() % rect.width(),
                          pos.y() - pos.y() % rect.height(), rect.width(),
                          rect.height())
         log.trace("Adjusting X/Y to %d/%d", rect.x(), rect.y())
         pos = rect
         self._icon_geometry = QRect(rect.x() + desk.x(),
                                     rect.y() + desk.y(), rect.width(),
                                     rect.height())
         log.trace("New rect is : %s,%s | %s,%s", pos.x(), pos.y(),
                   pos.width(), pos.height())
     x = rect.x() + rect.width() - self.width()
     y = rect.y() - self.height()
     # Prevent the systray to be hidden
     if y < 0:
         y = rect.y() + rect.height()
     if x < 0:
         x = rect.x()
     # Use the offset again
     x += desk.x()
     y += desk.y()
     log.trace("Move systray menu to %d/%d", x, y)
     self.move(x, y)
Exemplo n.º 11
0
 def mousePressEvent (self, event):
     '''Overrides QWidget's mousePressEvent. Handles starting
     a new selection, starting a drag operation'''
     # pylint: disable=C0103
     mouse_pos = event.pos() / self._zoom
     sel_rect = self._selection_rect
     
     if not event.button() == Qt.LeftButton:
         return
     
     if (not sel_rect.isNull()) and sel_rect.contains(mouse_pos, True):
         handle_rect = QRect(sel_rect.bottomRight(), self._handle_size)
         if handle_rect.contains(mouse_pos):
             self._resize_start = mouse_pos
         else:
             self._drag_start = mouse_pos
     else:
         self._resize_start = mouse_pos
         sel_rect.setTopLeft    (mouse_pos)
         self._selection_rect.setSize(QSize(0, 0))
Exemplo n.º 12
0
    def mousePressEvent(self, event):
        '''Overrides QWidget's mousePressEvent. Handles starting
        a new selection, starting a drag operation'''
        # pylint: disable=C0103
        mouse_pos = event.pos() / self._zoom
        sel_rect = self._selection_rect

        if not event.button() == Qt.LeftButton:
            return

        if (not sel_rect.isNull()) and sel_rect.contains(mouse_pos, True):
            handle_rect = QRect(sel_rect.bottomRight(), self._handle_size)
            if handle_rect.contains(mouse_pos):
                self._resize_start = mouse_pos
            else:
                self._drag_start = mouse_pos
        else:
            self._resize_start = mouse_pos
            sel_rect.setTopLeft(mouse_pos)
            self._selection_rect.setSize(QSize(0, 0))
Exemplo n.º 13
0
 def replace(self):
     log.trace("Icon is %r", self._icon)
     self._icon_geometry = rect = self._icon.geometry()
     log.trace("IconRect is : %s,%s | %s,%s",rect.x(), rect.y(), rect.width(), rect.height())
     from PyQt4.QtGui import QApplication, QCursor
     from PyQt4.QtCore import QRect
     desktop = QApplication.desktop()
     log.trace("Screen id is %d", desktop.screenNumber(rect.topLeft()))
     desk = desktop.screenGeometry(desktop.screenNumber(rect.topLeft()))
     log.trace("ScreenRect is : %s,%s | %s,%s",desk.x(), desk.y(), desk.width(), desk.height())
     pos = QCursor.pos()
     log.trace("Cursor is : %s,%s",pos.x(), pos.y())
     # Make our calculation on a offset screen to 0/0
     rect = QRect(rect.x()-desk.x(), rect.y()-desk.y(), rect.width(), rect.height())
     pos.setX(pos.x()-desk.x())
     pos.setY(pos.y()-desk.y())
     if not rect.contains(pos) or (rect.x() == 0 and rect.y() == 0):
         # Avoid any modulo 0
         if rect.width() == 0 or rect.height() == 0:
             rect = QRect(pos.x(), pos.y(), rect.width(), rect.height())
         else:
             rect = QRect(pos.x()-pos.x()%rect.width(), pos.y()-pos.y()%rect.height(), rect.width(), rect.height())
         log.trace("Adjusting X/Y to %d/%d", rect.x(), rect.y())
         pos = rect
         self._icon_geometry = QRect(rect.x()+desk.x(), rect.y()+desk.y(), rect.width(), rect.height())
         log.trace("New rect is : %s,%s | %s,%s",pos.x(), pos.y(), pos.width(), pos.height())
     x = rect.x() + rect.width() - self.width()
     y = rect.y() - self.height()
     # Prevent the systray to be hidden
     if y < 0:
         y = rect.y() + rect.height()
     if x < 0:
         x = rect.x()
     # Use the offset again
     x += desk.x()
     y += desk.y()
     log.trace("Move systray menu to %d/%d", x, y)
     self.move(x, y)
Exemplo n.º 14
0
 def mouseReleaseEvent(self, event):
     """ 
     Обрабатываем нажатие на иконку 'Интересно/Скучно' как нажатие на обычный чекбокс
     
     Решение достаточно грубое, но в данной ситуации вполне себе работает. Перехватывать нужно 
     отпускание мыши, потому что в QAbstractItemView редактирование запускается именно по 
     отпусканию. 
     
     """
     item = self.itemAt(event.pos())
     if self._itemIsCategory(item) and event.pos().x() < 20:
         item.setExpanded(not item.isExpanded())
     elif item is not None and event.pos().x() < settings.entryIconWidth():
         item.setSelected(True)
         rect = self.visualItemRect(item)
         iconRect = QRect(rect.left(),
                          rect.top() + (rect.height() - settings.entryIconHeight()) / 2,
                          settings.entryIconWidth(),
                          settings.entryIconHeight())
         if iconRect.contains(event.pos()):
             self._invertItemCheckState(item)
     else:
         QTreeWidget.mouseReleaseEvent(self, event)
Exemplo n.º 15
0
class LegendWidget(legend_widget, QWidget):
    showmap = pyqtSignal()

    def __init__(self, parent=None):
        super(LegendWidget, self).__init__(parent)
        self.setupUi(self)
        self.pixmap = QPixmap()
        self.items = {}
        self.framerect = QRect()
        self._lastextent = None

        self.legendareabrush = QBrush(QColor(255,255,255,200))
        self.legendareapen = QPen(QColor(255,255,255,20))
        self.legendareapen.setWidth(0.5)

    def paintEvent(self, event):
        def itemlist(items):
            for layer, items in self.items.iteritems():
                if len(items) == 1:
                    yield layer, items[0][1]
                else:
                    for text, icon in items:
                        if not text:
                            continue
                        yield text, icon

        def _drawitem(pixmap, text, itempostion):
            painter.drawPixmap(itempostion, pixmap)
            textrect = QRectF(pixmap.width() + currentx + 10,
                              itempostion.y(),
                              event.rect().width() - pixmap.width() - OFFSET_X,
                              pixmap.height())
            painter.drawText(textrect, text, QTextOption(Qt.AlignVCenter))

        def calcitems():
            font = painter.font()
            metrices = QFontMetrics(font)
            maxwidth = 0
            maxheight = 0
            for item, _ in itemlist(self.items):
                maxwidth = max(metrices.boundingRect(item).width(), maxwidth)
                maxheight = max(metrices.boundingRect(item).height(), maxheight)
            return maxwidth, maxheight

        if not self.pixmap:
            return

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)
        painter.drawPixmap(event.rect(), self.pixmap)

        itemwidths, itemmaxheight = calcitems()
        OFFSET_X = 30
        OFFSET_Y = itemmaxheight + 10
        rect = event.rect()
        neededheight = (len(self.items) * OFFSET_Y)
        runs = 1
        if neededheight > rect.height():
            import math
            runs = math.ceil(neededheight / float(rect.height()))
            print runs

        framerect = QRect(rect)
        framewidth = (itemwidths + OFFSET_X + ICON_SIZE.width() + 100) * runs
        framerect.setWidth(framewidth)
        painter.setBrush(self.legendareabrush)
        painter.setPen(self.legendareapen)
        painter.drawRect(framerect)
        self.framerect = framerect

        painter.setPen(Qt.black)
        currenty = OFFSET_Y
        currentx = OFFSET_X
        position = rect.topLeft() + QPoint(OFFSET_X, currenty)
        for text, icon in itemlist(self.items):
            itempostion = QPoint(position)
            if currenty > rect.height():
                currentx = itemwidths + OFFSET_X + 100
                currenty = itemmaxheight + 10

            itempostion.setX(currentx)
            itempostion.setY(currenty)

            _drawitem(icon, text, itempostion)
            currenty += OFFSET_Y

        position.setY(currenty + OFFSET_Y)


    def mousePressEvent(self, event):
        if self.framerect.contains(event.pos()):
            return

        self.showmap.emit()


    def updateitems(self, layers):
        self.items = {}
        for layer in layers:
            if not layer.type() == QgsMapLayer.VectorLayer:
                continue

            try:
                items = layer.rendererV2().legendSymbologyItems(ICON_SIZE)
            except AttributeError:
                continue
            self.items[layer.name()] = items
        self.update()

    def updatecanvas(self, canvas):
        """
        Update the canvas object for the legend background.
        """
        if canvas.isDrawing() or self._lastextent == canvas.extent():
            return

        self._lastextent = canvas.extent()
        pixmap = QPixmap(self.size())
        pixmap.fill(canvas.canvasColor())
        painter = QPainter(pixmap)
        painter.setRenderHints(QPainter.Antialiasing)
        renderer = canvas.mapRenderer()
        renderer.render(painter)
        del painter
        self.pixmap = pixmap
        self.update()
Exemplo n.º 16
0
class VispaWidgetOwner(object):
    """ Interface for classes containing VispaWidgets
    
    Only makes sense if implementing class also inherits QWidget or class inheriting QWidget.
    """
    def enableMultiSelect(self, multiSelect=True):
        self._multiSelectEnabledFlag = multiSelect

    def multiSelectEnabled(self):
        return hasattr(
            self, "_multiSelectEnabledFlag") and self._multiSelectEnabledFlag

    def selectedWidgets(self):
        """ Returns a list of all selected widgets.
        """
        if hasattr(self, "_selectedWidgets"):
            return self._selectedWidgets
        return [
            child for child in self.children()
            if hasattr(child, "isSelected") and child.isSelected()
        ]

    def widgetSelected(self, widget, multiSelect=False):
        """ Forward selection information to super class if it is a VispaWidgetOwner.
        """
        logging.debug(self.__class__.__name__ + ": widgetSelected()")

        if isinstance(self, QObject):
            if not hasattr(self, "_selectedWidgets"):
                self._selectedWidgets = []

            if not multiSelect or not self.multiSelectEnabled():
                self.deselectAllWidgets(widget)
                self._selectedWidgets = []

            if widget.parent() == self and not widget in self._selectedWidgets:
                self._selectedWidgets.append(widget)

            for widget in [
                    child for child in self._selectedWidgets
                    if hasattr(child, "isSelected") and not child.isSelected()
            ]:
                self._selectedWidgets.remove(widget)

            if isinstance(self.parent(), VispaWidgetOwner):
                self.parent().widgetSelected(widget)

    def widgetDoubleClicked(self, widget):
        """ Forward selection information to super class if it is a VispaWidgetOwner.
        """
        #logging.debug(self.__class__.__name__ +": widgetDoubleClicked()")
        if isinstance(self, QObject):
            if isinstance(self.parent(), VispaWidgetOwner):
                self.parent().widgetDoubleClicked(widget)

    def initWidgetMovement(self, widget):
        self._lastMovedWidgets = []
        if self.multiSelectEnabled():
            pos = widget.pos()
            for child in self.children():
                if child != widget and hasattr(
                        child, "isSelected") and child.isSelected():
                    child.setDragReferencePoint(pos - child.pos())

    def widgetDragged(self, widget):
        """ Tell parent widget has moved.
        
        Only informs parent if it is a VispaWidgetOwner, too.
        """
        if isinstance(self.parent(), VispaWidgetOwner):
            self.parent().widgetDragged(widget)

        if hasattr(self, "_lastMovedWidgets"):
            self._lastMovedWidgets.append(widget)

        if self.multiSelectEnabled():
            for child in self.children():
                if hasattr(
                        child,
                        "dragReferencePoint") and child != widget and hasattr(
                            child, "isSelected") and child.isSelected():
                    if hasattr(child, "setPreviousDragPosition"):
                        child.setPreviousDragPosition(child.pos())
                    child.move(widget.pos() - child.dragReferencePoint())
                    self._lastMovedWidgets.append(child)

# apparently unused feature (2010-07-02), remove if really unnecessary
# also see self._lastMovedWidget definition above

    def lastMovedWidgets(self):
        if hasattr(self, "_lastMovedWidgets"):
            return self._lastMovedWidgets
        return None

    def widgetAboutToDelete(self, widget):
        """ This function is called from the delete() function of VispaWidget.
        """
        pass

    def keyPressEvent(self, event):
        """ Calls delete() method of selected child widgets if multi-select is activated.
        """
        if self.multiSelectEnabled() and (event.key() == Qt.Key_Backspace
                                          or event.key() == Qt.Key_Delete):
            selection = self.selectedWidgets()[:]
            for widget in selection:
                widget.delete()

    def deselectAllWidgets(self, exception=None):
        """ Deselects all widgets except the widget given as exception.
        """
        #logging.debug(self.__class__.__name__ +": deselectAllWidgets()")
        self._selectedWidgets = []
        for child in self.children():
            if child != exception:
                if hasattr(child, 'select'):
                    child.select(False)
            else:
                self._selectedWidgets.append(child)

            if isinstance(child, VispaWidgetOwner):
                child.deselectAllWidgets(exception)
        self.update()

    def mousePressEvent(self, event):
        """ Calls deselectAllWidgets.
        """
        multiSelectEnabled = self.multiSelectEnabled()
        if event.modifiers() != Qt.ControlModifier:
            self.deselectAllWidgets()
        if multiSelectEnabled:
            self._selectionRectStartPos = QPoint(event.pos())
            self._selectionRect = None

    def mouseMoveEvent(self, event):
        if self.multiSelectEnabled() and self._selectionRectStartPos and (
                event.pos() - self._selectionRectStartPos
        ).manhattanLength() >= QApplication.startDragDistance():
            eventX = event.pos().x()
            eventY = event.pos().y()
            startX = self._selectionRectStartPos.x()
            startY = self._selectionRectStartPos.y()
            oldRect = self._selectionRect
            self._selectionRect = QRect(min(startX, eventX),
                                        min(startY, eventY),
                                        abs(eventX - startX),
                                        abs(eventY - startY))
            if oldRect:
                self.update(
                    self._selectionRect.united(oldRect).adjusted(-5, -5, 5, 5))
            else:
                self.update(self._selectionRect)

            # dynamically update selection statur
            # currently bad performance (2010-07-07)
            # TODO: improve selection mechanism
#            for child in self.children():
#                if hasattr(child, "select") and hasattr(child, "isSelected"):
#                    child.select(self._selectionRect.contains(child.geometry()), True)    # select, mulitSelect

    def mouseReleaseEvent(self, event):
        if hasattr(self, "_selectionRect"
                   ) and self._selectionRect and self.multiSelectEnabled():
            for child in self.children():
                if hasattr(child, "select") and hasattr(
                        child, "isSelected") and self._selectionRect.contains(
                            child.geometry()) and not child.isSelected():
                    child.select(True, True)  # select, mulitSelect
            self.update(self._selectionRect.adjusted(-5, -5, 5, 5))
        self._selectionRect = None
        self._selectionRectStartPos = None
Exemplo n.º 17
0
class LegendWidget(Ui_legendsWidget, QWidget):
    showmap = pyqtSignal()

    def __init__(self, parent=None):
        super(LegendWidget, self).__init__(parent)
        self.setupUi(self)
        self.canvasimage = QImage()
        self.items = {}
        self.framerect = QRect()
        self._lastextent = None

        self.legendareabrush = QBrush(QColor(255, 255, 255, 200))
        self.legendareapen = QPen(QColor(255, 255, 255, 20))
        self.legendareapen.setWidth(0.5)

    def paintEvent(self, event):
        def itemlist():
            for layer, items in self.items.iteritems():
                if len(items) == 1 and not layer.startswith("~"):
                    yield layer, items[0][1]
                else:
                    for text, icon in items:
                        if not text or text.startswith("~"):
                            continue
                        yield text, icon

        def _drawitem(pixmap, text, itempostion):
            painter.drawPixmap(itempostion, pixmap)
            textrect = QRectF(pixmap.width() + currentx + 10, itempostion.y(),
                              event.rect().width() - pixmap.width() - OFFSET_X,
                              pixmap.height())
            painter.drawText(textrect, text, QTextOption(Qt.AlignVCenter))

        def calcitems():
            font = painter.font()
            metrices = QFontMetrics(font)
            maxwidth = 0
            maxheight = 0
            for item, _ in itemlist():
                maxwidth = max(metrices.boundingRect(item).width(), maxwidth)
                maxheight = max(
                    metrices.boundingRect(item).height(), maxheight)
            return maxwidth, maxheight

        if not self.canvasimage:
            return

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)
        painter.drawImage(event.rect(), self.canvasimage)

        itemwidths, itemmaxheight = calcitems()
        OFFSET_X = 30
        OFFSET_Y = itemmaxheight + 10
        rect = event.rect()
        neededheight = (len(self.items) * OFFSET_Y)
        columns = 1
        if neededheight > rect.height():
            columns = math.ceil(neededheight / float(rect.height()))

        framerect = QRect(rect)
        framewidth = (itemwidths + OFFSET_X + ICON_SIZE.width() +
                      100) * columns
        framerect.setWidth(framewidth)
        painter.setBrush(self.legendareabrush)
        painter.setPen(self.legendareapen)
        painter.drawRect(framerect)
        self.framerect = framerect

        painter.setPen(Qt.black)
        currenty = OFFSET_Y
        currentx = OFFSET_X
        position = rect.topLeft() + QPoint(OFFSET_X, currenty)
        for text, icon in itemlist():
            itempostion = QPoint(position)
            if currenty > rect.height():
                currentx = itemwidths + OFFSET_X + 100
                currenty = itemmaxheight + 10

            itempostion.setX(currentx)
            itempostion.setY(currenty)

            _drawitem(icon, text, itempostion)
            currenty += OFFSET_Y

        position.setY(currenty + OFFSET_Y)

    def mousePressEvent(self, event):
        if self.framerect.contains(event.pos()):
            return

        self.showmap.emit()

    def updateitems(self, layers):
        self.items = {}
        for layer in layers:
            if not layer.type() == QgsMapLayer.VectorLayer:
                continue

            try:
                items = layer.rendererV2().legendSymbologyItems(ICON_SIZE)
            except AttributeError:
                continue
            self.items[layer.name()] = items
        self.update()

    def _renderimage(self):
        image = self.renderjob.renderedImage()
        self.canvasimage = image
        self.update()

    def updatecanvas(self, canvas):
        """
        Update the canvas object for the legend background.
        """
        if self._lastextent == canvas.extent():
            return

        self._lastextent = canvas.extent()
        if QGis.QGIS_VERSION_INT > 20200:
            from qgis.core import QgsMapRendererParallelJob, QgsMapSettings
            settings = canvas.mapSettings()
            extent = settings.extent()
            settings.setOutputSize(self.size())
            settings.setExtent(extent)
            #settings.setFlags(QgsMapSettings.Antialiasing | QgsMapSettings.DrawLabeling )
            self.renderjob = QgsMapRendererParallelJob(settings)
            self.renderjob.finished.connect(self._renderimage)
            self.renderjob.start()
        else:
            if canvas.isDrawing():
                return

            pixmap = QPixmap(self.size())
            pixmap.fill(canvas.canvasColor())
            painter = QPainter(pixmap)
            painter.setRenderHints(QPainter.Antialiasing)
            renderer = canvas.mapRenderer()
            renderer.render(painter)
            del painter
            self.canvasimage = pixmap.toImage()
            self.update()
Exemplo n.º 18
0
class WebSystrayView(WebDialog):
    DEFAULT_WIDTH = 300
    DEFAULT_HEIGHT = 370
    '''
    classdocs
    '''
    def __init__(self, application, icon):
        '''
        Constructor
        '''
        super(WebSystrayView,
              self).__init__(application,
                             "systray.html",
                             api=WebSystrayApi(application, self))
        self._icon = icon
        self._icon_geometry = None
        self._view.setFocusProxy(self)
        self.resize(WebSystrayView.DEFAULT_WIDTH,
                    WebSystrayView.DEFAULT_HEIGHT)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint
                            | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.Popup
                            | QtCore.Qt.Dialog)

    def replace(self):
        log.trace("Icon is %r", self._icon)
        self._icon_geometry = rect = self._icon.geometry()
        log.trace("IconRect is : %s,%s | %s,%s", rect.x(), rect.y(),
                  rect.width(), rect.height())
        from PyQt4.QtGui import QApplication, QCursor
        from PyQt4.QtCore import QRect
        desktop = QApplication.desktop()
        log.trace("Screen id is %d", desktop.screenNumber(rect.topLeft()))
        desk = desktop.screenGeometry(desktop.screenNumber(rect.topLeft()))
        log.trace("ScreenRect is : %s,%s | %s,%s", desk.x(), desk.y(),
                  desk.width(), desk.height())
        pos = QCursor.pos()
        log.trace("Cursor is : %s,%s", pos.x(), pos.y())
        # Make our calculation on a offset screen to 0/0
        rect = QRect(rect.x() - desk.x(),
                     rect.y() - desk.y(), rect.width(), rect.height())
        pos.setX(pos.x() - desk.x())
        pos.setY(pos.y() - desk.y())
        if not rect.contains(pos) or (rect.x() == 0 and rect.y() == 0):
            # Avoid any modulo 0
            if rect.width() == 0 or rect.height() == 0:
                rect = QRect(pos.x(), pos.y(), rect.width(), rect.height())
            else:
                rect = QRect(pos.x() - pos.x() % rect.width(),
                             pos.y() - pos.y() % rect.height(), rect.width(),
                             rect.height())
            log.trace("Adjusting X/Y to %d/%d", rect.x(), rect.y())
            pos = rect
            self._icon_geometry = QRect(rect.x() + desk.x(),
                                        rect.y() + desk.y(), rect.width(),
                                        rect.height())
            log.trace("New rect is : %s,%s | %s,%s", pos.x(), pos.y(),
                      pos.width(), pos.height())
        x = rect.x() + rect.width() - self.width()
        y = rect.y() - self.height()
        # Prevent the systray to be hidden
        if y < 0:
            y = rect.y() + rect.height()
        if x < 0:
            x = rect.x()
        # Use the offset again
        x += desk.x()
        y += desk.y()
        log.trace("Move systray menu to %d/%d", x, y)
        self.move(x, y)

    def show(self):
        self.replace()
        super(WebSystrayView, self).show()
        if self.isVisible():
            self.raise_()
            self.activateWindow()
            self.setFocus(QtCore.Qt.ActiveWindowFocusReason)

    def underMouse(self):
        # The original result was different from this simple
        return self.geometry().contains(QtGui.QCursor.pos())

    def shouldHide(self):
        log.trace("Geometry: %r", self.geometry())
        log.trace("Cursor is: %r", QtGui.QCursor.pos())
        log.trace("Icon: %r", self._icon)
        log.trace("Icon geometry: %r", self._icon_geometry)
        if not (self.underMouse() or
                (self._icon
                 and self._icon.geometry().contains(QtGui.QCursor.pos())) or
                (self._icon_geometry
                 and self._icon_geometry.contains(QtGui.QCursor.pos()))):
            log.trace('will close menu')
            self.close()

    def focusOutEvent(self, event):
        if not (self.underMouse() or
                (self._icon
                 and self._icon.geometry().contains(QtGui.QCursor.pos())) or
                (self._icon_geometry
                 and self._icon_geometry.contains(QtGui.QCursor.pos()))):
            self.close()
        super(WebSystrayView, self).focusOutEvent(event)

    def resizeEvent(self, event):
        super(WebSystrayView, self).resizeEvent(event)
        self.replace()

    @QtCore.pyqtSlot()
    def close(self):
        self._icon = None
        try:
            super(WebSystrayView, self).close()
        except RuntimeError:
            # This exception can happen here
            # wrapped C/C++ object of type WebSystrayView has been deleted
            pass
Exemplo n.º 19
0
class WebSystrayView(WebDialog):
    DEFAULT_WIDTH = 300
    DEFAULT_HEIGHT = 370
    '''
    classdocs
    '''
    def __init__(self, application, icon):
        '''
        Constructor
        '''
        super(WebSystrayView, self).__init__(application, "systray.html", api=WebSystrayApi(application, self))
        self._icon = icon
        self._icon_geometry = None
        self._view.setFocusProxy(self)
        self.resize(WebSystrayView.DEFAULT_WIDTH, WebSystrayView.DEFAULT_HEIGHT)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.Popup | QtCore.Qt.Dialog);

    def replace(self):
        log.trace("Icon is %r", self._icon)
        self._icon_geometry = rect = self._icon.geometry()
        log.trace("IconRect is : %s,%s | %s,%s",rect.x(), rect.y(), rect.width(), rect.height())
        from PyQt4.QtGui import QApplication, QCursor
        from PyQt4.QtCore import QRect
        desktop = QApplication.desktop()
        log.trace("Screen id is %d", desktop.screenNumber(rect.topLeft()))
        desk = desktop.screenGeometry(desktop.screenNumber(rect.topLeft()))
        log.trace("ScreenRect is : %s,%s | %s,%s",desk.x(), desk.y(), desk.width(), desk.height())
        pos = QCursor.pos()
        log.trace("Cursor is : %s,%s",pos.x(), pos.y())
        # Make our calculation on a offset screen to 0/0
        rect = QRect(rect.x()-desk.x(), rect.y()-desk.y(), rect.width(), rect.height())
        pos.setX(pos.x()-desk.x())
        pos.setY(pos.y()-desk.y())
        if not rect.contains(pos) or (rect.x() == 0 and rect.y() == 0):
            # Avoid any modulo 0
            if rect.width() == 0 or rect.height() == 0:
                rect = QRect(pos.x(), pos.y(), rect.width(), rect.height())
            else:
                rect = QRect(pos.x()-pos.x()%rect.width(), pos.y()-pos.y()%rect.height(), rect.width(), rect.height())
            log.trace("Adjusting X/Y to %d/%d", rect.x(), rect.y())
            pos = rect
            self._icon_geometry = QRect(rect.x()+desk.x(), rect.y()+desk.y(), rect.width(), rect.height())
            log.trace("New rect is : %s,%s | %s,%s",pos.x(), pos.y(), pos.width(), pos.height())
        x = rect.x() + rect.width() - self.width()
        y = rect.y() - self.height()
        # Prevent the systray to be hidden
        if y < 0:
            y = rect.y() + rect.height()
        if x < 0:
            x = rect.x()
        # Use the offset again
        x += desk.x()
        y += desk.y()
        log.trace("Move systray menu to %d/%d", x, y)
        self.move(x, y)

    def show(self):
        self.replace()
        super(WebSystrayView, self).show()
        if self.isVisible():
            self.raise_()
            self.activateWindow()
            self.setFocus(QtCore.Qt.ActiveWindowFocusReason)

    def underMouse(self):
        # The original result was different from this simple
        return self.geometry().contains(QtGui.QCursor.pos())

    def shouldHide(self):
        log.trace("Geometry: %r", self.geometry())
        log.trace("Cursor is: %r", QtGui.QCursor.pos())
        log.trace("Icon: %r", self._icon)
        log.trace("Icon geometry: %r", self._icon_geometry)
        if not (self.underMouse() or (self._icon and self._icon.geometry().contains(QtGui.QCursor.pos()))
                or (self._icon_geometry and self._icon_geometry.contains(QtGui.QCursor.pos()))):
            log.trace('will close menu')
            self.close()

    def focusOutEvent(self, event):
        if not (self.underMouse() or (self._icon and self._icon.geometry().contains(QtGui.QCursor.pos()))
                or (self._icon_geometry and self._icon_geometry.contains(QtGui.QCursor.pos()))):
            self.close()
        super(WebSystrayView, self).focusOutEvent(event)

    def resizeEvent(self, event):
        super(WebSystrayView, self).resizeEvent(event)
        self.replace()

    @QtCore.pyqtSlot()
    def close(self):
        self._icon = None
        try:
            super(WebSystrayView, self).close()
        except RuntimeError:
            # This exception can happen here
            # wrapped C/C++ object of type WebSystrayView has been deleted
            pass
Exemplo n.º 20
0
class LegendWidget(legend_widget, QWidget):
    showmap = pyqtSignal()

    def __init__(self, parent=None):
        super(LegendWidget, self).__init__(parent)
        self.setupUi(self)
        self.pixmap = QPixmap()
        self.items = {}
        self.framerect = QRect()
        self._lastextent = None

        self.legendareabrush = QBrush(QColor(255,255,255,200))
        self.legendareapen = QPen(QColor(255,255,255,20))
        self.legendareapen.setWidth(0.5)

    def paintEvent(self, event):
        def _drawitem(pixmap, text, itempostion):
            painter.drawPixmap(itempostion, pixmap)
            textrect = QRectF(pixmap.width() + 40,
                              itempostion.y(),
                              framerect.width() - pixmap.width() - 40,
                              pixmap.height())
            painter.drawText(textrect, text, QTextOption(Qt.AlignVCenter))

        if not self.pixmap:
            return

        painter = QPainter(self)
        painter.setRenderHints(QPainter.Antialiasing)
        painter.drawPixmap(event.rect(), self.pixmap)

        rect = event.rect()
        framerect = QRect(rect)
        newwidth = (rect.width() / 100) * 40
        framerect.setWidth(newwidth)
        painter.setBrush(self.legendareabrush)
        painter.setPen(self.legendareapen)
        painter.drawRect(framerect)
        self.framerect = framerect

        painter.setPen(Qt.black)

        currenty = 40
        position = rect.topLeft() + QPoint(30, currenty)
        for layer, items in self.items.iteritems():
            if len(items) == 1:
                itempostion = QPoint(position)
                itempostion.setY(currenty)
                _drawitem(items[0][1], layer, itempostion)
                currenty += 40
            else:
                for text, icon in items:
                    if not text:
                        continue
                    itempostion = QPoint(position)
                    itempostion.setY(currenty)
                    _drawitem(icon, text, itempostion)
                    currenty += 40

            position.setY(currenty + 40)

    def mousePressEvent(self, event):
        if self.framerect.contains(event.pos()):
            return

        self.showmap.emit()


    def updateitems(self, layers):
        self.items = {}
        for layer in layers:
            if not layer.type() == QgsMapLayer.VectorLayer:
                continue

            try:
                items = layer.rendererV2().legendSymbologyItems(QSize(32, 32))
            except AttributeError:
                continue
            self.items[layer.name()] = items
        self.update()

    def updatecanvas(self, canvas):
        """
        Update the canvas object for the legend background.
        """
        if canvas.isDrawing() or self._lastextent == canvas.extent():
            return

        self._lastextent = canvas.extent()
        pixmap = QPixmap(self.size())
        pixmap.fill(canvas.canvasColor())
        painter = QPainter(pixmap)
        painter.setRenderHints(QPainter.Antialiasing)
        renderer = canvas.mapRenderer()
        renderer.render(painter)
        del painter
        self.pixmap = pixmap
        self.update()
Exemplo n.º 21
0
class ScheduleVisualizer(QWidget):

    time = 50
    proc = 20
    scale = 1.5

    schedule = None
    method = None
    vertices = {}
    positions = {}
    procrects = {}

    colors = {
        "axis": QColor(255, 255, 255),
        "task": QColor(255, 255, 0),
        "delivery": QColor(100, 0, 255),
        "select": QColor(255, 0, 0)
    }

    selectedTask = None
    addrect = None
    delrect = None
    targetPos = None
    pressed = False

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setGeometry(0, 0, (70 + self.time * 10) * self.scale,
                         (40 + self.proc * 20) * self.scale)
        self.setSizePolicy(QtGui.QSizePolicy.Expanding,
                           QtGui.QSizePolicy.Expanding)
        try:
            _fromUtf8 = QtCore.QString.fromUtf8
        except AttributeError:
            _fromUtf8 = lambda s: s
        self.procicon = QImage(_fromUtf8(":/pics/pics/processor.png"))
        self.addicon = QImage(_fromUtf8(":/pics/pics/add.png"))
        self.delicon = QImage(_fromUtf8(":/pics/pics/meenoos.png"))

    def paintEvent(self, event):
        if self.schedule:
            paint = QPainter()
            paint.begin(self)
            paint.setPen(self.colors["axis"])
            paint.setFont(QtGui.QFont('Decorative', 9 * self.scale))
            procX = {}

            # Draw processor names and axis
            for i in range(self.proc):
                paint.drawImage(
                    QRect(15 * self.scale, (10 + i * 20) * self.scale,
                          24 * self.scale, 24 * self.scale), self.procicon)
                paint.drawText(40 * self.scale, (25 + i * 20) * self.scale,
                               str(self.schedule.processors[i].reserves))
                plus = QRect(5 * self.scale, (10 + i * 20) * self.scale,
                             10 * self.scale, 10 * self.scale)
                paint.drawImage(plus, self.addicon)
                meenoos = QRect(5 * self.scale, (20 + i * 20) * self.scale,
                                10 * self.scale, 10 * self.scale)
                paint.drawImage(meenoos, self.delicon)
                self.procrects[self.schedule.processors[i]] = [plus, meenoos]
                paint.drawLine(50 * self.scale, (20 + i * 20) * self.scale,
                               (50 + self.time * 10) * self.scale,
                               (20 + i * 20) * self.scale)
                procX[self.schedule.processors[i].number] = 20 + i * 20

            # Draw timeline
            tdir = self.method.system.tdir
            paint.drawLine(50 * self.scale,
                           self.height() - 15, (50 + tdir * 10) * self.scale,
                           self.height() - 15)
            paint.drawLine(50 * self.scale, 10 * self.scale, 50 * self.scale,
                           self.height() - 10)
            t = 0
            paint.setFont(QtGui.QFont('Decorative', 8))
            while t < tdir + 10:
                paint.drawLine((50 + t * 10) * self.scale,
                               self.height() - 20, (50 + t * 10) * self.scale,
                               self.height() - 10)
                paint.drawText((50 + t * 10 + 1) * self.scale,
                               self.height() - 5, str(t))
                t += 10

            paint.setPen(self.colors["select"])
            paint.drawLine((50 + tdir * 10) * self.scale, 10 * self.scale,
                           (50 + tdir * 10) * self.scale,
                           self.height() - 10)
            if self.selectedTask:
                t = self.selectedTask
                start = self.method.interpreter.executionTimes[t][0]
                finish = self.method.interpreter.executionTimes[t][1]
                paint.drawText((50 + start * 10) * self.scale,
                               self.height() - 16, str(start))
                paint.drawText((50 + finish * 10) * self.scale,
                               self.height() - 16, str(finish))

            # Draw tasks
            paint.setPen(self.colors["task"])
            paint.setFont(QtGui.QFont('Decorative', 9 * self.scale))
            self.vertices = {}
            self.positions = {}
            for m in self.schedule.vertices.keys():
                i = 0
                prev = None
                for t in self.schedule.vertices[m]:
                    start = self.method.interpreter.executionTimes[t][0]
                    finish = self.method.interpreter.executionTimes[t][1]
                    task = QtCore.QRect((50 + start * 10) * self.scale,
                                        (procX[t.m.number] - 5) * self.scale,
                                        (finish - start) * 10 * self.scale,
                                        10 * self.scale)
                    # TODO: calculate once!
                    self.vertices[t] = task
                    if i == 0:
                        self.positions[(m, i)] = QtCore.QRect(
                            QPoint(50 * self.scale, task.y()),
                            task.bottomLeft())
                    else:
                        self.positions[(m, i)] = QtCore.QRect(
                            prev.topRight(), task.bottomLeft())
                    if t != self.selectedTask:
                        paint.fillRect(task, self.colors["task"])
                    else:
                        paint.fillRect(task, self.colors["select"])
                        if self.schedule.CanAddVersions(t):
                            self.addrect = QRect(task.topLeft().x(),
                                                 task.topLeft().y(),
                                                 10 * self.scale,
                                                 10 * self.scale)
                            paint.drawImage(self.addrect, self.addicon)
                        if self.schedule.CanDeleteVersions(t):
                            self.delrect = QRect(
                                task.topRight().x() - 10 * self.scale,
                                task.topRight().y(), 10 * self.scale,
                                10 * self.scale)
                            paint.drawImage(self.delrect, self.delicon)
                    paint.setPen(self.colors["axis"])
                    paint.drawRect(task)
                    paint.setPen(self.colors["task"])
                    prev = task
                    i += 1
                self.positions[(m, i)] = QtCore.QRect(
                    prev.topRight(),
                    QPoint(prev.topRight().x() + 100,
                           prev.bottomRight().y()))

            if self.targetPos:
                width = min(self.selectedTask.v.time * 10 * self.scale,
                            self.positions[self.targetPos].width())
                rect = QtCore.QRect(self.positions[self.targetPos])
                rect.setWidth(width)
                paint.fillRect(rect, self.colors["select"])

            # Draw deliveries
            paint.setPen(QPen(self.colors["delivery"], 2))
            for d in self.method.interpreter.deliveryTimes:
                self.drawArrow(paint, (50 + d[2] * 10) * self.scale,
                               procX[d[0].number] * self.scale,
                               (50 + d[3] * 10) * self.scale,
                               procX[d[1].number] * self.scale)

            # Draw captions
            paint.setPen(self.colors["axis"])
            for m in self.schedule.vertices.keys():
                for t in self.schedule.vertices[m]:
                    start = self.method.interpreter.executionTimes[t][0]
                    finish = self.method.interpreter.executionTimes[t][1]
                    s = str(t.v.number)
                    if t.k.number > 1:
                        s += " v" + str(t.k.number)
                    paint.drawText((10 + finish + start - int(len(s) / 2)) *
                                   5 * self.scale,
                                   (procX[t.m.number] + 5) * self.scale, s)

            paint.end()

    def mousePressEvent(self, e):
        def update():
            self.proc = self.schedule.GetProcessorsWithoutDoubles()
            self.time = self.schedule.Interpret()
            self.targetPos = None
            self.pressed = False
            self.selectedTask = None
            self.addrect = None
            self.delrect = None
            self.emit(SIGNAL("ManualOperation"))
            self.ResizeCanvas()
            self.repaint()
            return

        if self.selectedTask:
            if self.addrect:
                if self.addrect.contains(e.pos()):
                    self.method.ManualStep("AddVersion", v=self.selectedTask.v)
                    update()
                    return
            if self.delrect:
                if self.delrect.contains(e.pos()):
                    self.method.ManualStep("DeleteVersion",
                                           v=self.selectedTask.v)
                    update()
                    return

        for p in self.procrects.keys():
            if self.procrects[p][0].contains(e.pos()):
                self.method.ManualStep("AddProcessor", m=p)
                update()
                return
            if self.procrects[p][1].contains(e.pos()):
                self.method.ManualStep("DeleteProcessor", m=p)
                update()
                return

        for v in self.vertices.keys():
            if self.vertices[v].contains(e.pos()):
                self.selectedTask = v
                self.repaint()
                self.pressed = True
                return
        self.selectedTask = None
        self.addrect = None
        self.delrect = None
        self.repaint()

    def mouseMoveEvent(self, e):
        if self.pressed:
            for p in self.positions.keys():
                if self.positions[p].contains(e.pos()):
                    self.targetPos = p
                    self.repaint()
                    return
            self.targetPos = None
            self.repaint()

    def mouseReleaseEvent(self, e):
        if self.pressed and self.targetPos:
            result = self.method.ManualStep(
                "MoveVertex",
                v=self.selectedTask,
                n1=self.schedule.vertices[self.selectedTask.m].index(
                    self.selectedTask),
                m2=self.schedule.GetProcessor(self.targetPos[0]),
                n2=self.targetPos[1])
            if result == True:
                self.proc = self.schedule.GetProcessorsWithoutDoubles()
                self.time = self.method.interpreter.Interpret(self.schedule)
                self.emit(SIGNAL("ManualOperation"))
            else:
                self.emit(SIGNAL("WrongOperation"), result)
            self.targetPos = None
            self.pressed = False
            self.selectedTask = None
            self.addrect = None
            self.delrect = None
            self.ResizeCanvas()
            self.repaint()
            return
        self.pressed = False
        self.targetPos = None
        self.repaint()

    def drawArrow(self, paint, x1, y1, x2, y2):
        m = paint.worldMatrix()
        paint.translate(x1, y1)
        pi = 3.1415926
        alpha = math.atan(abs(y2 - y1) / abs(x2 - x1)) * 180 / pi
        if y2 > y1:
            if x2 > x1:
                paint.rotate(alpha)
            else:
                paint.rotate(180 - alpha)
        else:
            if x2 > x1:
                paint.rotate(-alpha)
            else:
                paint.rotate(alpha - 180)
        endcoord = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        p1 = QPointF(endcoord, 0)
        paint.drawLine(0, 0, p1.x(), 0)

        coord = math.sqrt(12**2 - 6**2)
        p2 = QPointF(endcoord - coord, 6)
        p3 = QPointF(endcoord - coord, -6)
        path = QPainterPath()
        path.moveTo(p1)
        path.lineTo(p2)
        path.lineTo(p3)
        path.lineTo(p1)
        paint.fillPath(path, paint.pen().color())
        paint.setWorldMatrix(m)

    def SetScale(self, d):
        self.scale = d
        self.ResizeCanvas()
        self.repaint()

    def Visualize(self, m):
        self.schedule = m.system.schedule
        self.method = m
        # TODO: get rid of this
        self.proc = self.schedule.GetProcessorsWithoutDoubles()
        self.time = self.method.interpreter.Interpret(self.schedule)
        self.ResizeCanvas()
        self.repaint()

    def ResizeCanvas(self):
        self.setGeometry(
            0, 0,
            max(int((70 + self.time * 10) * self.scale),
                self.parent().width()),
            max(int((40 + self.proc * 20) * self.scale),
                self.parent().height()))
Exemplo n.º 22
0
class VispaWidgetOwner(object):
    """ Interface for classes containing VispaWidgets
    
    Only makes sense if implementing class also inherits QWidget or class inheriting QWidget.
    """
    
    def enableMultiSelect(self, multiSelect=True):
        self._multiSelectEnabledFlag = multiSelect
        
    def multiSelectEnabled(self):
        return hasattr(self, "_multiSelectEnabledFlag") and self._multiSelectEnabledFlag
    
    def selectedWidgets(self):
        """ Returns a list of all selected widgets.
        """
        if hasattr(self, "_selectedWidgets"):
            return self._selectedWidgets
        return [child for child in self.children() if hasattr(child, "isSelected") and child.isSelected()]
    
    def widgetSelected(self, widget, multiSelect=False):
        """ Forward selection information to super class if it is a VispaWidgetOwner.
        """
        logging.debug(self.__class__.__name__ +": widgetSelected()")

        if isinstance(self, QObject):
            if not hasattr(self, "_selectedWidgets"):
                self._selectedWidgets = []
                
            if  not multiSelect or not self.multiSelectEnabled():
                self.deselectAllWidgets(widget)
                self._selectedWidgets = []
                
            if widget.parent() == self and not widget in self._selectedWidgets:
                self._selectedWidgets.append(widget)
                
            for widget in [child for child in self._selectedWidgets if hasattr(child, "isSelected") and not child.isSelected()]:
                self._selectedWidgets.remove(widget)
                
            if isinstance(self.parent(), VispaWidgetOwner):
                self.parent().widgetSelected(widget)
            
    def widgetDoubleClicked(self, widget):
        """ Forward selection information to super class if it is a VispaWidgetOwner.
        """
        #logging.debug(self.__class__.__name__ +": widgetDoubleClicked()")
        if isinstance(self, QObject):
            if isinstance(self.parent(), VispaWidgetOwner):
                self.parent().widgetDoubleClicked(widget)
                
    def initWidgetMovement(self, widget):
        self._lastMovedWidgets = []
        if self.multiSelectEnabled():
            pos = widget.pos()
            for child in self.children():
                if child != widget and hasattr(child, "isSelected") and child.isSelected():
                    child.setDragReferencePoint(pos - child.pos())
            
    def widgetDragged(self, widget):
        """ Tell parent widget has moved.
        
        Only informs parent if it is a VispaWidgetOwner, too.
        """
        if isinstance(self.parent(), VispaWidgetOwner):
            self.parent().widgetDragged(widget)

        if hasattr(self, "_lastMovedWidgets"):
            self._lastMovedWidgets.append(widget)
            
        if self.multiSelectEnabled():
            for child in self.children():
                if hasattr(child, "dragReferencePoint") and child != widget and hasattr(child, "isSelected") and child.isSelected():
                    if hasattr(child, "setPreviousDragPosition"):
                        child.setPreviousDragPosition(child.pos())
                    child.move(widget.pos() - child.dragReferencePoint())
                    self._lastMovedWidgets.append(child)

# apparently unused feature (2010-07-02), remove if really unnecessary
# also see self._lastMovedWidget definition above
    def lastMovedWidgets(self):
        if hasattr(self, "_lastMovedWidgets"):
            return self._lastMovedWidgets
        return None

    def widgetAboutToDelete(self, widget):
        """ This function is called from the delete() function of VispaWidget.
        """
        pass
        
    def keyPressEvent(self, event):
        """ Calls delete() method of selected child widgets if multi-select is activated.
        """
        if self.multiSelectEnabled() and ( event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete ):
            selection = self.selectedWidgets()[:]
            for widget in selection:
                widget.delete()
    
    def deselectAllWidgets(self, exception=None):
        """ Deselects all widgets except the widget given as exception.
        """
        #logging.debug(self.__class__.__name__ +": deselectAllWidgets()")
        self._selectedWidgets = []
        for child in self.children():
            if child != exception:
                if hasattr(child, 'select'):
                    child.select(False)
            else:
                self._selectedWidgets.append(child)
                
            if isinstance(child, VispaWidgetOwner):
                child.deselectAllWidgets(exception)
        self.update()
        
    def mousePressEvent(self, event):
        """ Calls deselectAllWidgets.
        """
        multiSelectEnabled = self.multiSelectEnabled()
        if event.modifiers() != Qt.ControlModifier:
            self.deselectAllWidgets()
        if multiSelectEnabled:
            self._selectionRectStartPos = QPoint(event.pos())
            self._selectionRect = None

    def mouseMoveEvent(self, event):
        if self.multiSelectEnabled() and self._selectionRectStartPos and (event.pos() - self._selectionRectStartPos).manhattanLength() >= QApplication.startDragDistance():
            eventX = event.pos().x()
            eventY = event.pos().y()
            startX = self._selectionRectStartPos.x()
            startY = self._selectionRectStartPos.y()
            oldRect = self._selectionRect
            self._selectionRect = QRect(min(startX, eventX), min(startY, eventY), abs(eventX - startX), abs(eventY - startY))
            if oldRect:
                self.update(self._selectionRect.united(oldRect).adjusted(-5, -5, 5, 5))
            else:
                self.update(self._selectionRect)
                
            # dynamically update selection statur
            # currently bad performance (2010-07-07)
            # TODO: improve selection mechanism
#            for child in self.children():
#                if hasattr(child, "select") and hasattr(child, "isSelected"):
#                    child.select(self._selectionRect.contains(child.geometry()), True)    # select, mulitSelect 
                
    def mouseReleaseEvent(self, event):
        if hasattr(self, "_selectionRect") and  self._selectionRect and self.multiSelectEnabled():
            for child in self.children():
                if hasattr(child, "select") and hasattr(child, "isSelected") and self._selectionRect.contains(child.geometry()) and not child.isSelected():
                    child.select(True, True)    # select, mulitSelect 
            self.update(self._selectionRect.adjusted(-5, -5, 5, 5))
        self._selectionRect = None
        self._selectionRectStartPos = None
        
Exemplo n.º 23
0
    def mouseMoveEvent(self, event):
        if self._interaction.moving:
            mouse_position = event.globalPos()
            offset = mouse_position - self._interaction.mouse_last_position
            if self.parent() is not None:
                parent_rect = self.parent().rect()
                old_geometry = self.geometry()
                new_geometry = old_geometry.translated(offset)
                if new_geometry.left() < 0:
                    new_geometry.moveLeft(0)
                if new_geometry.top() < 0:
                    new_geometry.moveTop(0)
                if new_geometry.right() > parent_rect.right():
                    new_geometry.moveRight(parent_rect.right())
                if new_geometry.bottom() > parent_rect.bottom():
                    new_geometry.moveBottom(parent_rect.bottom())
                offset = new_geometry.topLeft() - old_geometry.topLeft()
            self.move(self.pos() + offset)
            self._interaction.mouse_last_position += offset
        elif self._interaction.resizing:
            mouse_position = event.globalPos()
            delta_y = mouse_position.y(
            ) - self._interaction.mouse_last_position.y()
            geometry = self.geometry()

            if self._interaction.resize_corner is self.TopLeftCorner:
                delta_x = -(self.width_for_height(geometry.height() - delta_y)
                            - geometry.width())
                geometry.setTopLeft(geometry.topLeft() +
                                    QPoint(delta_x, delta_y))
            elif self._interaction.resize_corner is self.TopRightCorner:
                delta_x = (self.width_for_height(geometry.height() - delta_y) -
                           geometry.width())
                geometry.setTopRight(geometry.topRight() +
                                     QPoint(delta_x, delta_y))
            elif self._interaction.resize_corner is self.BottomLeftCorner:
                delta_x = -(self.width_for_height(geometry.height() + delta_y)
                            - geometry.width())
                geometry.setBottomLeft(geometry.bottomLeft() +
                                       QPoint(delta_x, delta_y))
            else:
                delta_x = (self.width_for_height(geometry.height() + delta_y) -
                           geometry.width())
                geometry.setBottomRight(geometry.bottomRight() +
                                        QPoint(delta_x, delta_y))

            if self.minimumHeight() <= geometry.height() <= self.maximumHeight(
            ) and (self.parent() is None
                   or self.parent().rect().contains(geometry)):
                self.setGeometry(geometry)
                self._interaction.mouse_last_position = mouse_position
        elif self.interactive:
            mouse_position = event.pos()
            topbar_rect = QRect(0, 0, self.width(), 10)

            if self.rect().adjusted(0, 10, 0, -10).contains(mouse_position):
                self.setCursor(Qt.ArrowCursor)
            elif topbar_rect.contains(mouse_position):
                self.setCursor(self.cursors.resize_top)
            else:
                self.setCursor(self.cursors.resize_bottom)