예제 #1
0
	def __init__(self, mainWindow):
		"""Initializes the user list."""
		super(QDockWidget, self).__init__(mainWindow)
		self.setWindowTitle(self.tr("Scratch Pad"))
		self.widget = QWidget(mainWindow)
		self.textArea = QTextEdit(mainWindow)
		self.currentEditingLabel = QLabel("No one is editing.")
		self.getLockButton = QPushButton("Edit")
		self.releaseLockButton = QPushButton("Confirm")
		#self.saveToFileButton = QPushButton("Save...")
		#self.loadButton = QPushButton("Load")
		self.layout = QGridLayout()
		self.layout.addWidget(self.currentEditingLabel, 0, 0, 1, 2)
		self.layout.addWidget(self.textArea, 1, 0, 1, 2)
		self.layout.addWidget(self.getLockButton, 2, 0)
		self.layout.addWidget(self.releaseLockButton, 2, 1)
		self.releaseLockButton.pressed.connect(self._releaseLock)
		self.getLockButton.pressed.connect(self._getLock)
		self.widget.setLayout(self.layout)
		self.setWidget(self.widget)
		self.setObjectName("Scratch Pad Widget")
		self.hasLock = False
		self.updateButtonStatus()
		try:
			with open(ospath.join(SAVE_DIR, "scratchpad.txt"), 'r') as autosave:
				self.textArea.setText(autosave.read())
		except:
			pass
		mainWindow.addDockWidget(Qt.BottomDockWidgetArea, self)
예제 #2
0
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)

        #self.__eat = True
        self.painting = True
        self.dragging = False
        self.rectStart = None

        self.setWindowTitle(self.tr("Map Editor"))
        self.widget = QWidget(mainWindow)
        self.layout = QGridLayout()
        self.currentTileLayout = QBoxLayout(1)
        self.scrollarea = QScrollArea(mainWindow)
        self.noPaintingButton = QRadioButton(self.tr("Stop Painting"),
                                             mainWindow)
        self.singlePaintingButton = QRadioButton(self.tr("Single Tile Brush"),
                                                 mainWindow)
        self.noPaintingButton.setChecked(True)
        self.rectPaintingButton = QRadioButton(
            self.tr("Area (Rectangle) Brush"), mainWindow)
        self.hollowRectPaintingButton = QRadioButton(
            self.tr("Hollow Rectangle Brush"), mainWindow)
        self.currentTileLabel = QLabel()
        self.currentTileLabelLabel = QLabel(self.tr("Current tile: "))
        self.undoButton = QPushButton("Undo", mainWindow)
        self.redoButton = QPushButton("Redo", mainWindow)
        #self.moveMapButton = QPushButton("Move Map", mainWindow)
        self.layout.addWidget(self.scrollarea, 0, 0, 1, 2)
        self.layout.addWidget(self.noPaintingButton, 1, 0)
        self.layout.addWidget(self.singlePaintingButton, 2, 0)
        self.layout.addWidget(self.rectPaintingButton, 3, 0)
        self.layout.addWidget(self.hollowRectPaintingButton, 4, 0)
        self.layout.addWidget(self.undoButton, 1, 1)
        self.layout.addWidget(self.redoButton, 2, 1)
        #self.layout.addWidget(self.moveMapButton, 3, 1)
        self.layout.addWidget(self.currentTileLabel, 5, 1)
        self.layout.addWidget(self.currentTileLabelLabel, 5, 0)
        self.tilelabel = None
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("Map Editor")
        mainWindow.addDockWidget(Qt.RightDockWidgetArea, self)

        self.currentMap = None
        self.copyData = None

        self.undo = []
        self.undoButton.clicked.connect(self._undo)
        self.undoButton.setEnabled(False)

        self.redo = []
        self.redoButton.clicked.connect(self._redo)
        self.redoButton.setEnabled(False)

        addMapChangedListener(self.mapChangedResponse, NORMAL_RESPONSE_LEVEL)
        addMousePressListener(self.mousePressResponse, NORMAL_RESPONSE_LEVEL)
        addMouseMoveListener(self.mouseMoveResponse, NORMAL_RESPONSE_LEVEL)
        addMouseReleaseListener(self.mouseReleaseResponse,
                                NORMAL_RESPONSE_LEVEL)
예제 #3
0
class transferMonitorWidget(QDockWidget):
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)
        self.setToolTip(
            self.tr("Allows for monitoring and control of file transfers."))
        self.setWindowTitle(self.tr("Transfer Monitor"))
        self.transferDict = {}
        self.transferTable = QTableWidget(0, 3, mainWindow)
        self.transferTable.setHorizontalHeaderLabels(
            ["Client", "Filename", "Status"])
        self.widget = QWidget(mainWindow)
        self.status = QLabel("Initializing", mainWindow)
        self.layout = QBoxLayout(2)
        self.layout.addWidget(self.transferTable)
        self.layout.addWidget(self.status)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("Transfer Monitor")

        mainWindow.addDockWidget(Qt.BottomDockWidgetArea, self)

        self.hide()

    def updateItem(self, client, filename, status):
        '''Update the status of a transfer, creating a new table row for it if it's new.'''
        if client.username + filename not in list(self.transferDict.keys()):
            self.transferDict[client.username +
                              filename] = self.transferTable.rowCount()
            self.transferTable.setRowCount(self.transferTable.rowCount() + 1)
            for column in (0, 1, 2):
                self.transferTable.setItem(self.transferTable.rowCount() - 1,
                                           column, QTableWidgetItem(""))
                self.transferTable.item(self.transferTable.rowCount() - 1,
                                        column).setFlags(Qt.NoItemFlags)
        self.transferTable.item(self.transferDict[client.username + filename],
                                0).setText(client.username)
        self.transferTable.item(self.transferDict[client.username + filename],
                                1).setText(filename)
        self.transferTable.item(self.transferDict[client.username + filename],
                                2).setText(status)
        self.transferTable.update()
        self.update()

    def processFileEvent(self, client, filename, event):
        '''Process a raw file/general status event.'''
        if len(filename) > 1:
            self.updateItem(client, filename, event)
        else:
            self.status.setText(event)
            self.update()

    def processPartialTransferEvent(self, client, filename, size, processed):
        '''Process a partial transfer event.'''
        processedAmount = "".join(
            (UNICODE_STRING(round(float(processed) / float(size) * 100,
                                  1)), "%"))
        self.updateItem(client, filename, processedAmount)
예제 #4
0
 def displayImage(self, image):
     converted = imqt.ImageQt(image)
     converted = converted.copy()
     converted = QPixmap.fromImage(converted)
     label = QLabel()
     label.setPixmap(converted)
     self.scrollarea.setWidget(label)
     if (converted.height(),
             converted.width()) not in self.validBorderSizes:
         self.borderButton.setEnabled(False)
     else:
         self.borderButton.setEnabled(True)
예제 #5
0
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)
        self.setToolTip(
            self.tr("Allows for monitoring and control of file transfers."))
        self.setWindowTitle(self.tr("Transfer Monitor"))
        self.transferDict = {}
        self.transferTable = QTableWidget(0, 3, mainWindow)
        self.transferTable.setHorizontalHeaderLabels(
            ["Client", "Filename", "Status"])
        self.widget = QWidget(mainWindow)
        self.status = QLabel("Initializing", mainWindow)
        self.layout = QBoxLayout(2)
        self.layout.addWidget(self.transferTable)
        self.layout.addWidget(self.status)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("Transfer Monitor")

        mainWindow.addDockWidget(Qt.BottomDockWidgetArea, self)

        self.hide()
예제 #6
0
class mapEditor(QDockWidget):
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)

        #self.__eat = True
        self.painting = True
        self.dragging = False
        self.rectStart = None

        self.setWindowTitle(self.tr("Map Editor"))
        self.widget = QWidget(mainWindow)
        self.layout = QGridLayout()
        self.currentTileLayout = QBoxLayout(1)
        self.scrollarea = QScrollArea(mainWindow)
        self.noPaintingButton = QRadioButton(self.tr("Stop Painting"),
                                             mainWindow)
        self.singlePaintingButton = QRadioButton(self.tr("Single Tile Brush"),
                                                 mainWindow)
        self.noPaintingButton.setChecked(True)
        self.rectPaintingButton = QRadioButton(
            self.tr("Area (Rectangle) Brush"), mainWindow)
        self.hollowRectPaintingButton = QRadioButton(
            self.tr("Hollow Rectangle Brush"), mainWindow)
        self.currentTileLabel = QLabel()
        self.currentTileLabelLabel = QLabel(self.tr("Current tile: "))
        self.undoButton = QPushButton("Undo", mainWindow)
        self.redoButton = QPushButton("Redo", mainWindow)
        #self.moveMapButton = QPushButton("Move Map", mainWindow)
        self.layout.addWidget(self.scrollarea, 0, 0, 1, 2)
        self.layout.addWidget(self.noPaintingButton, 1, 0)
        self.layout.addWidget(self.singlePaintingButton, 2, 0)
        self.layout.addWidget(self.rectPaintingButton, 3, 0)
        self.layout.addWidget(self.hollowRectPaintingButton, 4, 0)
        self.layout.addWidget(self.undoButton, 1, 1)
        self.layout.addWidget(self.redoButton, 2, 1)
        #self.layout.addWidget(self.moveMapButton, 3, 1)
        self.layout.addWidget(self.currentTileLabel, 5, 1)
        self.layout.addWidget(self.currentTileLabelLabel, 5, 0)
        self.tilelabel = None
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("Map Editor")
        mainWindow.addDockWidget(Qt.RightDockWidgetArea, self)

        self.currentMap = None
        self.copyData = None

        self.undo = []
        self.undoButton.clicked.connect(self._undo)
        self.undoButton.setEnabled(False)

        self.redo = []
        self.redoButton.clicked.connect(self._redo)
        self.redoButton.setEnabled(False)

        addMapChangedListener(self.mapChangedResponse, NORMAL_RESPONSE_LEVEL)
        addMousePressListener(self.mousePressResponse, NORMAL_RESPONSE_LEVEL)
        addMouseMoveListener(self.mouseMoveResponse, NORMAL_RESPONSE_LEVEL)
        addMouseReleaseListener(self.mouseReleaseResponse,
                                NORMAL_RESPONSE_LEVEL)

    def _undo(self):
        try:
            from libraries.rggViews import _sendTileUpdate
        except ImportError:
            from rggViews import _sendTileUpdate
        redoTiles = []
        for data in self.undo.pop():
            redoTiles.append(
                (data[0], data[1], _sendTileUpdate(data[0], data[1], data[2])))
        self.redo.append(redoTiles)
        self.redoButton.setEnabled(True)
        if len(self.undo) == 0:
            self.undoButton.setEnabled(False)

    def _redo(self):
        try:
            from libraries.rggViews import _sendTileUpdate
        except ImportError:
            from rggViews import _sendTileUpdate
        undoTiles = []
        for data in self.redo.pop():
            undoTiles.append(
                (data[0], data[1], _sendTileUpdate(data[0], data[1], data[2])))
        self.undo.append(undoTiles)
        self.undoButton.setEnabled(True)
        if len(self.redo) == 0:
            self.redoButton.setEnabled(False)

    def updateCurrentTile(self):
        self.tilepix = QPixmap()
        self.tilepix.load(self.currentMap.tileset)
        self.tilepix = self.tilepix.copy(
            QRect(*self.tilelabel.currentTileDimensions))
        self.currentTileLabel.setPixmap(self.tilepix)

    def mousePressResponse(self, x, y, t):
        mapPosition = getMapPosition((x, y))

        #This and similar things were a regrettable necessity in the plugin -> nonplugin conversion process.
        try:
            from libraries.rggViews import topmap, _sendTileUpdate
        except ImportError:
            from rggViews import topmap, _sendTileUpdate

        map = topmap(mapPosition)
        if map == None:
            return
        if map != self.currentMap:
            self.mapChangedResponse(map)
        if t == 0:
            self.dragging = True
            if self.isVisible() and self.singlePaintingButton.isChecked():
                clickedtile = (int(((mapPosition[0] - map.drawOffset[0]) /
                                    self.tilelabel.tilex)),
                               int(((mapPosition[1] - map.drawOffset[1]) /
                                    self.tilelabel.tiley)))
                if not map.tilePosExists(clickedtile):
                    return True
                oldtile = _sendTileUpdate(map.ID, clickedtile,
                                          self.tilelabel.currentTile)
                self.undo.append([
                    (map.ID, clickedtile, oldtile),
                ])
                self.redo = []
                self.redoButton.setEnabled(False)
                self.undoButton.setEnabled(True)
                return True
            elif self.isVisible() and (
                    self.rectPaintingButton.isChecked()
                    or self.hollowRectPaintingButton.isChecked()):
                self.rectStart = (int(((mapPosition[0] - map.drawOffset[0]) /
                                       self.tilelabel.tilex)),
                                  int(((mapPosition[1] - map.drawOffset[1]) /
                                       self.tilelabel.tiley)))
                if not map.tilePosExists(self.rectStart):
                    self.rectStart = None
                return True
        elif t == 5:
            if self.isVisible() and not self.noPaintingButton.isChecked():
                clickedtile = (int(((mapPosition[0] - map.drawOffset[0]) /
                                    self.tilelabel.tilex)),
                               int(((mapPosition[1] - map.drawOffset[1]) /
                                    self.tilelabel.tiley)))
                self.tilelabel.currentTile = map.getTile(clickedtile)
                self.tilelabel.updateTile()
                return True
        elif t == 6:
            if self.isVisible(
            ) and not self.noPaintingButton.isChecked() and self.copyData:
                if self.singlePaintingButton.isChecked():
                    clickedtile = (int(((mapPosition[0] - map.drawOffset[0]) /
                                        self.tilelabel.tilex)),
                                   int(((mapPosition[1] - map.drawOffset[1]) /
                                        self.tilelabel.tiley)))
                    for row, columns in enumerate(self.copyData):
                        for column, tile in enumerate(columns):
                            _sendTileUpdate(map.ID, (clickedtile[0] + row,
                                                     clickedtile[1] + column),
                                            tile)
                elif self.rectPaintingButton.isChecked():
                    self.rectStart = (
                        int(((mapPosition[0] - map.drawOffset[0]) /
                             self.tilelabel.tilex)),
                        int(((mapPosition[1] - map.drawOffset[1]) /
                             self.tilelabel.tiley)))
                    if not map.tilePosExists(self.rectStart):
                        self.rectStart = None
                    return True
        elif t == 8:
            if self.isVisible() and not self.noPaintingButton.isChecked():
                self.rectStart = (int(((mapPosition[0] - map.drawOffset[0]) /
                                       self.tilelabel.tilex)),
                                  int(((mapPosition[1] - map.drawOffset[1]) /
                                       self.tilelabel.tiley)))
                if not map.tilePosExists(self.rectStart):
                    self.rectStart = None
                return True

    def mouseMoveResponse(self, x, y):
        if self.dragging and self.isVisible(
        ) and self.singlePaintingButton.isChecked():
            try:
                from libraries.rggViews import topmap
            except ImportError:
                from rggViews import topmap
            mapPosition = getMapPosition((x, y))
            map = topmap(mapPosition)
            if map == None:
                self.dragging = False
                return
            clickedtile = (int(
                ((mapPosition[0] - map.drawOffset[0]) / self.tilelabel.tilex)),
                           int(((mapPosition[1] - map.drawOffset[1]) /
                                self.tilelabel.tiley)))

            if map.tilePosExists(clickedtile) and map.getTile(
                    clickedtile) != self.tilelabel.currentTile:
                try:
                    from libraries.rggViews import _sendTileUpdate
                except ImportError:
                    from rggViews import _sendTileUpdate
                oldtile = _sendTileUpdate(map.ID, clickedtile,
                                          self.tilelabel.currentTile)
                self.undo[-1].append((map.ID, clickedtile, oldtile))
            return True

    def mouseReleaseResponse(self, x, y, t):
        if t == 0:
            try:
                from libraries.rggViews import topmap, _sendTileUpdate, _sendMultipleTileUpdate
            except ImportError:
                from rggViews import topmap, _sendTileUpdate, _sendMultipleTileUpdate
            if self.currentMap == None:
                return
            mapPosition = getMapPosition((x, y))
            map = topmap(mapPosition)
            self.dragging = False
            if map == None or map != self.currentMap:
                return
            if self.isVisible() and self.singlePaintingButton.isChecked():
                return True
            elif self.isVisible() and self.rectPaintingButton.isChecked(
            ) and self.rectStart is not None:
                rectEnd = (int(((mapPosition[0] - map.drawOffset[0]) /
                                self.tilelabel.tilex)),
                           int(((mapPosition[1] - map.drawOffset[1]) /
                                self.tilelabel.tiley)))
                if not map.tilePosExists(rectEnd):
                    self.rectStart = None
                    self.rectEnd = None
                    return
                self.undo.append([])
                self.undoButton.setEnabled(True)
                self.redo = []
                self.redoButton.setEnabled(False)
                oldtiles = _sendMultipleTileUpdate(
                    self.currentMap.ID, (min(rectEnd[0], self.rectStart[0]),
                                         min(rectEnd[1], self.rectStart[1])),
                    (max(rectEnd[0], self.rectStart[0]),
                     max(rectEnd[1], self.rectStart[1])),
                    self.tilelabel.currentTile)
                for x in range(min(rectEnd[0], self.rectStart[0]),
                               max(rectEnd[0], self.rectStart[0]) + 1):
                    for y in range(min(rectEnd[1], self.rectStart[1]),
                                   max(rectEnd[1], self.rectStart[1]) + 1):
                        self.undo[-1].append((map.ID, (x, y), oldtiles.pop(0)))
                return True
            elif self.isVisible() and self.hollowRectPaintingButton.isChecked(
            ) and self.rectStart is not None:
                rectEnd = (int(((mapPosition[0] - map.drawOffset[0]) /
                                self.tilelabel.tilex)),
                           int(((mapPosition[1] - map.drawOffset[1]) /
                                self.tilelabel.tiley)))
                if not map.tilePosExists(rectEnd):
                    self.rectStart = None
                    self.rectEnd = None
                    return
                self.undo.append([])
                self.undoButton.setEnabled(True)
                self.redo = []
                self.redoButton.setEnabled(False)
                if rectEnd[0] != self.rectStart[0]:
                    for x in range(
                            self.rectStart[0], rectEnd[0] +
                        (1 * (rectEnd[0] - self.rectStart[0])),
                            1 * (rectEnd[0] - self.rectStart[0])):
                        if rectEnd[1] != self.rectStart[1]:
                            #TODO: Less lazy and inefficient implementation for this case.
                            for y in range(
                                    self.rectStart[1], rectEnd[1] + 1 *
                                (rectEnd[1] - self.rectStart[1]),
                                    1 * (rectEnd[1] - self.rectStart[1])):
                                if x == self.rectStart[0] or x == rectEnd[
                                        0] or y == self.rectStart[
                                            1] or y == rectEnd[1]:
                                    if self.currentMap.tilePosExists((x, y)):
                                        oldtile = _sendTileUpdate(
                                            self.currentMap.ID, (x, y),
                                            self.tilelabel.currentTile)
                                        self.undo[-1].append(
                                            (map.ID, (x, y), oldtile))
                        else:
                            if self.currentMap.tilePosExists(
                                (x, self.rectStart[1])):
                                oldtile = _sendTileUpdate(
                                    self.currentMap.ID, (x, self.rectStart[1]),
                                    self.tilelabel.currentTile)
                                self.undo[-1].append(
                                    (map.ID, (x, self.rectStart[1]), oldtile))
                else:
                    if rectEnd[1] != self.rectStart[1]:
                        for y in range(
                                self.rectStart[1], rectEnd[1] + 1 *
                            (rectEnd[1] - self.rectStart[1]),
                                1 * (rectEnd[1], self.rectStart[1])):
                            if self.currentMap.tilePosExists(
                                (self.rectStart[0], y)):
                                oldtile = _sendTileUpdate(
                                    self.currentMap.ID, (self.rectStart[0], y),
                                    self.tilelabel.currentTile)
                                self.undo[-1].append(
                                    (map.ID, (self.rectStart[0], y), oldtile))
                    else:
                        if self.currentMap.tilePosExists(
                            (self.rectStart[0], self.rectStart[1])):
                            oldtile = _sendTileUpdate(
                                self.currentMap.ID,
                                (self.rectStart[0], self.rectStart[1]),
                                self.tilelabel.currentTile)
                            self.undo[-1].append(
                                (map.ID, (self.rectStart[0],
                                          self.rectStart[1]), oldtile))
                return True
        elif t == 6:
            if self.isVisible() and self.rectPaintingButton.isChecked(
            ) and self.copyData:
                try:
                    from libraries.rggViews import topmap, _sendTileUpdate
                except ImportError:
                    from rggViews import topmap, _sendTileUpdate
                if self.currentMap == None:
                    return
                mapPosition = getMapPosition((x, y))
                map = topmap(mapPosition)
                self.dragging = False
                if map == None or map != self.currentMap:
                    return
                rectEnd = (int(((mapPosition[0] - map.drawOffset[0]) /
                                self.tilelabel.tilex)),
                           int(((mapPosition[1] - map.drawOffset[1]) /
                                self.tilelabel.tiley)))
                if not map.tilePosExists(rectEnd):
                    self.rectStart = None
                    self.rectEnd = None
                    return
                topleft = (min(self.rectStart[0],
                               rectEnd[0]), min(self.rectStart[1], rectEnd[1]))
                bottomright = (max(self.rectStart[0], rectEnd[0]),
                               max(self.rectStart[1], rectEnd[1]))
                for row in range(1 + (bottomright[0] - topleft[0])):
                    for column in range(1 + (bottomright[1] - topleft[1])):
                        _sendTileUpdate(
                            self.currentMap.ID,
                            (topleft[0] + row, topleft[1] + column),
                            self.copyData[row % len(self.copyData)][
                                column %
                                len(self.copyData[row % len(self.copyData)])])
                return True
        elif t == 8:
            if self.isVisible() and not self.noPaintingButton.isChecked():
                try:
                    from libraries.rggViews import topmap
                except ImportError:
                    from rggViews import topmap
                if self.currentMap == None:
                    return
                mapPosition = getMapPosition((x, y))
                map = topmap(mapPosition)
                self.dragging = False
                if map == None or map != self.currentMap:
                    return
                rectEnd = (int(((mapPosition[0] - map.drawOffset[0]) /
                                self.tilelabel.tilex)),
                           int(((mapPosition[1] - map.drawOffset[1]) /
                                self.tilelabel.tiley)))
                if not map.tilePosExists(rectEnd):
                    self.rectStart = None
                    self.rectEnd = None
                    return
                topleft = (min(self.rectStart[0],
                               rectEnd[0]), min(self.rectStart[1], rectEnd[1]))
                bottomright = (max(self.rectStart[0], rectEnd[0]),
                               max(self.rectStart[1], rectEnd[1]))
                copypaste = []
                for row in range(1 + (bottomright[0] - topleft[0])):
                    copypaste.append([])
                    for column in range(1 + (bottomright[1] - topleft[1])):
                        copypaste[row].append(
                            map.getTile(
                                (topleft[0] + row, topleft[1] + column)))
                self.copyData = copypaste
                return True

    def mapChangedResponse(self, newMap):
        if newMap != None:
            self.currentMap = newMap
            self.tilepixmap = QPixmap()
            self.tilepixmap.load(newMap.tileset)
            if self.tilelabel is None:
                self.tilelabel = mapEditorLabel(newMap.tilesize,
                                                self.tilepixmap.width(),
                                                self.tilepixmap.height(), self)
            else:
                self.tilelabel = mapEditorLabel(newMap.tilesize,
                                                self.tilepixmap.width(),
                                                self.tilepixmap.height(), self,
                                                self.tilelabel.currentTile)
            self.tilelabel.setPixmap(self.tilepixmap)
            self.scrollarea.setWidget(self.tilelabel)
예제 #7
0
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)
        self.setToolTip(self.tr("A widget for in-character chat."))
        self.setWindowTitle(self.tr("IC Chat"))
        self.widgetEditor = QTextBrowser(mainWindow)
        self.widgetLineInput = chatLineEdit(mainWindow)
        self.widgetLineInput.setToolTip(
            self.tr(
                "Type text here and press Enter or Return to transmit it."))
        self.widget = QWidget(mainWindow)
        self.widgetEditor.setReadOnly(True)
        self.widgetEditor.setOpenLinks(False)
        self.characterPreview = QLabel(mainWindow)
        self.characterSelector = QComboBox(mainWindow)
        self.characterSelector.setToolTip(
            self.
            tr("Select the character to be displayed as the speaker of entered text."
               ))
        self.characterAddButton = QPushButton(self.tr("Add New"), mainWindow)
        self.characterAddButton.setToolTip(
            self.tr("Add a new in-character chat character via a dialog box."))
        self.characterDeleteButton = QPushButton(self.tr("Delete"), mainWindow)
        self.characterDeleteButton.setToolTip(
            self.tr(
                "Delete the currently selected in-character chat character."))
        self.characterClearButton = QPushButton(self.tr("Clear"), mainWindow)
        self.characterClearButton.setToolTip(
            self.tr("Deletes all in-character chat characters."))
        self.layout = QGridLayout()
        self.layout.addWidget(self.widgetEditor, 0, 0, 1, 4)
        self.layout.addWidget(self.widgetLineInput, 1, 1, 1, 3)
        self.layout.addWidget(self.characterPreview, 1, 0, 2, 1)
        self.layout.addWidget(self.characterDeleteButton, 2, 3, 1, 1)
        self.layout.addWidget(self.characterClearButton, 3, 3, 1, 1)
        self.layout.addWidget(self.characterAddButton, 2, 2, 1, 1)
        self.layout.addWidget(self.characterSelector, 2, 1, 1, 1)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("IC Chat Widget")
        self.messageCache = []

        self.setAcceptDrops(True)

        mainWindow.addDockWidget(Qt.LeftDockWidgetArea, self)

        #TODO: Store and access characters in a better fashion.
        try:
            self.load(jsonload(ospath.join(CHAR_DIR, "autosave.rgc")))
        except:
            self.characters = []

        self.widgetLineInput.returnPressed.connect(self.processInput)
        self.characterAddButton.clicked.connect(self.newCharacter)
        self.characterDeleteButton.clicked.connect(self.deleteCharacter)
        self.characterClearButton.clicked.connect(self.clearCharacters)
        self.characterSelector.currentIndexChanged.connect(
            self.setCharacterPreview)

        self.updateDeleteButton()

        self.setCharacterPreview()
예제 #8
0
class ICChatWidget(QDockWidget):
    def __init__(self, mainWindow):
        super(QDockWidget, self).__init__(mainWindow)
        self.setToolTip(self.tr("A widget for in-character chat."))
        self.setWindowTitle(self.tr("IC Chat"))
        self.widgetEditor = QTextBrowser(mainWindow)
        self.widgetLineInput = chatLineEdit(mainWindow)
        self.widgetLineInput.setToolTip(
            self.tr(
                "Type text here and press Enter or Return to transmit it."))
        self.widget = QWidget(mainWindow)
        self.widgetEditor.setReadOnly(True)
        self.widgetEditor.setOpenLinks(False)
        self.characterPreview = QLabel(mainWindow)
        self.characterSelector = QComboBox(mainWindow)
        self.characterSelector.setToolTip(
            self.
            tr("Select the character to be displayed as the speaker of entered text."
               ))
        self.characterAddButton = QPushButton(self.tr("Add New"), mainWindow)
        self.characterAddButton.setToolTip(
            self.tr("Add a new in-character chat character via a dialog box."))
        self.characterDeleteButton = QPushButton(self.tr("Delete"), mainWindow)
        self.characterDeleteButton.setToolTip(
            self.tr(
                "Delete the currently selected in-character chat character."))
        self.characterClearButton = QPushButton(self.tr("Clear"), mainWindow)
        self.characterClearButton.setToolTip(
            self.tr("Deletes all in-character chat characters."))
        self.layout = QGridLayout()
        self.layout.addWidget(self.widgetEditor, 0, 0, 1, 4)
        self.layout.addWidget(self.widgetLineInput, 1, 1, 1, 3)
        self.layout.addWidget(self.characterPreview, 1, 0, 2, 1)
        self.layout.addWidget(self.characterDeleteButton, 2, 3, 1, 1)
        self.layout.addWidget(self.characterClearButton, 3, 3, 1, 1)
        self.layout.addWidget(self.characterAddButton, 2, 2, 1, 1)
        self.layout.addWidget(self.characterSelector, 2, 1, 1, 1)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
        self.setObjectName("IC Chat Widget")
        self.messageCache = []

        self.setAcceptDrops(True)

        mainWindow.addDockWidget(Qt.LeftDockWidgetArea, self)

        #TODO: Store and access characters in a better fashion.
        try:
            self.load(jsonload(ospath.join(CHAR_DIR, "autosave.rgc")))
        except:
            self.characters = []

        self.widgetLineInput.returnPressed.connect(self.processInput)
        self.characterAddButton.clicked.connect(self.newCharacter)
        self.characterDeleteButton.clicked.connect(self.deleteCharacter)
        self.characterClearButton.clicked.connect(self.clearCharacters)
        self.characterSelector.currentIndexChanged.connect(
            self.setCharacterPreview)

        self.updateDeleteButton()

        self.setCharacterPreview()

    def toggleDarkBackgroundSupport(self, dark):
        if dark:
            self.widgetEditor.document().setDefaultStyleSheet(
                "a {color: cyan; }")
        else:
            self.widgetEditor.document().setDefaultStyleSheet(
                "a {color: blue; }")
        self.refreshMessages()

    def refreshMessages(self):
        '''Clear the text display and re-add all messages with current style settings etc.'''
        self.widgetEditor.clear()
        for message in self.messageCache:
            self.widgetEditor.append(message)

    def updateDeleteButton(self):
        self.characterDeleteButton.setEnabled(self.hasCharacters())
        self.characterClearButton.setEnabled(self.hasCharacters())
        self.characterSelector.setEnabled(self.hasCharacters())
        self.widgetLineInput.setEnabled(self.hasCharacters())

    def setCharacterPreview(self, newIndex=-1):
        try:
            preview = QPixmap(
                ospath.join(
                    UNICODE_STRING(PORTRAIT_DIR),
                    UNICODE_STRING(self.characters[
                        self.characterSelector.currentIndex()].portrait)))
            if preview.isNull(
            ):  #Sadly, we have to check ahead, because Qt is dumb and prints an error about the scaling instead of raising one we can catch.
                raise TypeError
            preview = preview.scaled(min(preview.width(), 64),
                                     min(preview.height(), 64))
            self.characterPreview.setPixmap(preview)
        except:
            self.characterPreview.clear()

    def insertMessage(self, mes):
        self.scroll = (self.widgetEditor.verticalScrollBar().value() ==
                       self.widgetEditor.verticalScrollBar().maximum())
        self.messageCache.append(mes)
        self.widgetEditor.append(mes)
        if self.scroll:
            self.widgetEditor.verticalScrollBar().setValue(
                self.widgetEditor.verticalScrollBar().maximum())
        try:
            try:
                self.logfile = open(
                    ospath.join(LOG_DIR, strftime("%b_%d_%Y.log",
                                                  localtime())), 'a')
                self.logfile.write(mes + "\n")
            finally:
                self.logfile.close()
        except:
            pass

    def dragEnterEvent(self, event):
        if event.mimeData().hasImage():
            event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasImage():
            dat = event.mimeData().imageData()
            img = QImage(dat)
            filename = promptSaveFile('Save Portrait',
                                      'Portrait files (*.png)', PORTRAIT_DIR)
            if filename is not None:
                img.save(filename, "PNG")
            event.acceptProposedAction()

    def newCharacter(self):
        dialog = newCharacterDialog()

        def accept():
            valid = dialog.is_valid()
            if not valid:
                showErrorMessage(dialog.error)
            return valid

        if dialog.exec_(self.parentWidget(), accept):
            newchardat = dialog.save()
            newchar = ICChar(*newchardat)
            self.characterSelector.addItem(newchar.id)
            self.characters.append(newchar)
            jsondump(self.dump(), ospath.join(CHAR_DIR, "autosave.rgc"))
            self.characterSelector.setCurrentIndex(
                self.characterSelector.count() - 1)
            self.updateDeleteButton()
            self.setCharacterPreview()

    def _newChar(self, char):
        self.characterSelector.addItem(char.id)
        self.characters.append(char)
        jsondump(self.dump(), ospath.join(CHAR_DIR, "autosave.rgc"))

    def deleteCharacter(self):
        if self.hasCharacters():
            self.characters.pop(self.characterSelector.currentIndex())
            self.characterSelector.removeItem(
                self.characterSelector.currentIndex())
            jsondump(self.dump(), ospath.join(CHAR_DIR, "autosave.rgc"))
            self.updateDeleteButton()

    def clearCharacters(self):
        if promptYesNo('Really clear all characters?') == 16384:
            self.characters = []
            self.characterSelector.clear()
            jsondump(self.dump(), ospath.join(CHAR_DIR, "autosave.rgc"))
            self.updateDeleteButton()
            self.setCharacterPreview()

    def processTags(self, message):
        message = message.replace("<", "&lt;").replace(">", "&gt;")
        for validTag in ("i", "b", "u", "s"):
            message = message.replace("".join(("[", validTag, "]")), "".join(
                ("<", validTag, ">")))
            message = message.replace("".join(("[", "/", validTag, "]")),
                                      "".join(("<", "/", validTag, ">")))
        return message

    def processInput(self):
        self.newmes = UNICODE_STRING(self.widgetLineInput.text())
        self.newmes = self.processTags(self.newmes)
        self.widgetLineInput.clear()
        self.widgetLineInput.addMessage(self.newmes)
        self.ICChatInput.emit(
            self.newmes,
            UNICODE_STRING(
                self.characters[self.characterSelector.currentIndex()].name),
            UNICODE_STRING(self.characters[
                self.characterSelector.currentIndex()].portrait))

    def hasCharacters(self):
        return len(self.characters) > 0

    def dump(self):
        """Serialize to an object valid for JSON dumping."""

        return dict(chars=dict([(i, char.dump())
                                for i, char in enumerate(self.characters)]))

    def load(self, obj):
        """Deserialize set of IC characters from a dictionary."""

        self.characters = []
        self.characterSelector.clear()

        chars = loadObject('ICChatWidget.chars', obj.get('chars'))
        chartemp = [None] * len(list(chars.keys()))
        for ID, char in list(chars.items()):
            chartemp[int(ID)] = char
        for char in chartemp:
            loaded = ICChar.load(char)
            self._newChar(loaded)
        self.updateDeleteButton()
        self.setCharacterPreview()

    ICChatInput = signal(
        BASE_STRING,
        BASE_STRING,
        BASE_STRING,
        doc="""Called when in-character chat input is received.

		charname -- the character name currently selected
		text -- the message entered
		portrait -- the portrait path, relative to data/portraits

		""")
예제 #9
0
class scratchPadWidget(QDockWidget):
	"""A mutually-editable shared text widget."""

	def __init__(self, mainWindow):
		"""Initializes the user list."""
		super(QDockWidget, self).__init__(mainWindow)
		self.setWindowTitle(self.tr("Scratch Pad"))
		self.widget = QWidget(mainWindow)
		self.textArea = QTextEdit(mainWindow)
		self.currentEditingLabel = QLabel("No one is editing.")
		self.getLockButton = QPushButton("Edit")
		self.releaseLockButton = QPushButton("Confirm")
		#self.saveToFileButton = QPushButton("Save...")
		#self.loadButton = QPushButton("Load")
		self.layout = QGridLayout()
		self.layout.addWidget(self.currentEditingLabel, 0, 0, 1, 2)
		self.layout.addWidget(self.textArea, 1, 0, 1, 2)
		self.layout.addWidget(self.getLockButton, 2, 0)
		self.layout.addWidget(self.releaseLockButton, 2, 1)
		self.releaseLockButton.pressed.connect(self._releaseLock)
		self.getLockButton.pressed.connect(self._getLock)
		self.widget.setLayout(self.layout)
		self.setWidget(self.widget)
		self.setObjectName("Scratch Pad Widget")
		self.hasLock = False
		self.updateButtonStatus()
		try:
			with open(ospath.join(SAVE_DIR, "scratchpad.txt"), 'r') as autosave:
				self.textArea.setText(autosave.read())
		except:
			pass
		mainWindow.addDockWidget(Qt.BottomDockWidgetArea, self)

	@property
	def currentText(self):
		return self.textArea.toPlainText()

	def updateButtonStatus(self):
		self.getLockButton.setEnabled(not self.hasLock)
		self.textArea.setReadOnly(not self.hasLock)
		self.releaseLockButton.setEnabled(self.hasLock)

	def _getLock(self):
		self.getScratchPadLock.emit()

	def _releaseLock(self):
		self.updateScratchPad.emit()
		self.releaseScratchPadLock.emit()

	def getLock(self):
		self.hasLock = True
		self.updateButtonStatus()

	def releaseLock(self, name):
		self.hasLock = False
		if name:
			self.currentEditingLabel.setText("%s is editing." % name)
		else:
			self.currentEditingLabel.setText("No one is editing.")
		self.updateButtonStatus()

	def updateText(self, txt):
		if len(txt) > 100000:
			print("Excessively long scratchpad data received. Might be an attack or just a bug.")
			return
		self.textArea.setText(txt)
		try:
			with open(ospath.join(SAVE_DIR, "scratchpad.txt"), 'w') as autosave:
				autosave.write(txt)
		except:
			pass

	getScratchPadLock = signal(doc=
		"""Called to request lock for scratch pad."""
	)

	releaseScratchPadLock = signal(doc=
		"""Called to indicate relinquishment of scratch pad lock."""
	)

	updateScratchPad = signal(doc=
		"""Called to request that the scratchpad be updated."""
	)