示例#1
0
class HiveMasterWindow(qtgui.QMainWindow, AbstractBeeMaster):
    # this constructor should never be called directly, use an alternate
    def __init__(self):
        qtgui.QMainWindow.__init__(self)
        AbstractBeeMaster.__init__(self)

        # set defaults
        settings = qtcore.QSettings("BeeDraw", "Hive")

        self.config["port"], ok = settings.value("port", 8333).toInt()
        self.config["width"], ok = settings.value("width", 600).toInt()
        self.config["height"], ok = settings.value("height", 400).toInt()
        self.config["networkhistorysize"], ok = settings.value("networkhistorysize", 20).toInt()
        self.config["password"] = settings.value("password").toString()
        self.config["autolog"] = False

        # Initialize values
        self.nextclientid = 1
        self.nextclientidmutex = qtcore.QMutex()

        self.passwordlock = qtcore.QReadWriteLock()

        # setup interface
        self.ui = Ui_HiveMasterSpec()
        self.ui.setupUi(self)
        self.show()

        # setup queues used for all thread communication
        self.routinginput = Queue(0)
        self.routingthread = HiveRoutingThread(self)
        self.routingthread.start()

        # this will be keyed on the client ids and values will be queue objects
        self.clientwriterqueues = {}
        self.socketsmap = {}

        self.readerthreads = {}
        self.writerthreads = {}

        # this dictionary will be keyed on id and map to the username
        self.clientnames = {}

        # set up client list mutex for messing with either of the above 2 dictinoaries
        self.clientslistmutex = qtcore.QReadWriteLock()

        # default value stuff that needs to be here
        self.fgcolor = qtgui.QColor(0, 0, 0)
        self.bgcolor = qtgui.QColor(255, 255, 255)

        # drawing window which holds the current state of the network session
        self.curwindow = None
        self.serverthread = None

        # restore window position
        self.restoreGeometry(settings.value("geometry").toByteArray())
        self.restoreState(settings.value("windowState").toByteArray())

    def getHistorySize(self):
        return self.config["networkhistorysize"]

        # since there should only be one window just return 1

    def getNextWindowId(self):
        return 1

    def getWindowById(self, id):
        return self.curwindow

    def getToolClassByName(self, name):
        return self.toolbox.getToolDescByName(name)

    def registerReaderThread(self, id, thread):
        lock = qtcore.QWriteLocker(self.clientslistmutex)
        self.readerthreads[id] = thread

    def registerWriterThread(self, id, thread):
        lock = qtcore.QWriteLocker(self.clientslistmutex)
        self.writerthreads[id] = thread

    def registerClient(self, username, id, socket):
        lock = qtcore.QWriteLocker(self.clientslistmutex)

        for name in self.clientnames.values():
            if name == username:
                return False

        self.clientwriterqueues[id] = Queue(100)
        self.clientnames[id] = username
        self.ui.clientsList.addItem(username)
        self.socketsmap[id] = socket

        command = (DrawingCommandTypes.networkcontrol, NetworkControlCommandTypes.resyncrequest)
        self.curwindow.addResyncRequestToQueue(id)

        return True

    def unregisterClient(self, id):
        # print_debug("unregistering client: %d" % id)
        lock = qtcore.QWriteLocker(self.clientslistmutex)
        if not id in self.clientnames:
            return

            # remove from dictionary of clients
        username = self.clientnames[id]
        del self.clientnames[id]

        if id in self.writerthreads:
            del self.writerthreads[id]

        if id in self.readerthreads:
            del self.readerthreads[id]

            # remove from list of outgoing queues
        del self.clientwriterqueues[id]

        # remove from gui
        items = self.ui.clientsList.findItems(username, qtcore.Qt.MatchFixedString)
        for item in items:
            index = self.ui.clientsList.row(item)
            self.ui.clientsList.takeItem(index)

            # set layers owned by that client to unowned
        lock = qtcore.QWriteLocker(self.curwindow.layerslistlock)
        for layer in self.curwindow.layers:
            if layer.owner == id:
                # print_debug("setting layer %d to unowned" % layer.key)
                self.curwindow.addGiveUpLayerToQueue(layer.key, id)

        del self.socketsmap[id]

    def closeEvent(self, event):
        if self.serverthread:
            result = qtgui.QMessageBox.question(
                self,
                "Ready to Quit?",
                "Are you sure you'd like to exit the whole application?\nThe currently running server will be terminated.",
                qtgui.QMessageBox.Ok,
                qtgui.QMessageBox.Cancel,
            )
            if result != qtgui.QMessageBox.Ok:
                event.ignore()
                return

        settings = qtcore.QSettings("BeeDraw", "Hive")
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("windowState", self.saveState())

        qtgui.QMainWindow.closeEvent(self, event)

    # 		self.stopServer()

    def resetState(self):
        # only do this if the server isn't running
        if not self.serverthread:
            self.curwindow = HiveSessionState(
                self, self.config["width"], self.config["height"], WindowTypes.standaloneserver, 20
            )
            self.curwindow.startRemoteDrawingThreads()

    def startServer(self):
        # make sure the state exists
        if not self.curwindow:
            self.resetState()

            # make sure no other instance is running
        self.stopServer()

        self.serverthread = HiveServerThread(self, self.config["port"], sockettype=BeeSocketTypes.python)
        self.serverthread.start()

    def event(self, event):
        if event.type() == BeeCustomEventTypes.hiveserverstatus:
            if event.status == HiveServerStatusTypes.running:
                self.changeStatusLabel("Serving on port: %d" % self.config["port"])
            elif event.status == HiveServerStatusTypes.starterror:
                if event.errorstring:
                    body = event.errorstring
                else:
                    body = (
                        "Failed to start server on port %d.\nMake sure port is not already in use."
                        % self.config["port"]
                    )
                qtgui.QMessageBox.critical(self, "Could not start server", body)
                self.changeStatusLabel("Failed to start on port %d" % self.config["port"])
            elif event.status == HiveServerStatusTypes.stopped:
                self.changeStatusLabel("Server not running")
                print "changed status to server not running"

        return qtgui.QMainWindow.event(self, event)

    def changeStatusLabel(self, text):
        self.ui.statusLabel.setText(text)

    def stopServer(self):
        if self.serverthread:
            self.serverthread.stopServerThread()
            # self.serverthread.terminate()
            # self.serverthread.quit()
            # self.serverthread.exit()
            # self.serverthread.wait()
            self.serverthread = None
            self.ui.statusLabel.setText("Serving not running")

    def on_kick_button_pressed(self):
        curselection = self.ui.clientsList.selectedIndexes()
        # if there are any items in the list that means that something was selected
        if curselection:
            target = curselection[0].data().toString()
            self.kickClient(target)

    def kickClient(self, name):
        for i in self.clientnames.keys():
            if self.clientnames[i] == name:
                self.socketsmap[i].disconnect()
                self.routinginput.put(((DrawingCommandTypes.quit,), 0 - i))

    def on_actionStart_triggered(self, accept=True):
        if accept:
            self.startServer()

    def on_actionStop_triggered(self, accept=True):
        if accept:
            self.stopServer()

    def getPassword(self):
        lock = qtcore.QReadLocker(self.passwordlock)
        return self.config["password"]

    def setPassword(self, newpass):
        lock = qtcore.QWriteLocker(self.passwordlock)
        self.config["password"] = newpass

    def on_actionOptions_triggered(self, accept=True):
        if not accept:
            return

        dialog = qtgui.QDialog()
        dialog.ui = Ui_HiveOptionsDialog()
        dialog.ui.setupUi(dialog)

        dialog.ui.port_box.setValue(self.config["port"])
        dialog.ui.history_size_box.setValue(self.config["networkhistorysize"])
        dialog.ui.password_entry.setText(self.config["password"])
        dialog.ui.width_box.setValue(self.config["width"])
        dialog.ui.height_box.setValue(self.config["height"])

        ok = dialog.exec_()

        if not ok:
            return

        self.config["port"] = dialog.ui.port_box.value()
        self.config["password"] = str(dialog.ui.password_entry.text())
        self.config["width"] = dialog.ui.width_box.value()
        self.config["height"] = dialog.ui.height_box.value()
        self.config["networkhistorysize"] = dialog.ui.history_size_box.value()

        settings = qtcore.QSettings("BeeDraw", "Hive")

        settings.setValue("port", self.config["port"])
        settings.setValue("password", self.config["password"])
        settings.setValue("width", self.config["width"])
        settings.setValue("height", self.config["height"])
        settings.setValue("networkhistorysize", self.config["networkhistorysize"])
示例#2
0
class HiveMasterWindow(qtgui.QMainWindow):
	# this constructor should never be called directly, use an alternate
	def __init__(self,app):
		qtgui.QMainWindow.__init__(self)
		self.app=app

		# Initialize values
		self.connections=[]
		self.nextclientid=1
		self.nextclientidmutex=qtcore.QMutex()

		self.password=""

		# setup interface
		self.ui=Ui_HiveMasterSpec()
		self.ui.setupUi(self)
		self.show()

		# setup queues used for all thread communication
		self.routinginput=Queue(0)
		self.routingthread=HiveRoutingThread(self)
		self.routingthread.start()

		# this will be keyed on the client ids and values will be queue objects
		self.clientwriterqueues={}

		# this dictionary will be keyed on id and map to the username
		self.clientnames={}

		self.toolbox=BeeToolBox()

		# drawing window which holds the current state of the network session
		self.window=BeeDrawingWindow(self,600,400,False,WindowTypes.standaloneserver)

	def getToolClassByName(self,name):
		self.toolbox.getToolClassByName(name)

	def getCurToolInst(self,window):
		curtool=self.getCurToolDesc()
		return curtool.setupTool(window)

	def getCurToolDesc(self):
		return self.toolbox.getCurToolDesc()

	# alternate constuctor to create a standalone server
	def standAloneServer(app):
		master=HiveMasterWindow(app)
		master.standalonemode=True
		# this serves as both the window and the master
		master.master=master
		master.layers=[]
		
		master.serverthread=None

	standAloneServer=staticmethod(standAloneServer)

	def registerClient(self,username):
		lock=qtcore.QMutexLocker(self.nextclientidmutex)
		newid=self.nextclientid
		self.nextclientid+=1
		lock.unlock()
		self.clientwriterqueues[newid]=Queue(100)
		self.clientnames[newid]=username
		return newid

	def closeEvent(self,event):
		qtgui.QMainWindow.closeEvent(self,event)
#		self.stopServer()

	def startServer(self):
		# make sure no other instance is running

		self.stopServer()
		self.serverthread=HiveServerThread(self)
		print "starting thread:"
		self.serverthread.start()

	def stopServer(self):
		if self.serverthread:
			self.serverthread.terminate()
			self.serverthread.wait()
			self.serverthread=None

	def on_actionStart_triggered(self):
		self.startServer()