Exemple #1
0
class PostViewWidget(HorsePanel):
    def __init__(self, parent, order_overview_widget, find_order_slot):
        global configuration

        super(PostViewWidget, self).__init__(parent)

        self.set_panel_title(_("Post overview"))
        self.bold_font = QFont(self.font())
        self.bold_font.setBold(True)
        self.nb_cols = 8  # Number of columns in the operation definition table

        self.order_overview_widget = order_overview_widget

        self.button = QPushButton(_("Refresh"), self)
        self.button.clicked.connect(self.refresh_action)
        self.sort_by_deadline_button = QRadioButton(_("By deadline"), self)
        self.sort_by_deadline_button.toggled.connect(self.sort_by_deadline)
        self.sort_by_size_button = QRadioButton(_("By hours left to do"), self)
        self.sort_by_size_button.toggled.connect(self.sort_by_size)

        # hlayout = QHBoxLayout()
        # hlayout.setObjectName("halyout")
        # hlayout.setContentsMargins(0,0,0,0)
        # hlayout.addWidget(self.sort_by_deadline_button)
        # hlayout.addWidget(self.sort_by_size_button)
        # hlayout.addWidget(self.button)
        # hlayout.addStretch()

        self.navbar = NavBar(self, [(self.sort_by_deadline_button, None),
                                    (self.sort_by_size_button, None),
                                    (self.button, None),
                                    (_("Find"), find_order_slot)])
        self.navbar.buttons[3].setObjectName("specialMenuButton")

        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(
            TitleWidget(_("Posts Overview"), self, self.navbar))

        self._table_model = QStandardItemModel(1, self.nb_cols, self)
        self.table_view = QTableView(None)
        self.table_view.setModel(self._table_model)
        self.table_view.selectionModel().currentChanged.connect(
            self.operation_selected)

        self.table_view.verticalHeader().hide()
        self.table_view.horizontalHeader().hide()
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        # This forces Qt to expand layout once I fill data in
        # FIXME dirty but I really don't get why setting
        # the mini width to something smaller (that happens at
        # startup, on first refresh) doesn't work
        self.table_view.setMinimumWidth(1)
        self.table_view.setMaximumWidth(1)

        self.post_view_scene = PostViewScene(self, order_overview_widget)
        self.post_view_scene_view = QGraphicsView(self)
        self.post_view_scene_view.setScene(self.post_view_scene)
        self.post_view_scene_view.setSizePolicy(QSizePolicy.Expanding,
                                                QSizePolicy.Expanding)

        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(
            SubFrame(_("Posts"), self.table_view, self.splitter))
        self.splitter.addWidget(
            SubFrame(_("Workload"), self.post_view_scene_view, self.splitter))
        # self.splitter.setStretchFactor(0,1)
        self.splitter.setStretchFactor(1, 1)
        self.vlayout.addWidget(self.splitter)

        # hlayout = QHBoxLayout()
        # hlayout.addWidget(SubFrame(_("Posts"),self.table_view,self))
        # hlayout.addWidget(SubFrame(_("Workload"),self.post_view_scene_view,self))
        # hlayout.setStretch(1,1)
        # self.vlayout.addLayout(hlayout)

        self.vlayout.setStretch(0, 0)
        self.vlayout.setStretch(1, 1)

        self.setLayout(self.vlayout)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.slidePostsScene)

        self.current_view_y = 0

    def _data_load(self):
        global dao

        all_operations = dao.operation_dao.load_all_operations_ready_for_production(
        )
        operation_definitions = dao.operation_definition_dao.all_direct_frozen(
        )

        return operation_definitions, all_operations

    def _reset_operation_definitions(self, operations):
        self._table_model.setColumnCount(1)
        self._table_model.setRowCount(len(operations))

        # BUG This should be refreshed on reload() too

        row = col = 0
        first_active = None

        for opdef in operations:

            if opdef.operation_definition_id in self.post_view_scene.drawn_operations_data:
                # currently total planned time
                t = self.post_view_scene.drawn_operations_data[
                    opdef.operation_definition_id]
                ndx = self._table_model.index(row, col)
                if not first_active:
                    first_active = ndx
                self._table_model.setData(
                    ndx, u"{} {}".format(opdef.description, t), Qt.DisplayRole)
                # self._table_model.setData(ndx,self.bold_font,Qt.FontRole)

                self._table_model.setData(self._table_model.index(row, col),
                                          opdef.operation_definition_id,
                                          Qt.UserRole)
                row += 1

            else:
                pass
                # self._table_model.setData(self._table_model.index(row,col),opdef.description,Qt.DisplayRole)

            # = col + 1
            # if col == self.nb_cols:
            #     col = 0
            #     row += 1

        self._table_model.setRowCount(row)

        # self.table_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.vlayout.setStretch(0,0)
        # self.vlayout.setStretch(1,10)
        # self.vlayout.setStretch(2,10000)

        # height = 0
        # for c in range(self.table_view.model().rowCount()):
        #     height += self.table_view.rowHeight(c) + 1 # +1 for cell border
        # self.table_view.setMinimumHeight(height)
        # self.table_view.setMaximumHeight(height)
        for i in range(self.nb_cols):
            self.table_view.resizeColumnToContents(i)
        self.table_view.setMaximumWidth(self.table_view.columnWidth(0))
        self.table_view.setMinimumWidth(self.table_view.columnWidth(0))
        self.table_view.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Preferred)

        self.table_view.update()
        self.splitter.update()

        return first_active

    def slide_to_operation(self, opdef_id):
        if opdef_id in self.post_view_scene.posts_offsets:
            self.slide_target_opdef_id = opdef_id
            # mainlog.debug("Target y = {}".format(self.post_view_scene.posts_offsets[self.slide_target_opdef]))
            self.timer.start(20)

    @Slot()
    def slidePostsScene(self):
        if self.slide_target_opdef_id is None:
            return

        # self.post_view_scene_view
        self.post_view_scene.set_cursor_on(
            self.slide_target_opdef_id
        )  # This done here also aviod some screen trashing

        v = self.post_view_scene_view.verticalScrollBar().value()
        # mainlog.debug( "slidePostsScene : {}".format(v))

        r = self.post_view_scene.posts_offsets[self.slide_target_opdef_id]
        target_y = r.y() + r.height() / 2
        delta = (target_y - self.current_view_y) * 0.4
        self.current_view_y = self.current_view_y + delta
        self.post_view_scene_view.centerOn(0, self.current_view_y)
        # mainlog.debug( "slidePostsScene : {} / {}".format(target_y, self.current_view_y))

        if self.post_view_scene_view.verticalScrollBar().value() == v:
            # Close enough => stop moving
            # FIXME not correct because we must stop when the view stops moving, not when the goal we set for centerOn is reached
            self.timer.stop()

    @Slot(QModelIndex, QModelIndex)
    def operation_selected(self, ndx_cur, ndx_old):
        if ndx_cur.isValid():
            opdef = self._table_model.data(ndx_cur, Qt.UserRole)
            if opdef:
                self.slide_to_operation(
                    self._table_model.data(ndx_cur, Qt.UserRole))

    @Slot()
    def refresh_action(self):
        # FIXME reload operations as well

        operation_definitions, all_operations = self._data_load()

        # mainlog.debug("reload")
        if self.sort_by_deadline_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 1)
        elif self.sort_by_size_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 2)
        else:
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 0)

        # mainlog.debug("reset")
        first_active = self._reset_operation_definitions(operation_definitions)
        # self.table_view.selectionModel().currentChanged.connect(self.operation_selected)
        if first_active:
            self.table_view.setCurrentIndex(first_active)

        # mainlog.debug("done reset")

    @Slot(bool)
    def sort_by_deadline(self, checked):
        if checked:
            self.refresh_action()

    @Slot(bool)
    def sort_by_size(self, checked):
        if checked:
            self.refresh_action()

    order_part_double_clicked = Signal(int)

    # Callback that will be called by HooverBar
    def set_on_order_part(self, order_part_id):
        self.order_part_double_clicked.emit(order_part_id)
Exemple #2
0
class WorldViewer(QWidget):
    def __init__(self, charname='', currentzone='', parent=None):
        super(WorldViewer, self).__init__(parent)

        self.setWindowTitle("World Viewer")
        if not DEBUG:
            self.setWindowState(Qt.WindowMaximized)
        self.move(0,0)
        self.grabKeyboard()
        self.keyspressed = set()

        self.currentzone = currentzone
        self.charname = charname

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.scale(5, 5)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

#         pb = QPushButton("Push!")
#         stylesheet = '''
#                         QPushButton {
#                             border: 2px solid #8f8f91;
#                             border-radius: 6px;
#                             background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
#                                                             stop: 0 #f6f7fa, stop: 1 #dadbde);
#                             min-width: 80px;
#                         }
# 
#                         QPushButton:pressed {
#                             background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
#                                                             stop: 0 #dadbde, stop: 1 #f6f7fa);
#                         }
# 
#                         QPushButton:flat {
#                             border: none; /* no border for a flat push button */
#                         }
#                         QPushButton:default {
#                             border-color: navy; /* make the default button prominent */
#                         }
#         '''
#         pb.setStyleSheet(stylesheet)
#         self.scene.addWidget(pb)

        layout = QVBoxLayout()
        for w in (self.view, ):
            layout.addWidget(w)
        self.setLayout(layout)

        self.loading = self.scene.addText("Loading...")
        self.loading.setHtml("<h1>Loading...</h1>")

        self.last_update = datetime.datetime.now()
        self.world_objects = {}
        self.world_object_widgets = {}
        self._update_objects(client.get_all_objects(self.currentzone))
        print self.world_objects

        # Set character status to online.
        client.set_status(self.currentzone, self.charname)

        self.loading.hide()

        # Set a repeating callback on a timer to get object updates
        self.obj_update_timer = QTimer(self)
        self.connect(self.obj_update_timer, SIGNAL("timeout()"), self.update_objects)
        self.obj_update_timer.start(CLIENT_UPDATE_FREQ)

        # Set a repeating callback on a timer to send movement packets.
        self.movement_timer = QTimer(self)
        self.connect(self.movement_timer, SIGNAL("timeout()"), self.send_movement)
        self.movement_timer.start(CLIENT_UPDATE_FREQ)

    def sizeHint(self):
        desktop = QApplication.instance().desktop()
        geom = desktop.availableGeometry()
        return QSize(geom.width()/2, geom.height()/2)

    def keyPressEvent(self, event):
        '''Qt's key handling is wierd. If a key gets "stuck", just press and release it again.'''

        # Ignore autorepeat events.
        if event.isAutoRepeat():
            event.ignore()
            return

        # Add all other events to our set of pressed keys.
        self.keyspressed.add(event.key())
        event.accept()

    def keyReleaseEvent(self, event):
        # Ignore autorepeat events.
        if event.isAutoRepeat():
            event.ignore()
            return

        # Remove all other events from our set of pressed keys.
        self.keyspressed.discard(event.key())
        event.accept()

    def send_movement(self):
        '''Send movement calls to the zone/movement server.'''
        x = 0
        y = 0

        def _in_set(x, *args):
            for a in args:
                if int(a) in x:
                    return True
            return False

        if _in_set(self.keyspressed, Qt.Key_Left, Qt.Key_A):
            x -= 1
        if _in_set(self.keyspressed, Qt.Key_Right, Qt.Key_D):
            x += 1
        if _in_set(self.keyspressed, Qt.Key_Up, Qt.Key_W):
            y -= 1
        if _in_set(self.keyspressed, Qt.Key_Down, Qt.Key_S):
            y += 1

        client.send_movement(self.currentzone, self.charname, x, y, 0)

    def _update_objects(self, objectslist):
        if len(objectslist) != 0:
            print "Updated %d objects." % len(objectslist)

        for obj in objectslist:
            # Filter out any hidden objects
            if "hidden" in obj.get('states'):
                continue

            obj_id = obj['_id']['$oid']
            self.world_objects.update({obj_id: obj})
            if obj_id not in self.world_object_widgets:
                # Create a new widget, add it to the view and to world_object_widgets
                objwidget = WorldObject(obj)
                self.world_object_widgets.update({obj_id: objwidget})
                self.scene.addItem(objwidget)
            else:
                objwidget = self.world_object_widgets[obj_id]
                objwidget.setOffset(obj['loc']['x'], obj['loc']['y'])

            # Update our view if the name is the same as our character.
            if obj['name'] == self.charname:
                self.view.centerOn(objwidget)
                self.view.ensureVisible(objwidget)

    def update_objects(self):
        '''Gets an upated list of objects from the zone and stores them locally.'''
        new_objects = client.get_objects_since(self.last_update, self.currentzone)
        self._update_objects(new_objects)
        self.last_update = datetime.datetime.now()
Exemple #3
0
class WorldViewer(QWidget):
    def __init__(self, charname='', currentzone='', parent=None):
        super(WorldViewer, self).__init__(parent)

        self.setWindowTitle("World Viewer")
        if not DEBUG:
            self.setWindowState(Qt.WindowMaximized)
        self.move(0, 0)
        self.grabKeyboard()
        self.keyspressed = set()

        self.currentzone = currentzone
        self.charname = charname

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.scale(5, 5)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        #         pb = QPushButton("Push!")
        #         stylesheet = '''
        #                         QPushButton {
        #                             border: 2px solid #8f8f91;
        #                             border-radius: 6px;
        #                             background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
        #                                                             stop: 0 #f6f7fa, stop: 1 #dadbde);
        #                             min-width: 80px;
        #                         }
        #
        #                         QPushButton:pressed {
        #                             background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
        #                                                             stop: 0 #dadbde, stop: 1 #f6f7fa);
        #                         }
        #
        #                         QPushButton:flat {
        #                             border: none; /* no border for a flat push button */
        #                         }
        #                         QPushButton:default {
        #                             border-color: navy; /* make the default button prominent */
        #                         }
        #         '''
        #         pb.setStyleSheet(stylesheet)
        #         self.scene.addWidget(pb)

        layout = QVBoxLayout()
        for w in (self.view, ):
            layout.addWidget(w)
        self.setLayout(layout)

        self.loading = self.scene.addText("Loading...")
        self.loading.setHtml("<h1>Loading...</h1>")

        self.last_update = datetime.datetime.now()
        self.world_objects = {}
        self.world_object_widgets = {}
        self._update_objects(client.get_all_objects(self.currentzone))
        print self.world_objects

        # Set character status to online.
        client.set_status(self.currentzone, self.charname)

        self.loading.hide()

        # Set a repeating callback on a timer to get object updates
        self.obj_update_timer = QTimer(self)
        self.connect(self.obj_update_timer, SIGNAL("timeout()"),
                     self.update_objects)
        self.obj_update_timer.start(CLIENT_UPDATE_FREQ)

        # Set a repeating callback on a timer to send movement packets.
        self.movement_timer = QTimer(self)
        self.connect(self.movement_timer, SIGNAL("timeout()"),
                     self.send_movement)
        self.movement_timer.start(CLIENT_UPDATE_FREQ)

    def sizeHint(self):
        desktop = QApplication.instance().desktop()
        geom = desktop.availableGeometry()
        return QSize(geom.width() / 2, geom.height() / 2)

    def keyPressEvent(self, event):
        '''Qt's key handling is wierd. If a key gets "stuck", just press and release it again.'''

        # Ignore autorepeat events.
        if event.isAutoRepeat():
            event.ignore()
            return

        # Add all other events to our set of pressed keys.
        self.keyspressed.add(event.key())
        event.accept()

    def keyReleaseEvent(self, event):
        # Ignore autorepeat events.
        if event.isAutoRepeat():
            event.ignore()
            return

        # Remove all other events from our set of pressed keys.
        self.keyspressed.discard(event.key())
        event.accept()

    def send_movement(self):
        '''Send movement calls to the zone/movement server.'''
        x = 0
        y = 0

        def _in_set(x, *args):
            for a in args:
                if int(a) in x:
                    return True
            return False

        if _in_set(self.keyspressed, Qt.Key_Left, Qt.Key_A):
            x -= 1
        if _in_set(self.keyspressed, Qt.Key_Right, Qt.Key_D):
            x += 1
        if _in_set(self.keyspressed, Qt.Key_Up, Qt.Key_W):
            y -= 1
        if _in_set(self.keyspressed, Qt.Key_Down, Qt.Key_S):
            y += 1

        client.send_movement(self.currentzone, self.charname, x, y, 0)

    def _update_objects(self, objectslist):
        if len(objectslist) != 0:
            print "Updated %d objects." % len(objectslist)

        for obj in objectslist:
            # Filter out any hidden objects
            if "hidden" in obj.get('states'):
                continue

            obj_id = obj['_id']['$oid']
            self.world_objects.update({obj_id: obj})
            if obj_id not in self.world_object_widgets:
                # Create a new widget, add it to the view and to world_object_widgets
                objwidget = WorldObject(obj)
                self.world_object_widgets.update({obj_id: objwidget})
                self.scene.addItem(objwidget)
            else:
                objwidget = self.world_object_widgets[obj_id]
                objwidget.setOffset(obj['loc']['x'], obj['loc']['y'])

            # Update our view if the name is the same as our character.
            if obj['name'] == self.charname:
                self.view.centerOn(objwidget)
                self.view.ensureVisible(objwidget)

    def update_objects(self):
        '''Gets an upated list of objects from the zone and stores them locally.'''
        new_objects = client.get_objects_since(self.last_update,
                                               self.currentzone)
        self._update_objects(new_objects)
        self.last_update = datetime.datetime.now()