Example #1
0
    def __init__(self, parent, title='', msg = '', width=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(title)
        self.setPalette(white_palette)

        sizer = QVBoxLayout()
        self.setLayout(sizer)

        texte = QTextEdit(self)
        texte.setPlainText(msg)
        texte.setMinimumHeight(500)
        texte.setReadOnly(True)
        if width is None:
            texte.setLineWrapMode(QTextEdit.NoWrap)
            doc = texte.document()
            width = doc.idealWidth() + 4*doc.documentMargin()
        texte.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        texte.setMinimumWidth(width)
        sizer.addWidget(texte)

        boutons = QHBoxLayout()
        boutons.addStretch()
        ok = QPushButton('OK', clicked=self.close)
        boutons.addWidget(ok)
        boutons.addStretch()
        sizer.addLayout(boutons)
Example #2
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.parent = parent

        sizer = QVBoxLayout()

        texte = QTextEdit(self)
        with open(path2("%/wxgeometrie/doc/license.txt"), "r") as f:
            msg = f.read().decode("utf8")
        texte.setPlainText(msg)
        texte.setMinimumHeight(500)
        texte.setReadOnly(True)
        texte.setLineWrapMode(QTextEdit.NoWrap)
        doc = texte.document()
        width = doc.idealWidth() + 4 * doc.documentMargin()
        texte.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        texte.setMinimumWidth(width)
        sizer.addWidget(texte)
        self.setLayout(sizer)
Example #3
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.parent = parent

        sizer = QVBoxLayout()

        texte = QTextEdit(self)
        with open(path2("%/wxgeometrie/doc/changelog.txt"), "r") as f:
            msg = f.read().decode("utf8").replace("\n", "<br>")
        titre = u"<b>Changements apportés par la version %s :</b>" % param.version
        msg = "<br>".join((titre, "", msg))
        texte.setHtml(msg)
        texte.setMinimumHeight(500)
        texte.setReadOnly(True)
        texte.setLineWrapMode(QTextEdit.NoWrap)
        doc = texte.document()
        width = doc.idealWidth() + 4 * doc.documentMargin()
        texte.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        texte.setMinimumWidth(width)
        sizer.addWidget(texte)
        self.setLayout(sizer)
class MembersWidget(QWidget):
    def __init__(self, parent, logger):
        super(MembersWidget, self).__init__(parent)

        self.logger = logger
        layout = QVBoxLayout(self)
        layout.setSpacing(0)

        self.dropdown_members_dict = {}
        self.dropdown_members_model = DropdownModel(get_peers(), self.logger)
        self.dropdown_members = QComboBox(self)
        self.dropdown_members.setModel(self.dropdown_members_model)

        topLayout = QHBoxLayout()
        topLayout.setSpacing(10)
        topLayout.addWidget(self.dropdown_members, 1)
        self.requestLogsButton = QPushButton("Request Logfiles", self)
        topLayout.addWidget(self.requestLogsButton)
        layout.addLayout(topLayout)

        layout.addWidget(QLabel("Member Information:", self))
        self.memberInformationTable = QTreeWidget(self)
        self.memberInformationTable.setMaximumHeight(65)
        self.memberInformationTable.setSelectionMode(QTreeWidget.NoSelection)
        layout.addWidget(self.memberInformationTable, 0)

        layout.addWidget(QLabel("Send Message:", self))

        sendMessageLayout = QHBoxLayout()
        sendMessageLayout.setSpacing(10)
        messageInput = HistoryLineEdit(self, "Enter a message")
        self.sendMessageButton = QPushButton("Send", self)
        sendMessageLayout.addWidget(messageInput, 1)
        sendMessageLayout.addWidget(self.sendMessageButton)
        layout.addLayout(sendMessageLayout)

        layout.addWidget(QLabel("Log files:", self))
        logSplitter = QSplitter(Qt.Horizontal, self)

        logListWidget = QWidget(self)
        logListLayout = QVBoxLayout(logListWidget)
        logListLayout.setContentsMargins(0, 0, 0, 0)

        self.log_tree_view = QTreeWidget(logSplitter)
        self.log_tree_view.setAlternatingRowColors(True)
        self.log_tree_view.setColumnCount(1)
        self.log_tree_view.setHeaderHidden(True)
        self.log_tree_view.setItemsExpandable(False)
        self.log_tree_view.setIndentation(0)

        logListLayout.addWidget(self.log_tree_view, 1)

        logListBottomLayout = QHBoxLayout()
        self.logSizeLabel = QLabel(logListWidget)
        logListBottomLayout.addWidget(self.logSizeLabel, 1)

        self.clearLogsButton = QPushButton("Clear", logListWidget)
        self.clearLogsButton.setEnabled(False)
        self.clearLogsButton.clicked.connect(self.clearLogs)
        logListBottomLayout.addWidget(self.clearLogsButton, 0)

        logListLayout.addLayout(logListBottomLayout)

        logSplitter.addWidget(logListWidget)

        self.log_area = QTextEdit(logListWidget)
        self.log_area.setLineWrapMode(QTextEdit.WidgetWidth)
        self.log_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.log_area.setReadOnly(True)
        logSplitter.addWidget(self.log_area)

        logSplitter.setStretchFactor(0, 0)
        logSplitter.setStretchFactor(1, 1)

        layout.addWidget(logSplitter, 1)

        self.memberSelectionChanged()
        self.log_tree_view.selectionModel().selectionChanged.connect(self.displaySelectedLogfile)
        self.dropdown_members.currentIndexChanged.connect(self.memberSelectionChanged)
        self.requestLogsButton.clicked.connect(self.requestLogClicked)
        self.sendMessageButton.clicked.connect(partial(self.sendMessageToMember, messageInput))
        messageInput.returnPressed.connect(partial(self.sendMessageToMember, messageInput))

        get_notification_center().connectPeerAppended(self.dropdown_members_model.externalRowAppended)
        get_notification_center().connectPeerUpdated(self.dropdown_members_model.externalRowUpdated)
        get_notification_center().connectPeerRemoved(self.dropdown_members_model.externalRowRemoved)
        get_notification_center().connectPeerUpdated(self.updateMemberInformation)

    def destroy_widget(self):
        get_notification_center().disconnectPeerAppended(self.dropdown_members_model.externalRowAppended)
        get_notification_center().disconnectPeerUpdated(self.dropdown_members_model.externalRowUpdated)
        get_notification_center().disconnectPeerRemoved(self.dropdown_members_model.externalRowRemoved)
        get_notification_center().disconnectPeerUpdated(self.updateMemberInformation)

    def listLogfiles(self, basePath, sort=None):
        if sort is None:
            sort = lambda aFile: -self.getLogNumber(aFile)
        logList = [
            os.path.join(basePath, aFile)
            for aFile in os.listdir(basePath)
            if aFile.endswith(".log") and not os.path.isdir(os.path.join(basePath, aFile))
        ]
        return sorted(logList, key=sort)

    def getNumLogsToKeep(self, oldLogFiles, newLogFiles, logOffset):
        oldestNew = None
        for aLogFile in newLogFiles:
            oldestNew, _ = self.getLogDates(aLogFile)
            if oldestNew != None:
                break

        if oldestNew == None:
            # new new log file contains timestamps (they are probably all empty)
            return len(oldLogFiles)

        numToKeep = 0
        while numToKeep < len(oldLogFiles) - logOffset:
            curTime, _ = self.getLogDates(oldLogFiles[numToKeep])
            if curTime == None or curTime < oldestNew:
                # keep empty log files
                numToKeep = numToKeep + 1
            else:
                break
        return numToKeep

    def getLogDates(self, aLogFile):
        with codecs.open(aLogFile, "rb", "utf-8") as logContent:
            logLines = logContent.readlines()
            firstDate = None
            for aLine in logLines:
                firstDate = getLogLineTime(aLine)
                if firstDate != None:
                    break

            lastDate = None
            for aLine in reversed(logLines):
                lastDate = getLogLineTime(aLine)
                if lastDate != None:
                    break

            return firstDate, lastDate

    def getLogNumber(self, aLogFile):
        aLogFile = os.path.basename(aLogFile)
        try:
            return int(aLogFile[: aLogFile.rfind(".")])
        except:
            return -1

    def shiftLogFiles(self, oldLogFiles, numToKeep, shift, logOffset):
        renamedLogfiles = []
        for index, aFile in enumerate(oldLogFiles):
            logNum = self.getLogNumber(aFile)
            if logNum < logOffset:
                # don't touch up-to-date logs
                break
            if index < numToKeep:
                newName = os.path.join(os.path.dirname(aFile), "%d.log" % (logNum + shift))
                renamedLogfiles.append((len(oldLogFiles) - index - 1, aFile, newName))
                os.rename(aFile, newName)
            else:
                os.remove(aFile)
        return renamedLogfiles

    def handleNewLogFiles(self, basePath, tmpPath, logOffset=0):
        oldLogFiles = self.listLogfiles(basePath)
        newLogFiles = self.listLogfiles(tmpPath)

        # check how many log files are actually new
        numToKeep = self.getNumLogsToKeep(oldLogFiles, newLogFiles, logOffset)

        # rename / remove old log files to make room for the new ones
        numNew = len(newLogFiles) - (len(oldLogFiles) - logOffset - numToKeep)
        renamedLogfiles = self.shiftLogFiles(oldLogFiles, numToKeep, numNew, logOffset)

        # move new log files
        addedLogfiles = []
        for index, aLogFile in enumerate(reversed(newLogFiles)):
            shutil.move(aLogFile, basePath)
            if index < numNew:
                addedLogfiles.append((index + logOffset, os.path.join(basePath, os.path.basename(aLogFile))))
        shutil.rmtree(tmpPath, True)

        return numNew, addedLogfiles, renamedLogfiles

    def requestFinished(self):
        self.requestLogsButton.setEnabled(True)
        self.dropdown_members.setEnabled(True)

    @loggingSlot(QThread, object)
    def cb_log_transfer_success(self, thread, path):
        path = convert_string(path)

        basePath = os.path.dirname(path)
        tmpPath = os.path.join(basePath, "tmp")
        if not os.path.exists(tmpPath):
            os.makedirs(tmpPath)

        logsAdded = []
        if path.endswith(".tgz"):
            # extract received log files
            with contextlib.closing(tarfile.open(path, "r:gz")) as tarContent:
                tarContent.extractall(tmpPath)
            _, logsAdded, logsRenamed = self.handleNewLogFiles(basePath, tmpPath)
            self.requestFinished()
        else:
            # log comes from old version
            logNum = 0
            if thread.sender in self.logRequests:
                logNum, requestTime = self.logRequests[thread.sender]
                now = datetime.now()
                td = now - requestTime
                tdSeconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 6
                if tdSeconds > self.LOG_REQUEST_TIMEOUT:
                    # request timed out or was finished already
                    logNum = 0

            shutil.move(path, os.path.join(tmpPath, "%d.log" % logNum))

            numNew, logsAdded, logsRenamed = self.handleNewLogFiles(basePath, tmpPath, logNum)
            if numNew > 0 and logNum < 9:
                # there might be more new ones
                self.logRequests[thread.sender] = (logNum + 1, datetime.now())
                self.logger.debug("log seems to be new, another!!!")
                logsAdded.append((logNum + 1, None))
                self.request_log(thread.sender, logNum + 1)
            elif thread.sender in self.logRequests:
                # request finished
                del self.logRequests[thread.sender]
                self.requestFinished()
            else:
                self.requestFinished()

        if len(logsAdded) > 0 or len(logsRenamed) > 0:
            self.updateLogList(logsAdded, logsRenamed)

    @loggingSlot(QThread, object)
    def cb_log_transfer_error(self, _thread, message):
        if not self.isVisible():
            return False
        self.log_area.setText("Error while getting log (%s)" % message)
        self.requestFinished()

    def get_selected_log_member(self):
        member = convert_string(self.dropdown_members.currentText())
        if not member:
            return None

        if "(" in member:
            # member contains name, extract ID
            member = member[member.rfind("(") + 1 : member.rfind(")")]

        return member

    def request_log(self, member=None, logNum=0):
        if member == None:
            member = self.get_selected_log_member()
        if member != None:
            self.logger.debug("Requesting log %d from %s", logNum, member)
            get_server().call(
                "HELO_REQUEST_LOGFILE %s %d" % (DataReceiverThread.getOpenPort(category="log%s" % member), logNum),
                set([member]),
            )
        else:
            self.log_area.setText("No Member selected!")

    @loggingSlot()
    def requestLogClicked(self):
        self.requestLogsButton.setEnabled(False)
        self.dropdown_members.setEnabled(False)
        self.updateLogList([(0, None)])
        self.request_log()

    def listLogFilesForMember(self, member):
        if member is None:
            return []
        logDir = os.path.join(get_settings().get_main_config_dir(), "logs", member)
        if not os.path.exists(logDir):
            return []
        return self.listLogfiles(logDir)

    def numLogFilesForMember(self, member):
        return len(self.listLogFilesForMember(member))

    def requestTimedOut(self, item):
        if not sip.isdeleted(item) and item != None and item.data(0, Qt.UserRole) == None:
            self.log_tree_view.takeTopLevelItem(self.log_tree_view.indexFromItem(item).row())
            self.requestFinished()

    def formatFileSize(self, num):
        for x in ["Bytes", "KB", "MB", "GB", "TB"]:
            if num < 1024.0:
                return "%3.1f %s" % (num, x)
            num /= 1024.0

    def initializeLogItem(self, item, logFile):
        firstDate, lastDate = self.getLogDates(logFile)
        text = None
        tooltip = None
        if firstDate != None:
            text = firstDate.strftime("%Y-%m-%d %H:%M:%S")
            tooltip = u"File: %s\nFirst entry: %s\nLast entry: %s" % (
                logFile,
                firstDate.strftime("%Y-%m-%d %H:%M:%S"),
                lastDate.strftime("%Y-%m-%d %H:%M:%S"),
            )
        else:
            timestamp = datetime.fromtimestamp(os.path.getmtime(logFile)).strftime("%Y-%m-%d %H:%M:%S")
            text = u"%s" % os.path.basename(logFile)
            tooltip = u"File:%s\nModification Date: %s" % (logFile, timestamp)
        text = text + "\n%s" % self.formatFileSize(os.path.getsize(logFile))
        if tooltip != None:
            item.setData(0, Qt.ToolTipRole, QVariant(tooltip))
        item.setData(0, Qt.UserRole, logFile)
        item.setData(0, Qt.DisplayRole, QVariant(text))

    @loggingSlot()
    def clearLogs(self):
        for aLogFile in self.listLogFilesForMember(self.get_selected_log_member()):
            os.remove(aLogFile)
        self.updateLogList()

    def updateLogList(self, logsAdded=None, logsRenamed=None):
        selectedMember = self.get_selected_log_member()

        if logsAdded == None:
            self.log_tree_view.clear()
            logsAdded = []
            for index, logFile in enumerate(reversed(self.listLogFilesForMember(selectedMember))):
                logsAdded.append((index, logFile))
            if len(logsAdded) == 0:
                self.log_tree_view.clear()
                self.log_tree_view.addTopLevelItem(
                    QTreeWidgetItem(self.log_tree_view, QStringList("No logs available."))
                )
                self.log_tree_view.setSelectionMode(QTreeWidget.NoSelection)
                self.logSizeLabel.setText("No logs")
                self.clearLogsButton.setEnabled(False)
                return

        if logsRenamed != None:
            for index, oldName, newName in logsRenamed:
                # index + 1 because of the "requesting" item
                item = self.log_tree_view.topLevelItem(index + 1)
                if item != None:
                    itemLogFile = convert_string(item.data(0, Qt.UserRole).toString())
                    if itemLogFile != oldName:
                        self.logger.warning(
                            "index does not correspond to item in list:\n\t%s\n\t%s", itemLogFile, oldName
                        )
                    self.initializeLogItem(item, newName)

        if len(logsAdded) == 0:
            self.log_tree_view.takeTopLevelItem(0)
        else:
            for index, logFile in logsAdded:
                oldItem = self.log_tree_view.topLevelItem(index)
                item = None
                if oldItem != None and oldItem.data(0, Qt.UserRole) == None:
                    # requested item has been received
                    item = oldItem
                else:
                    item = QTreeWidgetItem()
                    oldItem = None

                if logFile == None:
                    item.setData(0, Qt.DisplayRole, QVariant("Requesting..."))
                    QTimer.singleShot(6000, partial(self.requestTimedOut, item))
                else:
                    self.initializeLogItem(item, logFile)

                if oldItem == None:
                    # else, the old item is being modified
                    self.log_tree_view.insertTopLevelItem(index, item)
                self.log_tree_view.setSelectionMode(QTreeWidget.SingleSelection)

        totalSize = 0
        for aLogFile in self.listLogFilesForMember(selectedMember):
            totalSize += os.path.getsize(aLogFile)

        self.logSizeLabel.setText("%s consumed" % self.formatFileSize(totalSize))
        self.clearLogsButton.setEnabled(True)
        # self.displaySelectedLogfile()

    def getSelectedLogContent(self):
        member = self.get_selected_log_member()
        if member == None:
            return "No Log selected."
        selection = self.log_tree_view.selectedIndexes()
        if len(selection) is 0:
            return "No Log selected."

        logPath = convert_string(selection[0].data(Qt.UserRole).toString())
        if logPath == None:
            return "ERROR: path is None"
        if not os.path.exists(logPath):
            return "File not found: " + logPath

        fcontent = ""
        try:
            with codecs.open(logPath, "r", "utf8") as fhandler:
                fcontent = fhandler.read()
        except Exception as e:
            self.logger.exception("Error reading file")
            fcontent = "Error reading file: %s" % str(e)
        return fcontent

    @loggingSlot(QItemSelection, QItemSelection)
    def displaySelectedLogfile(self, _new, _old):
        self.log_area.setText(self.getSelectedLogContent())

    @loggingSlot(int)
    def memberSelectionChanged(self, _new=None):
        self.updateLogList()
        isMemberSelected = self.get_selected_log_member() != None
        self.sendMessageButton.setEnabled(isMemberSelected)
        self.requestLogsButton.setEnabled(isMemberSelected)
        self.updateMemberInformation()

    @loggingSlot(object)
    def sendMessageToMember(self, lineEdit):
        selectedMember = self.get_selected_log_member()
        if selectedMember != None:
            get_server().call(convert_string(lineEdit.text()), set([selectedMember]))
            lineEdit.clear()

    @loggingSlot(object, object)
    def updateMemberInformation(self, peerID=None, peerInfo=None):
        if peerID != None and peerID != self.get_selected_log_member():
            # only update if selected member updated
            return

        self.memberInformationTable.clear()

        if self.get_selected_log_member() == None:
            self.memberInformationTable.setColumnCount(0)
            self.memberInformationTable.setHeaderLabel("No member selected.")
            return

        if peerInfo == None:
            peerInfo = get_peers().getPeerInfo(pID=self.get_selected_log_member())

        if peerInfo == None:
            self.memberInformationTable.setColumnCount(0)
            self.memberInformationTable.setHeaderLabel("No member information available.")
            return

        self.memberInformationTable.setColumnCount(len(peerInfo))
        headers = sorted(peerInfo.keys(), key=lambda s: s.lower())
        self.memberInformationTable.setHeaderLabels(QStringList(headers))
        item = QTreeWidgetItem(self.memberInformationTable)
        for col, header in enumerate(headers):
            item.setData(col, Qt.DisplayRole, QVariant(peerInfo[header]))
        for col in range(self.memberInformationTable.columnCount()):
            self.memberInformationTable.resizeColumnToContents(col)
Example #5
0
class Ui_RightWidget(object):
    def setupUi(self, RightWidget, server):
        RightWidget.setMinimumHeight(500)

        main_layout = QVBoxLayout(RightWidget)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(10)

        # We hide all the main elements, to allow the proper viewer to enable
        # (only) the elements that uses.

        if hasattr(server, 'wild_chars'):
            self.text_map = QTextEdit()
            self.text_map.setObjectName('text_map')
            self.text_map.setVisible(False)
            self.text_map.setFocusPolicy(Qt.NoFocus)
            self.text_map.setAutoFillBackground(True)
            self.text_map.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.text_map.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.text_map.setUndoRedoEnabled(False)
            self.text_map.setReadOnly(True)
            # for some unknown reason, the fontmetrics of the text map is wrong
            # if the font is set with a global stylesheet, so we set it on the
            # specific widget.
            self.text_map.setStyleSheet("QTextEdit { font: 13px \"Courier\";}")
            main_layout.addWidget(self.text_map)

            # We calculate the map area size using the size of the font used. We
            # assume that the font is a monospace ones.
            font_metrics = self.text_map.fontMetrics()
            self.text_map.setFixedWidth(font_metrics.width('#' * server.map_width))
            self.text_map.setFixedHeight(font_metrics.height() * server.map_height)

            # The rightwidget width is determined by the map area size
            RightWidget.setMinimumWidth(self.text_map.width())
        else:
            RightWidget.setMinimumWidth(220)

        self.box_status = QWidget()
        self.box_status.setVisible(False)
        main_layout.addWidget(self.box_status)

        status_layout = QGridLayout(self.box_status)
        status_layout.setContentsMargins(5, 5, 5, 0)
        status_layout.setHorizontalSpacing(0)
        status_layout.setVerticalSpacing(15)

        label_health = QLabel()
        label_health.setMinimumWidth(80)
        label_health.setText(QApplication.translate("RightWidget", "Health"))
        status_layout.addWidget(label_health, 0, 0)

        self.bar_health = QProgressBar()
        self.bar_health.setObjectName("bar_health")
        self.bar_health.setFixedHeight(22)
        self.bar_health.setProperty("value", QVariant(100))
        self.bar_health.setTextVisible(False)
        status_layout.addWidget(self.bar_health, 0, 1)

        label_mana = QLabel()
        label_mana.setMinimumWidth(80)
        label_mana.setText(QApplication.translate("RightWidget", "Mana"))
        status_layout.addWidget(label_mana, 1, 0)

        self.bar_mana = QProgressBar()
        self.bar_mana.setObjectName("bar_mana")
        self.bar_mana.setFixedHeight(22)
        self.bar_mana.setProperty("value", QVariant(100))
        self.bar_mana.setTextVisible(False)
        status_layout.addWidget(self.bar_mana, 1, 1)

        label_movement = QLabel()
        label_movement.setMinimumWidth(80)
        label_movement.setText(QApplication.translate("RightWidget", "Movement"))
        status_layout.addWidget(label_movement, 2, 0)

        self.bar_movement = QProgressBar()
        self.bar_movement.setObjectName("bar_movement")
        self.bar_movement.setFixedHeight(22)
        self.bar_movement.setProperty("value", QVariant(100))
        self.bar_movement.setTextVisible(False)
        status_layout.addWidget(self.bar_movement, 2, 1)

        main_layout.addStretch()
Example #6
0
class Ui_dev_client(object):
    def setupUi(self, dev_client):
        dev_client.resize(935, 660)
        dev_client.setWindowTitle(QApplication.translate("dev_client", "DevClient"))

        self.centralwidget = QWidget(dev_client)
        dev_client.setCentralWidget(self.centralwidget)

        main_layout = QGridLayout(self.centralwidget)
        main_layout.setContentsMargins(5, 5, 5, 3)
        main_layout.setSpacing(3)
        main_layout.setColumnStretch(0, 1)
        main_layout.setRowStretch(1, 1)

        top_layout = QHBoxLayout()
        top_layout.setContentsMargins(0, 0, 0, 0)
        top_layout.setSpacing(5)

        top_label_conn = QLabel()
        top_label_conn.setText(QApplication.translate("dev_client", "Connection"))
        top_layout.addWidget(top_label_conn)

        self.list_conn = QComboBox()
        self.list_conn.setFixedSize(145, 26)
        self.list_conn.setFocusPolicy(Qt.NoFocus)
        top_layout.addWidget(self.list_conn)

        self.list_account = QComboBox()
        self.list_account.setFixedSize(145, 26)
        self.list_account.setFocusPolicy(Qt.NoFocus)
        top_layout.addWidget(self.list_account)

        top_layout.addItem(QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
        top_label_account = QLabel()
        top_label_account.setText(QApplication.translate("dev_client", "Account"))
        top_layout.addWidget(top_label_account)

        self.button_connect = QPushButton()
        self.button_connect.setFixedSize(105, 26)
        self.button_connect.setFocusPolicy(Qt.NoFocus)
        self.button_connect.setIcon(QIcon(":/images/connect.png"))
        self.button_connect.setIconSize(QSize(16, 16))
        self.button_connect.setText(QApplication.translate("dev_client", "Connect"))
        top_layout.addWidget(self.button_connect)

        self.button_option = QPushButton()
        self.button_option.setFixedSize(105, 26)
        self.button_option.setFocusPolicy(Qt.NoFocus)
        self.button_option.setIcon(QIcon(":/images/option.png"))
        self.button_option.setIconSize(QSize(16, 16))
        self.button_option.setText(QApplication.translate("dev_client", "Option"))
        top_layout.addWidget(self.button_option)
        main_layout.addLayout(top_layout, 0, 0)

        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.addItem(QSpacerItem(40, 29, QSizePolicy.Minimum, QSizePolicy.Fixed))

        self.rightpanel = QWidget()
        self.rightpanel.setMinimumWidth(225)
        right_layout.addWidget(self.rightpanel)
        main_layout.addLayout(right_layout, 0, 1, 3, 1)

        self.output_splitter = QSplitter(self.centralwidget)
        self.output_splitter.setOrientation(Qt.Vertical)
        self.output_splitter.setHandleWidth(3)
        self.output_splitter.setChildrenCollapsible(False)

        self.text_output = QTextEdit(self.output_splitter)
        self.text_output.setMinimumWidth(690)
        self.text_output.setFocusPolicy(Qt.NoFocus)
        self.text_output.setAutoFillBackground(True)
        self.text_output.setUndoRedoEnabled(False)
        self.text_output.setReadOnly(True)

        self.text_output_noscroll = QTextEdit(self.output_splitter)
        self.text_output_noscroll.setMinimumWidth(690)
        self.text_output_noscroll.setFocusPolicy(Qt.NoFocus)
        self.text_output_noscroll.setAutoFillBackground(True)
        self.text_output_noscroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.text_output_noscroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.text_output_noscroll.setUndoRedoEnabled(False)
        self.text_output_noscroll.setReadOnly(True)
        main_layout.addWidget(self.output_splitter, 1, 0)

        bottom_layout = QHBoxLayout()
        bottom_layout.setContentsMargins(0, 0, 0, 0)
        bottom_layout.setSpacing(5)

        self.text_input = QComboBox()
        self.text_input.setMinimumWidth(660)
        self.text_input.setFixedHeight(25)
        self.text_input.setEditable(True)
        self.text_input.addItem("")
        bottom_layout.addWidget(self.text_input)

        self.toggle_splitter = QPushButton()
        self.toggle_splitter.setFixedSize(25, 25)
        self.toggle_splitter.setFocusPolicy(Qt.NoFocus)
        self.toggle_splitter.setIcon(QIcon(":/images/split-window.png"))
        bottom_layout.addWidget(self.toggle_splitter)
        main_layout.addLayout(bottom_layout, 2, 0)