Ejemplo n.º 1
0
class ImportDataDlg(QDialog):
    __isJy = False  # 数据校验成功的标志
    __mlist = []  # 定义一个列表用于保存从excel表中取出的数据

    def __init__(self, iface, parent=None, impType=ImpDateType.SITEANDCELL):
        super(ImportDataDlg, self).__init__()
        self.iface = iface
        self.parent = parent
        self.impType = impType
        self.initView()

    def initView(self):
        if self.impType == ImpDateType.SERVINGCELL:
            self.setWindowTitle(u'相邻小区数据导入')
        else:
            self.setWindowTitle(u'基站和小区数据导入')
        self.setWindowIcon(QIcon('images/logo.png'))
        self.resize(620, 480)

        # 数据表格
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(7)
        # 设置当前Table不能编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 初始化表格上下文菜单
        self.initTableContextMenu()
        # 初始化表头
        self.initTableHeader()
        # 导入出错列表
        self.listWidget = QListWidget(self)
        # 按钮组
        impBtn = QPushButton(u"导入EXCEL表", self)
        yzBtn = QPushButton(u"数据检验", self)
        impdateBtn = QPushButton(u"导入数据", self)
        btnVBox = QVBoxLayout()
        btnVBox.addWidget(impBtn)
        btnVBox.addWidget(yzBtn)
        btnVBox.addWidget(impdateBtn)
        # 错误列表与按钮组
        hBox = QHBoxLayout()
        hBox.setMargin(20)
        hBox.addWidget(self.listWidget)
        hBox.addLayout(btnVBox)

        self.mbar = QStatusBar(self)
        self.mbar.showMessage(u'准备就绪...')

        self.maction = QToolBar(self)
        self.editAction = QAction(u'编辑', self.maction)
        self.editAction.setCheckable(True)

        self.combox = QComboBox(self)
        self.combox.addItems(HeadsConfig.ImpExcelName)

        self.maction.addWidget(self.combox)
        self.maction.addAction(self.editAction)

        vBox = QVBoxLayout()
        vBox.addWidget(self.maction)
        vBox.addWidget(self.tableWidget)
        vBox.addLayout(hBox)
        vBox.addWidget(self.mbar)

        vBox.setStretchFactor(self.tableWidget, 9)
        vBox.setStretchFactor(hBox, 5)
        vBox.setStretchFactor(self.mbar, 1)

        self.setLayout(vBox)

        QObject.connect(impBtn, SIGNAL('clicked()'), self.impClick)
        QObject.connect(yzBtn, SIGNAL('clicked()'), self.yzClick)
        QObject.connect(impdateBtn, SIGNAL('clicked()'), self.impdateClick)
        QObject.connect(self.editAction, SIGNAL('triggered()'), self.editClick)
        QObject.connect(self.combox, SIGNAL('currentIndexChanged(int)'),
                        self.comboxChange)

        self.listWidget.doubleClicked.connect(self.mlistClicked)
        # self.connect(self.listWidget, SIGNAL("itemDoubleClicked (QListWidgetItem)"), self.mlistClicked)

    def initTableContextMenu(self):
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.popMenu = QMenu(self.tableWidget)
        delAction = QAction(u'删除', self)  # 删除
        self.popMenu.addAction(delAction)

    # 设置表格可以双击修改数据
    def setEditTriggers(self, isTrigger):
        if isTrigger:
            self.tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked)
        else:
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

    # 提供给外部修改状态栏消息
    def setStatusBarMsg(self, msg):
        self.mbar.showMessage(msg)

    # 选框改变时,清空当前表格的全部内容,包括表格头
    def updateType(self, mtype):
        self.impType = mtype
        self.tableWidget.clear()  # 清空表格所有内容
        self.initTableHeader()

    # 初始化表格的每个Item
    def initTable(self, mlist):
        self.tableWidget.setRowCount(len(mlist))
        for (i, v) in enumerate(mlist):
            for (j, item) in enumerate(v):
                if type(item) != str:
                    item = unicode(item)
                if item == None:
                    item = u""
                tabItem = QTableWidgetItem(item)
                tabItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, j, tabItem)

    # 初始化错误信息列表
    def initListView(self, mlist):

        for iv in mlist:
            lisItm = QListWidgetItem(self.listWidget)
            lisItm.setTextColor(Qt.red)
            lisItm.setData(Qt.UserRole, iv)
            if isinstance(iv, basestring):
                # 如果错误信息是一行字符串
                lisItm.setText(iv)
            else:
                lisItm.setText(u'第' + unicode(str(iv['row'] + 1)) + u'行,第' +
                               unicode(str(iv['col'] + 1)) + u'列:' + iv['msg'])

    # 初始化Table的头
    def initTableHeader(self):
        self.heads = []
        if self.impType == ImpDateType.SITEANDCELL:
            # 获取当前项目图层的字段名
            cell_layer = getLayerByName(u"小区", self.iface)
            for head in HeadsConfig.SiteANDCellHead:
                self.heads.append(head)
            if len(cell_layer.pendingFields()) > 55:
                for (index, field) in enumerate(cell_layer.pendingFields()):
                    if index > 54:
                        field_name = field.name().strip()
                        self.heads.append(field_name)

        else:
            self.heads = HeadsConfig.ServingCellHead

        self.tableWidget.setColumnCount(len(self.heads))  # 设置表格的列数
        for (i, h) in enumerate(self.heads):
            tabItem = QTableWidgetItem(h)
            self.tableWidget.setHorizontalHeaderItem(i, tabItem)

    # 自定义为Table添加Item
    def addTableItem(self, row, col, content):
        tabItem = QTableWidgetItem(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 修改Item的内容
    def editTableItem(self, row, col, content):
        tabItem = self.tableWidget.item(row, col)
        tabItem.setText(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 从Excel表读取数据(导入Excel表)
    def impClick(self):
        fileName = QFileDialog.getOpenFileName(self, u'基站小区数据导入', '/',
                                               'Excel Files (*.xls *.xlsx)')
        if fileName.strip() != "":
            self.setStatusBarMsg(u'选择完毕:' + fileName)
            importData = GetDataFromExcel(fileName, self.impType, self.heads)
            self.__mlist = []
            self.__mlist.extend(importData.getData())
            self.tableWidget.clearContents()
            self.listWidget.clear()
            self.initTable(self.__mlist)
            self.setStatusBarMsg(u'数据导入完成...')
            self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

        else:
            QMessageBox.information(self.parent, u"错误", u"请选中文件")

    # 数据验证按钮点击事件处理
    def yzClick(self):
        if len(self.__mlist) > 0:
            self.erlist = []  # 定义一个列表用于保存数据验证错误的数据
            # 清楚全部的Item
            if self.listWidget.count() > 0:
                self.listWidget.clear()

            # 根据tableWidget更新self.__mlist
            for (r, items) in enumerate(self.__mlist):
                for (v, item) in enumerate(self.__mlist[r]):
                    if self.tableWidget.item(r, v).text() == u"":
                        continue
                    else:
                        # 跟据self.__mlist[r][v]数据类型进行比对
                        if type(self.__mlist[r][v]) == int:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = int(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == float:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = float(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == str:
                            if unicode(self.__mlist[r][v]
                                       ) != self.tableWidget.item(r, v).text():
                                self.__mlist[r][v] = str(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == unicode:
                            if (self.__mlist[r][v]) != self.tableWidget.item(
                                    r, v).text():
                                self.__mlist[r][v] = self.tableWidget.item(
                                    r, v).text()
                        else:
                            print type(self.__mlist[r][v])
            # 执行数据校验函数
            self.erlist = checkDataByDataType(self.__mlist, self.impType)
            if len(self.erlist) > 0:
                self.initListView(self.erlist)
                QMessageBox.information(self.parent, u'数据校验',
                                        u'数据校验失败,请检查数据正确性后,再导入到地图中')
                self.__isJy = False
            else:
                QMessageBox.information(self.parent, u'数据校验', u'数据校验成功,没有错误数据')
                self.__isJy = True
        else:
            QMessageBox.warning(self.parent, u'数据校验', u'请先导入Excel数据后再操作!')

    # 导入数据到地图中
    def impdateClick(self):
        if self.__isJy:  # 如果数据校验成功
            if self.impType == ImpDateType.SITEANDCELL:
                # 导入基站小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSiteAndCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")

            else:
                # 导入相邻小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")
        else:
            QMessageBox.warning(self.parent, u'数据导入', u'请确保校验数据成功后,再导入到地图中')

    # 编辑Action点击事件
    def editClick(self):
        self.setEditTriggers(self.editAction.isChecked())

    # 错误列表双击事件处理
    def mlistClicked(self, listItem):
        itemData = listItem.data(Qt.UserRole)
        self.tableWidget.setFocus()
        self.tableWidget.setCurrentCell(itemData['row'], itemData['col'])

    # 选框改变事件
    def comboxChange(self, index):
        self.updateType(index)

    # 字段验证是否为空
    def __validNull(self, name, col, row, itm, rowitm):
        if itm is None or itm == '':
            tmpMap = {}
            tmpMap['col'] = col
            tmpMap['row'] = row
            tmpMap['msg'] = unicode(name) + u'不能为空'
            tmpMap['item'] = rowitm
            return tmpMap
        else:
            return None

    # 导入数据线程开始信号  绑定函数
    def impStart(self):
        self.setStatusBarMsg(u'准备导入...')

    # 导入数据线程发生异常信号 绑定函数
    def impError(self, e, exception_string):
        self.setStatusBarMsg(u'发生错误:' + unicode(e))
        QMessageBox.warning(self.parent, u'Excel数据导入', u'发生错误:' + unicode(e))

    # 导入数据线程完成信号 绑定函数
    def impFinish(self, mylist):
        self.__mlist = []
        self.__mlist.extend(mylist)
        self.mthread.quit()
        self.mthread.wait()
        self.mthread.deleteLater()
        self.impDateThread.deleteLater()

        self.tableWidget.clearContents()
        self.listWidget.clear()
        self.initTable(self.__mlist)
        self.setStatusBarMsg(u'数据导入完成...')
        self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

    # 导入数据到地图线程发生异常信号 绑定函数
    def impError1(self, e, exception_string):
        self.setStatusBarMsg(u"导入数据发生错误")
        QMessageBox.critical(self, u'数据导入', u"发生错误:" + unicode(e))

    # 导入数据到地图线程完成信号 绑定函数
    def impFinish1(self, mylist):
        self.threadImp.quit()
        self.threadImp.wait()
        self.threadImp.deleteLater()
        self.impFeatureThread.deleteLater()
        remsg = u'数据导入完成!'
        layer = None
        if self.impType == LayerType.SITE:
            # remsg = u'基站' + remsg
            layer = getLayerByName(u'基站', self.iface)
        elif self.impType == LayerType.CELL:
            # remsg = u'小区' + remsg
            layer = getLayerByName(u'小区', self.iface)
        else:
            remsg = u'相邻小区' + remsg
            layer = getLayerByName(u'相邻小区', self.iface)
        self.setStatusBarMsg(remsg)
        layer.updateExtents()  # 更新地图数据
        self.iface.actionDraw().trigger()
        QMessageBox.information(self, u'数据导入', remsg)

        merlist = []
        for eritm in self.erlist:
            merlist.append(eritm['item'])
        self.tableWidget.clearContents()  # 先清楚表格的内容,再将错误的行显示到表格中
        self.initTable(merlist)
Ejemplo n.º 2
0
class Main(plugin.Plugin):
    " Main Class "

    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.scriptPath, self.scriptArgs = "", []
        self.profilerPath, self.tempPath = profilerPath, tempPath
        self.output = " ERROR: FAIL: No output ! "

        self.process = QProcess()
        self.process.finished.connect(self.on_process_finished)
        self.process.error.connect(self.on_process_error)

        self.tabWidget, self.stat = QTabWidget(), QWidget()
        self.tabWidget.tabCloseRequested.connect(
            lambda: self.tabWidget.setTabPosition(1) if self.tabWidget.
            tabPosition() == 0 else self.tabWidget.setTabPosition(0))
        self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}')
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.vboxlayout1 = QVBoxLayout(self.stat)
        self.hboxlayout1 = QHBoxLayout()
        self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat)
        self.hboxlayout1.addWidget(self.filterTableLabel)
        self.filterTableLineEdit = QLineEdit(self.stat)
        self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ')
        self.hboxlayout1.addWidget(self.filterTableLineEdit)
        self.filterHintTableLabel = QLabel(" ? ", self.stat)
        self.hboxlayout1.addWidget(self.filterHintTableLabel)
        self.vboxlayout1.addLayout(self.hboxlayout1)
        self.tableWidget = QTableWidget(self.stat)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setColumnCount(8)
        self.tableWidget.setRowCount(2)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(7, item)
        self.tableWidget.itemDoubleClicked.connect(
            self.on_tableWidget_itemDoubleClicked)
        self.vboxlayout1.addWidget(self.tableWidget)
        self.tabWidget.addTab(self.stat, " ? ")

        self.source = QWidget()
        self.gridlayout = QGridLayout(self.source)
        self.scintillaWarningLabel = QLabel(
            "QScintilla is not installed!. Falling back to basic text edit!.",
            self.source)
        self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2)
        self.sourceTreeWidget = QTreeWidget(self.source)
        self.sourceTreeWidget.setAlternatingRowColors(True)
        self.sourceTreeWidget.itemActivated.connect(
            self.on_sourceTreeWidget_itemActivated)
        self.sourceTreeWidget.itemClicked.connect(
            self.on_sourceTreeWidget_itemClicked)
        self.sourceTreeWidget.itemDoubleClicked.connect(
            self.on_sourceTreeWidget_itemClicked)

        self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1)
        self.sourceTextEdit = QTextEdit(self.source)
        self.sourceTextEdit.setReadOnly(True)
        self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1)
        self.tabWidget.addTab(self.source, " ? ")

        self.result = QWidget()
        self.vlayout = QVBoxLayout(self.result)
        self.globalStatGroupBox = QGroupBox(self.result)
        self.hboxlayout = QHBoxLayout(self.globalStatGroupBox)
        self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.totalTimeLcdNumber.setNumDigits(7)
        self.totalTimeLcdNumber.display(1000000)
        self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.totalTimeLcdNumber)
        self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>",
                                 self.globalStatGroupBox)
        self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.tTimeLabel)
        self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.numCallLcdNumber.setNumDigits(7)
        self.numCallLcdNumber.display(1000000)
        self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.numCallLcdNumber)
        self.numCallLabel = QLabel("<b>Number of calls</b>",
                                   self.globalStatGroupBox)
        self.numCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.numCallLabel)
        self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.primCallLcdNumber.setNumDigits(7)
        self.primCallLcdNumber.display(1000000)
        self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.primCallLcdNumber)
        self.primCallLabel = QLabel("<b>Primitive calls (%)</b>",
                                    self.globalStatGroupBox)
        self.primCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.primCallLabel)
        self.vlayout.addWidget(self.globalStatGroupBox)
        try:
            from PyKDE4.kdeui import KRatingWidget
            self.rating = KRatingWidget(self.globalStatGroupBox)
            self.rating.setToolTip('Profiling Performance Rating')
        except ImportError:
            pass
        self.tabWidget.addTab(self.result, " Get Results ! ")

        self.resgraph = QWidget()
        self.vlayout2 = QVBoxLayout(self.result)
        self.graphz = QGroupBox(self.resgraph)
        self.hboxlayout2 = QHBoxLayout(self.graphz)
        try:
            from PyKDE4.kdeui import KLed
            KLed(self.graphz)
        except ImportError:
            pass
        self.hboxlayout2.addWidget(
            QLabel('''
            Work in Progress  :)  Not Ready Yet'''))
        self.vlayout2.addWidget(self.graphz)
        self.tabWidget.addTab(self.resgraph, " Graphs and Charts ")

        self.pathz = QWidget()
        self.vlayout3 = QVBoxLayout(self.pathz)
        self.patz = QGroupBox(self.pathz)
        self.hboxlayout3 = QVBoxLayout(self.patz)
        self.profilepath = QLineEdit(profilerPath)
        self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open')
        self.getprofile.setToolTip(
            'Dont touch if you dont know what are doing')
        self.getprofile.clicked.connect(lambda: self.profilepath.setText(
            str(
                QFileDialog.getOpenFileName(
                    self.patz, ' Open the profile.py file ',
                    path.expanduser("~"), ';;(profile.py)'))))
        self.hboxlayout3.addWidget(
            QLabel(
                '<center><b>Profile.py Python Library Full Path:</b></center>')
        )
        self.hboxlayout3.addWidget(self.profilepath)
        self.hboxlayout3.addWidget(self.getprofile)

        self.argGroupBox = QGroupBox(self.pathz)
        self.hbxlayout = QHBoxLayout(self.argGroupBox)
        self.argLineEdit = QLineEdit(self.argGroupBox)
        self.argLineEdit.setToolTip(
            'Not touch if you dont know what are doing')
        self.argLineEdit.setPlaceholderText(
            'Dont touch if you dont know what are doing')
        self.hbxlayout.addWidget(
            QLabel('<b>Additional Profile Arguments:</b>'))
        self.hbxlayout.addWidget(self.argLineEdit)
        self.hboxlayout3.addWidget(self.argGroupBox)

        self.vlayout3.addWidget(self.patz)
        self.tabWidget.addTab(self.pathz, " Paths and Configs ")

        self.outp = QWidget()
        self.vlayout4 = QVBoxLayout(self.outp)
        self.outgro = QGroupBox(self.outp)
        self.outgro.setTitle(" MultiProcessing Output Logs ")
        self.hboxlayout4 = QVBoxLayout(self.outgro)
        self.outputlog = QTextEdit()
        self.outputlog.setText('''
        I do not fear computers, I fear the lack of them.   -Isaac Asimov ''')
        self.hboxlayout4.addWidget(self.outputlog)
        self.vlayout4.addWidget(self.outgro)
        self.tabWidget.addTab(self.outp, " Logs ")

        self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"),
                                           'New Profiling', self)
        self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"),
                                          'Open Profiling', self)
        self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean',
                                   self)
        self.actionClean.triggered.connect(lambda: self.clearContent)
        self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About',
                                   self)
        self.actionAbout.triggered.connect(lambda: QMessageBox.about(
            self.dock, __doc__, ', '.join(
                (__doc__, __license__, __author__, __email__))))
        self.actionSave_profile = QAction(QIcon.fromTheme("document-save"),
                                          'Save Profiling', self)
        self.actionManual = QAction(QIcon.fromTheme("help-contents"), 'Help',
                                    self)
        self.actionManual.triggered.connect(lambda: open_new_tab(
            'http://docs.python.org/library/profile.html'))

        self.tabWidget.setCurrentIndex(2)

        self.globalStatGroupBox.setTitle("Global Statistics")
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText("Number of Calls")
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText("Total Time")
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText("Cumulative Time")
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText("Filename")
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText("Line")
        item = self.tableWidget.horizontalHeaderItem(7)
        item.setText("Function")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat),
                                  "Statistics per Function")

        self.sourceTreeWidget.headerItem().setText(0, "Source files")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.source),
                                  "Sources Navigator")
        #######################################################################

        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(self.tabWidget)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        QToolBar(self.dock).addActions(
            (self.actionNew_profiling, self.actionClean,
             self.actionSave_profile, self.actionLoad_profile,
             self.actionManual, self.actionAbout))

        self.actionNew_profiling.triggered.connect(
            self.on_actionNew_profiling_triggered)
        self.actionLoad_profile.triggered.connect(
            self.on_actionLoad_profile_triggered)
        self.actionSave_profile.triggered.connect(
            self.on_actionSave_profile_triggered)

        self.locator.get_service('misc').add_widget(
            self.dock, QIcon.fromTheme("document-open-recent"), __doc__)

        if QSCI:
            # Scintilla source editor management
            self.scintillaWarningLabel.setText(' QScintilla is Ready ! ')
            layout = self.source.layout()
            layout.removeWidget(self.sourceTextEdit)
            self.sourceTextEdit = Qsci.QsciScintilla(self.source)
            layout.addWidget(self.sourceTextEdit, 0, 1)
            doc = self.sourceTextEdit
            doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit))
            doc.setReadOnly(True)
            doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine)
            doc.setEdgeColumn(80)
            doc.setEdgeColor(QColor("#FF0000"))
            doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle)
            doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch)
            doc.setCaretLineVisible(True)
            doc.setMarginLineNumbers(1, True)
            doc.setMarginWidth(1, 25)
            doc.setTabWidth(4)
            doc.setEolMode(Qsci.QsciScintilla.EolUnix)
            self.marker = {}
            for color in COLORS:
                mnr = doc.markerDefine(Qsci.QsciScintilla.Background)
                doc.setMarkerBackgroundColor(color, mnr)
                self.marker[color] = mnr
        self.currentSourcePath = None

        # Connect table and tree filter edit signal to unique slot
        self.filterTableLineEdit.textEdited.connect(
            self.on_filterLineEdit_textEdited)

        # Timer to display filter hint message
        self.filterHintTimer = QTimer(self)
        self.filterHintTimer.setSingleShot(True)
        self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout)

        # Timer to start search
        self.filterSearchTimer = QTimer(self)
        self.filterSearchTimer.setSingleShot(True)
        self.filterSearchTimer.timeout.connect(
            self.on_filterSearchTimer_timeout)

        self.tabLoaded = {}
        for i in range(10):
            self.tabLoaded[i] = False
        self.backgroundTreeMatchedItems = {}
        self.resizeWidgetToContent(self.tableWidget)

    def on_actionNew_profiling_triggered(self):
        self.clearContent()
        self.scriptPath = str(
            QFileDialog.getOpenFileName(self.dock,
                                        "Choose your script to profile",
                                        path.expanduser("~"),
                                        "Python (*.py *.pyw)"))
        commandLine = [
            self.profilerPath, "-o", self.tempPath, self.scriptPath
        ] + self.scriptArgs
        commandLine = " ".join(commandLine)
        ##if self.termCheckBox.checkState() == Qt.Checked:
        #termList = ["xterm", "aterm"]
        #for term in termList:
        #termPath = which(term)
        #if termPath:
        #break
        #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \
        #% (termPath, commandLine)
        self.process.start(commandLine)
        if not self.process.waitForStarted():
            print((" ERROR: {} failed!".format(commandLine)))
            return

    def on_process_finished(self, exitStatus):
        ' whan the process end '
        print((" INFO: OK: QProcess is %s" % self.process.exitCode()))
        self.output = self.process.readAll().data()
        if not self.output:
            self.output = " ERROR: FAIL: No output ! "
        self.outputlog.setText(self.output + str(self.process.exitCode()))
        if path.exists(self.tempPath):
            self.setStat(self.tempPath)
            remove(self.tempPath)
        else:
            self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.")
        self.tabWidget.setCurrentIndex(2)

    def on_process_error(self, error):
        ' when the process fail, I hope you never see this '
        print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ")
        if error == QProcess.FailedToStart:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ")
        elif error == QProcess.Crashed:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ")
        else:
            self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ")

    def on_actionLoad_profile_triggered(self):
        """Load a previous profile sessions"""
        statPath = str(
            QFileDialog.getOpenFileName(self.dock, "Open profile dump",
                                        path.expanduser("~"),
                                        "Profile file (*)"))
        if statPath:
            self.clearContent()
            print(' INFO: OK: Loading profiling from ' + statPath)
            self.setStat(statPath)

    def on_actionSave_profile_triggered(self):
        """Save a profile sessions"""
        statPath = str(
            QFileDialog.getSaveFileName(self.dock, "Save profile dump",
                                        path.expanduser("~"),
                                        "Profile file (*)"))
        if statPath:
            #TODO: handle error case and give feelback to user
            print(' INFO: OK: Saving profiling to ' + statPath)
            self.stat.save(statPath)

    #=======================================================================#
    # Common parts                                                          #
    #=======================================================================#

    def on_tabWidget_currentChanged(self, index):
        """slot for tab change"""
        # Kill search and hint timer if running to avoid cross effect
        for timer in (self.filterHintTimer, self.filterSearchTimer):
            if timer.isActive():
                timer.stop()
        if not self.stat:
            #No stat loaded, nothing to do
            return
        self.populateTable()
        self.populateSource()

    def on_filterLineEdit_textEdited(self, text):
        """slot for filter change (table or tree"""
        if self.filterSearchTimer.isActive():
            # Already runnning, stop it
            self.filterSearchTimer.stop()
        # Start timer
        self.filterSearchTimer.start(300)

    def on_filterHintTimer_timeout(self):
        """Timeout to warn user about text length"""
        print("timeout")
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            label = self.filterHintTableLabel
        label.setText("Type > 2 characters to search")

    def on_filterSearchTimer_timeout(self):
        """timeout to start search"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            text = self.filterTableLineEdit.text()
            label = self.filterHintTableLabel
            edit = self.filterTableLineEdit
            widget = self.tableWidget
        else:
            print("Unknow tab for filterSearch timeout !")

        print(("do search for %s" % text))
        if not len(text):
            # Empty keyword, just clean all
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")
            self.warnUSer(True, edit)
            self.clearSearch()
            return
        if len(text) < 2:
            # Don't filter if text is too short and tell it to user
            self.filterHintTimer.start(600)
            return
        else:
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")

        # Search
        self.clearSearch()
        matchedItems = []
        if tab == TAB_FUNCTIONSTAT:
            # Find items
            matchedItems = widget.findItems(text, Qt.MatchContains)
            widget.setSortingEnabled(False)
            matchedRows = [item.row() for item in matchedItems]
            # Hide matched items
            header = widget.verticalHeader()
            for row in range(widget.rowCount()):
                if row not in matchedRows:
                    header.hideSection(row)
            widget.setSortingEnabled(True)
        else:
            print(" Unknow tab for filterSearch timeout ! ")

        print(("got %s members" % len(matchedItems)))
        self.warnUSer(matchedItems, edit)
        self.resizeWidgetToContent(widget)

    def resizeWidgetToContent(self, widget):
        """Resize all columns according to content"""
        for i in range(widget.columnCount()):
            widget.resizeColumnToContents(i)

    def clearSearch(self):
        """Clean search result
        For table, show all items
        For tree, remove colored items"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            header = self.tableWidget.verticalHeader()
            if header.hiddenSectionCount():
                for i in range(header.count()):
                    if header.isSectionHidden(i):
                        header.showSection(i)

    def clearContent(self):
        # Clear tabs
        self.tableWidget.clearContents()
        self.sourceTreeWidget.clear()
        # Reset LCD numbers
        for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber,
                          self.primCallLcdNumber):
            lcdNumber.display(1000000)
        # Reset stat
        self.pstat = None
        # Disable save as menu
        self.actionSave_profile.setEnabled(False)
        # Mark all tabs as unloaded
        for i in range(10):
            self.tabLoaded[i] = False

    def warnUSer(self, result, inputWidget):
        palette = inputWidget.palette()
        if result:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 255, 255))
        else:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 136, 138))
        inputWidget.setPalette(palette)
        inputWidget.update()

    def setStat(self, statPath):
        self.stat = Stat(path=statPath)
        # Global stat update
        self.totalTimeLcdNumber.display(self.stat.getTotalTime())
        self.numCallLcdNumber.display(self.stat.getCallNumber())
        self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio())
        # Refresh current tab
        self.on_tabWidget_currentChanged(self.tabWidget.currentIndex())
        # Activate save as menu
        self.actionSave_profile.setEnabled(True)
        try:
            self.rating.setMaxRating(10)
            self.rating.setRating(
                int(self.stat.getPrimitiveCallRatio()) / 10 - 1)
        except:
            pass

    #========================================================================#
    # Statistics table                                                      #
    #=======================================================================#

    def populateTable(self):
        row = 0
        rowCount = self.stat.getStatNumber()
        progress = QProgressDialog("Populating statistics table...", "Abort",
                                   0, 2 * rowCount)
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setRowCount(rowCount)

        progress.setWindowModality(Qt.WindowModal)
        for (key, value) in self.stat.getStatItems():
            #ncalls
            item = StatTableWidgetItem(str(value[0]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_NCALLS, item)
            colorTableItem(item, self.stat.getCallNumber(), value[0])
            #total time
            item = StatTableWidgetItem(str(value[2]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[2])
            #per call (total time)
            if value[0] != 0:
                tPerCall = str(value[2] / value[0])
                cPerCall = str(value[3] / value[0])
            else:
                tPerCall = ""
                cPerCall = ""
            item = StatTableWidgetItem(tPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TPERCALL, item)
            colorTableItem(
                item,
                100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(),
                tPerCall)
            #per call (cumulative time)
            item = StatTableWidgetItem(cPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CPERCALL, item)
            colorTableItem(
                item,
                100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(),
                cPerCall)
            #cumulative time
            item = StatTableWidgetItem(str(value[3]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[3])
            #Filename
            self.tableWidget.setItem(row, STAT_FILENAME,
                                     StatTableWidgetItem(str(key[0])))
            #Line
            item = StatTableWidgetItem(str(key[1]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_LINE, item)
            #Function name
            self.tableWidget.setItem(row, STAT_FUNCTION,
                                     StatTableWidgetItem(str(key[2])))
            row += 1
            # Store it in stat hash array
            self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT)
            progress.setValue(row)
            if progress.wasCanceled():
                return

        for i in range(self.tableWidget.rowCount()):
            progress.setValue(row + i)
            for j in range(self.tableWidget.columnCount()):
                item = self.tableWidget.item(i, j)
                if item:
                    item.setFlags(Qt.ItemIsEnabled)

        self.tableWidget.setSortingEnabled(True)
        self.resizeWidgetToContent(self.tableWidget)
        progress.setValue(2 * rowCount)

    def on_tableWidget_itemDoubleClicked(self, item):
        matchedItems = []
        filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text())
        if not filename or filename.startswith("<"):
            # No source code associated, return immediatly
            return
        function = self.tableWidget.item(item.row(), STAT_FUNCTION).text()
        line = self.tableWidget.item(item.row(), STAT_LINE).text()

        self.on_tabWidget_currentChanged(TAB_SOURCE)  # load source tab
        function = "%s (%s)" % (function, line)
        fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains,
                                                  SOURCE_FILENAME)
        print(("find %s father" % len(fathers)))
        for father in fathers:
            findItems(father, function, SOURCE_FILENAME, matchedItems)
        print(("find %s items" % len(matchedItems)))

        if matchedItems:
            self.tabWidget.setCurrentIndex(TAB_SOURCE)
            self.sourceTreeWidget.scrollToItem(matchedItems[0])
            self.on_sourceTreeWidget_itemClicked(matchedItems[0],
                                                 SOURCE_FILENAME)
            matchedItems[0].setSelected(True)
        else:
            print("oups, item found but cannot scroll to it !")

    #=======================================================================#
    # Source explorer                                                      #
    #=====================================================================#

    def populateSource(self):
        items = {}
        for stat in self.stat.getStatKeys():
            source = stat[0]
            function = "%s (%s)" % (stat[2], stat[1])
            if source in ("", "profile") or source.startswith("<"):
                continue
            # Create the function child
            child = QTreeWidgetItem([function])
            # Store it in stat hash array
            self.stat.setStatLink(child, stat, TAB_SOURCE)
            if source in items:
                father = items[source]
            else:
                # Create the father
                father = QTreeWidgetItem([source])
                items[source] = father
            father.addChild(child)
        self.sourceTreeWidget.setSortingEnabled(False)
        for value in list(items.values()):
            self.sourceTreeWidget.addTopLevelItem(value)
        self.sourceTreeWidget.setSortingEnabled(True)

    def on_sourceTreeWidget_itemActivated(self, item, column):
        self.on_sourceTreeWidget_itemClicked(item, column)

    def on_sourceTreeWidget_itemClicked(self, item, column):
        line = 0
        parent = item.parent()
        if QSCI:
            doc = self.sourceTextEdit
        if parent:
            pathz = parent.text(column)
            result = match("(.*) \(([0-9]+)\)", item.text(column))
            if result:
                try:
                    function = str(result.group(1))
                    line = int(result.group(2))
                except ValueError:
                    # We got garbage... falling back to line 0
                    pass
        else:
            pathz = item.text(column)
        pathz = path.abspath(str(pathz))
        if self.currentSourcePath != pathz:
            # Need to load source
            self.currentSourcePath == pathz
            try:
                if QSCI:
                    doc.clear()
                    doc.insert(file(pathz).read())
                else:
                    self.sourceTextEdit.setPlainText(file(pathz).read())
            except IOError:
                QMessageBox.warning(self, "Error",
                                    "Source file could not be found",
                                    QMessageBox.Ok)
                return

            if QSCI:
                for function, line in [(i[2], i[1])
                                       for i in self.stat.getStatKeys()
                                       if i[0] == pathz]:
                    # expr, regexp, case sensitive, whole word, wrap, forward
                    doc.findFirst("def", False, True, True, False, True, line,
                                  0, True)
                    end, foo = doc.getCursorPosition()
                    time = self.stat.getStatTotalTime((pathz, line, function))
                    colorSource(doc, self.stat.getTotalTime(), time, line, end,
                                self.marker)
        if QSCI:
            doc.ensureLineVisible(line)
Ejemplo n.º 3
0
class MainWidget(QMainWindow):
    def __init__(self, parent=None):
        super(MainWidget,
              self).__init__(parent,
                             windowTitle='GithubRemote',
                             windowIcon=QIcon(image_path('git.png')),
                             geometry=QRect(300, 300, 600, 372))

        self.repo_pixmap = QPixmap(image_path('book_16.png'))
        self.big_repo_pixmap = QPixmap(image_path('book_32.png'))
        self.repo_fork_pixmap = QPixmap(image_path('book_fork_16.png'))
        self.star_pixmap = QPixmap(image_path('star_16.png'))
        self.big_star_pixmap = QPixmap(image_path('star_32.png'))
        self.fork_pixmap = QPixmap(image_path('fork_16.png'))
        self.eye_pixmap = QPixmap(image_path('eye_16.png'))

        self.github = None

        # Actions

        self.repoAddAction = QAction(QIcon(image_path('plus_48.png')),
                                     '&Add Repo',
                                     self,
                                     statusTip='Add a new repo')
        self.repoAddAction.triggered.connect(self.repoAdd)

        self.repoRemoveAction = QAction(QIcon(image_path('minus.png')),
                                        '&Remove Repo',
                                        self,
                                        statusTip='Remove repo')
        self.repoRemoveAction.triggered.connect(self.repoRemove)

        self.repoRefreshAction = QAction(QIcon(image_path('refresh.png')),
                                         'Refresh',
                                         self,
                                         statusTip='Refresh list of repos')
        self.repoRefreshAction.triggered.connect(self.reposRefresh)
        self.repoRefreshAction.triggered.connect(self.starsRefresh)

        self.addAccountAction = QAction('Add Account',
                                        self,
                                        statusTip='Add Account')
        self.addAccountAction.triggered.connect(self.addAccount)

        # userPushButton - Displays the current active username and
        # image on the top right of the toolbar.

        self.userButtonMenu = UserButtonMenu(32, 32)

        # ToolBar

        self.toolBar = self.addToolBar('Main')
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolBar.addAction(self.repoAddAction)
        self.toolBar.addAction(self.repoRemoveAction)
        self.toolBar.addAction(self.repoRefreshAction)
        self.toolBar.addWidget(spacer)
        self.toolBar.addWidget(self.userButtonMenu)

        # Menu

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        actionMenu = menuBar.addMenu('&Action')
        fileMenu.addAction(self.addAccountAction)
        actionMenu.addAction(self.repoAddAction)
        actionMenu.addAction(self.repoRemoveAction)
        actionMenu.addAction(self.repoRefreshAction)

        # StatusBar

        statusBar = self.statusBar()
        self.setStatusBar(statusBar)

        # reposTableWidget - Displays a list of the users repositories

        self.reposTableWidget = QTableWidget(
            0,
            5,
            selectionBehavior=QAbstractItemView.SelectRows,
            selectionMode=QAbstractItemView.SingleSelection,
            editTriggers=QAbstractItemView.NoEditTriggers,
            itemSelectionChanged=self.actionsUpdate)
        self.reposTableWidget.horizontalHeader().setResizeMode(
            QHeaderView.ResizeToContents)
        self.reposTableWidget.horizontalHeader().setResizeMode(
            1, QHeaderView.Stretch)
        self.reposTableWidget.horizontalHeader().setVisible(False)
        self.reposTableWidget.verticalHeader().setVisible(False)
        self.reposTableWidget.setShowGrid(False)
        self.reposTableWidget.verticalHeader().setMinimumSectionSize(25)

        # repoTab - Layout
        reposTab = QWidget()
        reposTabLayout = QVBoxLayout(reposTab)
        reposTabLayout.addWidget(self.reposTableWidget)
        reposTab.setLayout(reposTabLayout)

        # starsTableWidget - Displays a list of the users repositories

        self.starsTableWidget = QTableWidget(
            0,
            5,
            selectionBehavior=QAbstractItemView.SelectRows,
            selectionMode=QAbstractItemView.SingleSelection,
            editTriggers=QAbstractItemView.NoEditTriggers,
            itemSelectionChanged=self.actionsUpdate)
        self.starsTableWidget.horizontalHeader().setResizeMode(
            QHeaderView.ResizeToContents)
        self.starsTableWidget.horizontalHeader().setResizeMode(
            1, QHeaderView.Stretch)
        self.starsTableWidget.horizontalHeader().setVisible(False)
        self.starsTableWidget.verticalHeader().setVisible(False)
        self.starsTableWidget.setShowGrid(False)
        self.starsTableWidget.verticalHeader().setMinimumSectionSize(25)

        # repoTab - Layout
        starsTab = QWidget()
        starsTabLayout = QVBoxLayout(starsTab)
        starsTabLayout.addWidget(self.starsTableWidget)
        starsTab.setLayout(starsTabLayout)

        # Tab Widget
        self.tabs = QTabWidget()
        self.tabs.setTabBar(FlippedTabBar(self))
        self.tabs.addTab(reposTab, QIcon(self.big_repo_pixmap), "repos")
        self.tabs.addTab(starsTab, QIcon(self.big_star_pixmap), "stars")
        self.tabs.setTabPosition(QTabWidget.West)

        # Layout

        self.setCentralWidget(self.tabs)
        self.actionsUpdate()
        self.show()

        # Update

        self.loadUserMenu()
        if self.activeUserAction:
            self.activeUserAction.setVisible(False)
        self.authenticate()
        self.actionsUpdate()
        self.reposRefresh()
        self.starsRefresh()
        self.updateImage()

    @waiting_effects
    def updateImage(self):

        try:
            url = self.github.get_user().avatar_url
        except (GithubException, AttributeError):
            return
        data = urllib.urlopen(url).read()
        pixmap = QPixmap()
        pixmap.loadFromData(data)
        self.activeUserAction.setIcon(QIcon(pixmap))
        self.userButtonMenu.setPixmap(pixmap)
        self.userButtonMenu.setText(self.github.get_user().login)

    @waiting_effects
    def loadUserMenu(self):

        action = None
        for _, username, token in generate_tokens(CONFIG_PATH, 'github'):

            try:
                url = Github(token).get_user().avatar_url
            except (GithubException, AttributeError):
                action = QAction(username, self, triggered=self.changeActive)
                self.userButtonMenu.addAction(action)
                continue
            data = urllib.urlopen(url).read()
            pixmap = QPixmap()
            pixmap.loadFromData(data)
            action = QAction(QIcon(pixmap),
                             username,
                             self,
                             triggered=self.changeActive)
            action.setIconVisibleInMenu(True)
            self.userButtonMenu.addAction(action)

        self.activeUserAction = action

    def changeActive(self):

        sender = self.sender()

        self.activeUserAction.setVisible(True)
        self.activeUserAction = sender
        self.activeUserAction.setVisible(False)
        self.authenticate()
        self.actionsUpdate()
        self.reposRefresh()
        self.starsRefresh()
        self.updateImage()

    @waiting_effects
    def reposRefresh(self):

        self.reposTableWidget.clearContents()

        try:
            repos = self.github.get_user().get_repos()
            self.reposTableWidget.setRowCount(
                self.github.get_user().public_repos)
        except (GithubException, AttributeError):
            return
        for row, repo in enumerate(repos):
            imageLabel = QLabel()
            if repo.fork:
                imageLabel.setPixmap(self.repo_fork_pixmap)
            else:
                imageLabel.setPixmap(self.repo_pixmap)
            imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            imageLabel.setMargin(5)

            self.reposTableWidget.setCellWidget(row, 0, imageLabel)
            label = QLabel('<b>{}</b><br />{}'.format(str(repo.name),
                                                      str(repo.description)))
            label.setAlignment(Qt.AlignVCenter)
            label.setMargin(5)
            label.setWordWrap(True)
            self.reposTableWidget.setCellWidget(row, 1, label)
            self.reposTableWidget.setItem(
                row, 2,
                QTableWidgetItem(QIcon(self.star_pixmap),
                                 str(repo.stargazers_count)))
            self.reposTableWidget.setItem(
                row, 3,
                QTableWidgetItem(QIcon(self.eye_pixmap),
                                 str(repo.watchers_count)))
            self.reposTableWidget.setItem(
                row, 4,
                QTableWidgetItem(QIcon(self.fork_pixmap),
                                 str(repo.forks_count)))

        self.reposTableWidget.resizeRowsToContents()

    @waiting_effects
    def starsRefresh(self):

        self.starsTableWidget.clearContents()

        try:
            starred = self.github.get_user().get_starred()
            self.starsTableWidget.setRowCount(
                self.github.get_user().public_repos)
        except (GithubException, AttributeError):
            return
        for row, repo in enumerate(starred):
            imageLabel = QLabel()
            if repo.fork:
                imageLabel.setPixmap(self.repo_fork_pixmap)
            else:
                imageLabel.setPixmap(self.repo_pixmap)
            imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            imageLabel.setMargin(5)

            self.starsTableWidget.setCellWidget(row, 0, imageLabel)
            label = QLabel(u'<b>{}/{}</b><br />{}'.format(
                unicode(repo.owner.login), unicode(repo.name),
                unicode(repo.description)))
            label.setAlignment(Qt.AlignVCenter)
            label.setMargin(5)
            label.setWordWrap(True)
            self.starsTableWidget.setCellWidget(row, 1, label)
            self.starsTableWidget.setItem(
                row, 2, QTableWidgetItem(QIcon(self.star_pixmap), '0'))
            self.starsTableWidget.setItem(
                row, 3,
                QTableWidgetItem(QIcon(self.eye_pixmap),
                                 str(repo.watchers_count)))
            self.starsTableWidget.setItem(
                row, 4,
                QTableWidgetItem(QIcon(self.fork_pixmap),
                                 str(repo.forks_count)))

        self.starsTableWidget.resizeRowsToContents()

    @waiting_effects
    def authenticate(self):

        if self.activeUserAction:
            username = str(self.activeUserAction.text())
            token = load_token(CONFIG_PATH, 'github', username)
            self.github = Github(token)
        else:
            self.github = None

    def actionsUpdate(self):
        # TODO disable if no user is logged in
        if self.github is None:
            self.repoAddAction.setEnabled(False)
            self.repoRemoveAction.setEnabled(False)
            self.repoRefreshAction.setEnabled(False)
        else:
            self.repoAddAction.setEnabled(True)
            self.repoRefreshAction.setEnabled(True)
            if self._isARepoSelected():
                self.repoRemoveAction.setEnabled(True)
            else:
                self.repoRemoveAction.setEnabled(False)

    def addAccount(self):
        wizard = AddAccountWizard(self)
        if wizard.exec_():
            username = str(wizard.field('username').toString())
            token = str(wizard.field('token').toString())
            store_token(CONFIG_PATH, 'github', username, token)
            self.authenticate()
            self.reposRefresh()
            self.updateImage()
            self.actionsUpdate()

    def repoAdd(self):
        wizard = AddRepoWizard(self.github, self)
        if wizard.exec_():
            self.github.get_user().create_repo(
                str(wizard.field('name').toString()),
                description=str(wizard.field('description').toString()),
                private=bool(wizard.field('private').toBool()),
                auto_init=bool(wizard.field('auto_init').toBool()),
                gitignore_template=str(wizard.field('gitignore').toString()),
                homepage=str(wizard.field('homepage').toString()),
                has_wiki=bool(wizard.field('has_wiki').toBool()),
                has_downloads=bool(wizard.field('has_downloads').toBool()),
                has_issues=bool(wizard.field('has_issues').toBool()))
            self.reposRefresh()

    def repoRemove(self):

        row = self._selectedRepoRow()
        name = self.reposTableWidget.item(row, 0).text()
        dialog = RepoRemoveDialog(self.github, name)
        if dialog.exec_():
            self.github.get_user().get_repo(str(name)).delete()
            self.reposRefresh()

    def _isARepoSelected(self):
        """ Return True if a repo is selected else False """
        if len(self.reposTableWidget.selectedItems()) > 0:
            return True
        else:
            return False

    def _selectedRepoRow(self):
        """ Return the currently select repo """
        # TODO - figure out what happens if no repo is selected
        selectedModelIndexes = \
            self.reposTableWidget.selectionModel().selectedRows()
        for index in selectedModelIndexes:
            return index.row()
Ejemplo n.º 4
0
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        logging.info(u'创建主窗口...')

        QtGui.QMainWindow.__init__(self, parent)

        tabs = QtGui.QTabWidget(self)

        tab2 = QtGui.QWidget()
        tab3 = QtGui.QWidget()

        self.console = MyConsole(parent=self)

        # tab2 - self.console
        self.console.setMinimumSize(1500, 800)
        scroll = QtGui.QScrollArea()
        scroll.setWidget(self.console)
        scroll.setAutoFillBackground(True)
        scroll.setWidgetResizable(True)
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(scroll)
        tab2.setLayout(vbox)

        # tab3 -
        self.viewEntry = QTableWidget(0, 12)
        self.viewEntry.setHorizontalHeaderLabels(
                [u'期数', u'时间', u'冠军', u'亚军', u'第三名', u'第四名', u'第五名', u'第六名', u'第七名', u'第八名', u'第九名', u'第十名'])
        self.viewEntry.horizontalHeader().setStretchLastSection(True)
        self.viewEntry.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)

        vbox3 = QtGui.QVBoxLayout()
        vbox3.addWidget(self.viewEntry)
        tab3.setLayout(vbox3)
        tabs.addTab(tab2, u"控制台")
        tabs.addTab(tab3, u"开奖结果")

        tabs.resize(1500, 800)
        self.resize(1500, 800)
        self.tabs = tabs
        self.tab2 = tab2
        self.tab3 = tab3
        self.scroll = scroll
        # 禁止最大化
        self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint)

        from myutil.tool.Overlay import Overlay
        self.setCentralWidget(self.tabs)
        self.overlay = Overlay(self.centralWidget())
        self.overlay.hide()

        self.show()

    @pyqtSlot(str)
    def mySetWindowTitle(self, title):
        self.setWindowTitle(title)

    @pyqtSlot(str, list)
    def completeHistoryResultData(self, timesnow, open_balls):
        logging.info(u"【主窗口-历史数据展板-填充之】")
        for i in range(len(open_balls)):
            newItem = QTableWidgetItem(str(open_balls[i]))
            self.viewEntry.setItem(0, 2 + i, newItem)
        logging.info(u"【主窗口-历史数据展板-填充完毕】")

    @pyqtSlot(str, list)
    def appendHistoryResultData(self, timesnow, open_balls):
        logging.info(u"【主窗口-历史数据展板-追加】")
        time_str = MyTool.getCurrentTimeStr()
        self.viewEntry.insertRow(0)
        # 期数
        newItem = QTableWidgetItem(str(int(timesnow) - 1))
        self.viewEntry.setItem(0, 0, newItem)
        # 时间
        newItem = QTableWidgetItem(time_str)
        self.viewEntry.setItem(0, 1, newItem)

        for i in range(len(open_balls)):
            newItem = QTableWidgetItem(str(open_balls[i]))
            self.viewEntry.setItem(0, 2 + i, newItem)
        logging.info(u"【主窗口-历史数据展板-追加完毕】")

    @pyqtSlot(list)
    def updateHistoryResultData(self, data_list):
        logging.info(u"【主窗口-历史数据展板-大更新】################START HistoryResultData################")
        # 先清空...
        self.viewEntry.clearContents()
        self.viewEntry.setRowCount(0)

        for period in data_list:
            # 添加一行
            row = self.viewEntry.rowCount()
            self.viewEntry.insertRow(row)

            # 期数
            newItem = QTableWidgetItem(period[0])
            self.viewEntry.setItem(row, 0, newItem)

            # 时间
            newItem = QTableWidgetItem(str(period[1]))
            self.viewEntry.setItem(row, 1, newItem)
            if self.console.play_mode in [common.PLAYMODE_PK10, common.PLAYMODE_XYFT]:
                for i in range(10):
                    newItem = QTableWidgetItem(str(period[2 + i]))
                    self.viewEntry.setItem(row, 2 + i, newItem)
            else:
                for i in range(5):
                    newItem = QTableWidgetItem(str(period[2 + i]))
                    self.viewEntry.setItem(row, 2 + i, newItem)

        logging.info(u"【主窗口-历史数据展板-大更新】################END HistoryResultData################")

    def closeEvent(self, event):
        reply = QtGui.QMessageBox.question(self, u'退出', u"您确定离开吗?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        if reply == QtGui.QMessageBox.Yes:
            # 关闭http连接...
            from common.common import req_session
            req_session.close()

            event.accept()
        else:
            event.ignore()

    def resizeEvent(self, event):
        self.overlay.resize(event.size())
        event.accept()
Ejemplo n.º 5
0
class ScanRecordTable(QGroupBox):
    """ GUI component. Displays a list of previous scan results. Selecting a scan causes
    details of the scan to appear in other GUI components (list of barcodes in the barcode
    table and image of the puck in the image frame).
    """
    COLUMNS = ['Date', 'Time', 'Plate Type', 'Valid', 'Invalid', 'Empty']

    def __init__(self, barcode_table, image_frame, options):
        super(ScanRecordTable, self).__init__()

        # Read the store from file
        self._store = Store(options.store_directory.value(), options)
        self._options = options

        self._barcodeTable = barcode_table
        self._imageFrame = image_frame

        self.setTitle("Scan Records")
        self._init_ui()

        self._load_store_records()

    def _init_ui(self):
        # Create record table - lists all the records in the store
        self._table = QTableWidget()
        self._table.setFixedWidth(440)
        self._table.setFixedHeight(600)
        self._table.setColumnCount(len(self.COLUMNS))
        self._table.setHorizontalHeaderLabels(self.COLUMNS)
        self._table.setColumnWidth(0, 70)
        self._table.setColumnWidth(1, 55)
        self._table.setColumnWidth(2, 85)
        self._table.setColumnWidth(3, 60)
        self._table.setColumnWidth(4, 60)
        self._table.setColumnWidth(5, 60)
        self._table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self._table.cellPressed.connect(self._record_selected)

        # Delete button - deletes selected records
        btn_delete = QtGui.QPushButton('Delete')
        btn_delete.setToolTip('Delete selected scan/s')
        btn_delete.resize(btn_delete.sizeHint())
        btn_delete.clicked.connect(self._delete_selected_records)

        hbox = QHBoxLayout()
        hbox.setSpacing(10)
        hbox.addWidget(btn_delete)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self._table)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def add_record(self, plate, image):
        """ Add a new scan record to the store and display it. """
        self._store.add_record(plate, image)
        self._load_store_records()

    def add_record_frame(self, plate, image):
        """ Add a new scan frame - creates a new record if its a new puck, else merges with previous record"""
        self._store.merge_record(plate, image)
        self._load_store_records()
        if self._options.scan_clipboard.value():
            self._barcodeTable.copy_selected_to_clipboard()

    def _load_store_records(self):
        """ Populate the record table with all of the records in the store.
        """
        self._table.clearContents()
        self._table.setRowCount(self._store.size())

        for n, record in enumerate(self._store.records):
            items = [record.date, record.time, record.plate_type, record.num_valid_barcodes,
                     record.num_unread_slots, record.num_empty_slots]

            if (record.num_valid_barcodes + record.num_empty_slots) == record.num_slots:
                color = self._options.col_ok()
            else:
                color = self._options.col_bad()

            color.a = 192
            for m, item in enumerate(items):
                new_item = QtGui.QTableWidgetItem(str(item))
                new_item.setBackgroundColor(color.to_qt())
                new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self._table.setItem(n, m, new_item)

        # Display the first (most recent) record
        self._table.setCurrentCell(0, 0)
        self._record_selected()

    def _record_selected(self):
        """ Called when a row is selected, causes details of the selected record to be
        displayed (list of barcodes in the barcode table and image of the scan in the
        image frame).
        """
        try:
            row = self._table.selectionModel().selectedRows()[0].row()
            record = self._store.get_record(row)
            self._barcodeTable.populate(record.barcodes)
            marked_image = record.marked_image(self._options)
            self._imageFrame.display_puck_image(marked_image)
        except IndexError:
            pass
            self._barcodeTable.populate([])
            self._imageFrame.clear_frame()

    def _delete_selected_records(self):
        """ Called when the 'Delete' button is pressed. Deletes all of the selected records
        (and the associated images) from the store and from disk. Asks for user confirmation.
        """
        # Display a confirmation dialog to check that user wants to proceed with deletion
        quit_msg = "This operation cannot be undone.\nAre you sure you want to delete these record/s?"
        reply = QtGui.QMessageBox.warning(self, 'Confirm Delete',
                         quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        # If yes, find the appropriate records and delete them
        if reply == QtGui.QMessageBox.Yes:
            rows = self._table.selectionModel().selectedRows()
            records_to_delete = []
            for row in rows:
                index = row.row()
                record = self._store.get_record(index)
                records_to_delete.append(record)

            self._store.delete_records(records_to_delete)
            self._load_store_records()
Ejemplo n.º 6
0
class ProcExpWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # setup menu bar
        exitItem = QAction('Exit', self)
        exitItem.setShortcut('Ctrl+Q')
        exitItem.setStatusTip('Exit application')
        exitItem.triggered.connect(self.close)
        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(exitItem)

        # setup widgets
        self.model = ProcTableModel(self)
        self.procTable = ProcTableWidget(self.model)
        self.procTable.clicked.connect(self.showDescriptors)
        self.handlesTable = QTableWidget()
        self.handlesTable.setColumnCount(2)
        self.handlesTable.setHorizontalHeaderLabels(('Type', 'Object Name'))
        self.handlesTable.verticalHeader().setVisible(False)
        self.handlesTable.setShowGrid(False)
        self.handlesTable.setSelectionBehavior(QTableWidget.SelectRows)
        self.handlesTable.horizontalHeader().setStretchLastSection(True)

        # TODO: find a way to get the row height from the QTreeView
        self.handlesTable.verticalHeader().setDefaultSectionSize(24)

        mainSplitter = QSplitter(Qt.Vertical)
        mainSplitter.addWidget(self.procTable)
        mainSplitter.addWidget(self.handlesTable)
        self.setCentralWidget(mainSplitter)

        desktopGeometry = QApplication.desktop().screenGeometry()
        self.setGeometry(0, 0, 1280, 700)
        self.move((desktopGeometry.width() - self.width()) / 2,
                  (desktopGeometry.height() - self.height()) / 2)
        self.setWindowTitle('Linux Process Explorer')

        # find handle dialog
        self.findDialog = None

    @pyqtSlot(int)
    def removeFindDialog(self):
        self.findDialog = None

    def keyPressEvent(self, event):
        modifiers = event.modifiers()
        if event.key() == Qt.Key_F and modifiers & Qt.ControlModifier:
            if self.findDialog is None:
                self.findDialog = FindHandleDialog(self.model, self)
                self.findDialog.finished.connect(self.removeFindDialog)
                self.findDialog.show()
            else:
                self.findDialog.activateWindow()
        else:
            super().keyPressEvent(event)

    @pyqtSlot(QModelIndex)
    def showDescriptors(self, processMIdx):
        try:
            self.handlesTable.setRowCount(0)
            self.handlesTable.clearContents()
            descriptors = self.model.getProcDescriptors(processMIdx)
            libs = self.model.getProcLibraries(processMIdx)
            self.handlesTable.setRowCount(len(descriptors) + len(libs))
        except PermissionError:
            self.handlesTable.setRowCount(1)
            self.handlesTable.setSpan(0, 0, 1, 2)
            permDeniedMsg = QTableWidgetItem('<Permission Denied>')
            permDeniedMsg.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            permDeniedMsg.setTextAlignment(Qt.AlignCenter)
            permDeniedMsg.setTextColor(QColor(255, 0, 0))
            self.handlesTable.setItem(0, 0, permDeniedMsg)
        else:
            for row, descriptor in enumerate(descriptors):
                typeItem = QTableWidgetItem(descriptor.type)
                typeItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                nameItem = QTableWidgetItem(descriptor.name)
                nameItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.handlesTable.setItem(row, 0, typeItem)
                self.handlesTable.setItem(row, 1, nameItem)

            for row, libName in enumerate(libs, start=len(descriptors)):
                typeItem = QTableWidgetItem('Shared Library')
                typeItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                nameItem = QTableWidgetItem(libName)
                nameItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self.handlesTable.setItem(row, 0, typeItem)
                self.handlesTable.setItem(row, 1, nameItem)
Ejemplo n.º 7
0
class OptimizateNewSiteUI(QDialog):
    def __init__(self, iface, parent=None):
        super(OptimizateNewSiteUI, self).__init__()
        self.iface = iface
        self.parent = parent

        self.initUI()

    # 初始化界面
    def initUI(self):
        self.setWindowTitle(u'自动规划基站优化')
        self.setWindowIcon(QIcon('images/logo.png'))
        self.resize(600, 300)
        self.setWindowFlags(Qt.WindowMinMaxButtonsHint)
        self.initView()

    def initView(self):
        # 数据表格
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(7)
        # 设置当前Table不能编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 初始化表格上下文菜单
        self.initTableContextMenu()

        self.initTableHeader()
        # 定义按钮
        impBtn = QPushButton(u"导入EXCEL表", self)
        self.connect(impBtn, SIGNAL('clicked()'), self.impData)
        startBtn = QPushButton(u"开始合并", self)
        self.connect(startBtn, SIGNAL('clicked()'), self.mergeJSite)
        #布局
        hbox = QHBoxLayout()
        hbox.addWidget(impBtn)
        hbox.addWidget(startBtn)
        vbox = QVBoxLayout()
        vbox.addWidget(self.tableWidget)
        vbox.addLayout(hbox)

        self.setLayout(vbox)
        # 判断是否已有规划基站结果
        layer = getLayerByName(u'规划基站结果', self.iface)
        if layer:
            data_list = []
            for feature in layer.getFeatures():
                temp_list = []
                for value in feature.attributes():
                    temp_list.append(value)
                data_list.append(temp_list)
                del temp_list
            self.initTable(data_list)
            self.__mlist = data_list

    def initTableContextMenu(self):
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.popMenu = QMenu(self.tableWidget)
        delAction = QAction(u'删除', self)  # 删除
        self.popMenu.addAction(delAction)

    # 初始化Table的头
    def initTableHeader(self):
        self.heads = []
        self.heads = MergeSiteHead
        self.tableWidget.setColumnCount(len(self.heads))  # 设置表格的列数
        for (i, h) in enumerate(self.heads):
            tabItem = QTableWidgetItem(h)
            self.tableWidget.setHorizontalHeaderItem(i, tabItem)

    # 导入Excel表数据
    def impData(self):
        fileName = QFileDialog.getOpenFileName(self, u'数据导入', '/',
                                               'Excel Files (*.xls *.xlsx)')
        if fileName != None and fileName != '':
            self.impType = ExcelType.MERGESITE
            getDataFromExcel = GetDataFromExcel(fileName, self.impType)
            datas_list = getDataFromExcel.getData()
            self.impFinish(datas_list)

    # 导入数据完成绑定函数
    def impFinish(self, mylist):
        self.__mlist = []
        self.__mlist.extend(mylist)
        self.tableWidget.clearContents()
        self.initTable(self.__mlist)

    # 初始化表格的每个Item
    def initTable(self, mlist):
        self.tableWidget.setRowCount(len(mlist))
        for (i, v) in enumerate(mlist):
            for (j, item) in enumerate(v):
                if type(item) != str:
                    item = unicode(item)
                if item == None:
                    item = ''
                tabItem = QTableWidgetItem(item)
                tabItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, j, tabItem)

    # 开始运行
    def mergeJSite(self):
        self.accept()
        merge = OptimizateNewSite(self.__mlist, self)
        merge.calculationResult.connect(self.calculationFinish)
        merge.run()

    def calculationFinish(self, merge_result):
        self.setResultLayer(merge_result)
        fileName = QFileDialog.getSaveFileName(self, u'合并结果导出到 ...', '/',
                                               'Excel File(*.xls *.xlsx)')
        if fileName:
            self.sphead = [u'规划基站名称', u'经度', u'纬度', u'区域类型', u"平均距离"]
            for i in range(6):  # 根据输入的参数增加表头
                self.sphead.append(u'基站名称')
                self.sphead.append(u'距离')
                self.sphead.append(u'经度')
                self.sphead.append(u'纬度')

            layer = getLayerByName(u"基站合并结果", self.iface)
            if not layer:
                QMessageBox.critical(self, u"错误", u"找不到基站合并结果图层")
            exportData = ExportData(self.iface, self)
            if exportData.exportDataToExcel(layer, fileName):
                QMessageBox.information(self, u"成功", u"数据导出成功!")
            else:
                QMessageBox.critical(self, u"错误", u"数据导出失败!")

        else:
            self.close()

    # 生成规划基站结果图层
    def setResultLayer(self, result_list):
        layerName = u'规划基站优化结果'
        layerType = QGis.WKBPoint

        project_dir = getProjectDir(self.iface)
        # 先判断是否已存在规划基站结果图层
        result_layer = getLayerByName(layerName, self.iface)
        if result_layer:
            # 清空数据
            delAllFeatures(result_layer)
        else:
            # 删除原有图层文件
            deleteShapefile(project_dir, layerName)
            shapPath = os.path.join(project_dir, layerName + u".shp")
            # 生成图层
            fileds = self.createFields()
            # 创建出Shap文件
            # 数据源编码模式为GBK2312(否则中文字段会乱码)
            wr = QgsVectorFileWriter(shapPath, "GBK2312", fileds, layerType,
                                     None, "ESRI Shapefile")
            # 如果保存的时候没有错误
            if wr.hasError() == QgsVectorFileWriter.NoError:
                pass
            else:
                print wr.hasError()
                raise Exception, wr.errorMessage()  # 发生错误,抛出异常交给外面的方法处理异常
            del wr  # 使添加的字段生效

            result_layer = QgsVectorLayer(shapPath, layerName, 'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(result_layer)

        # 添加数据
        features_list = []
        for result in result_list:
            feature = createABasicPointFeature(
                QgsPoint(float(result[1]), float(result[2])), result)
            features_list.append(feature)
        importFeaturesToLayer(result_layer, features_list)

    def createFields(self):
        names = PLANNINGHead
        types = PLANNINGType2
        lengs = PLANNINGLength
        precs = PLANNINGPrec

        fields = QgsFields()
        for (i, itm) in enumerate(names):
            cuType = types[i]
            mtype = 'String'
            if cuType == QVariant.Int:
                mtype = 'Integer'
            elif cuType == QVariant.Double:
                mtype = 'Real'
            field = QgsField(itm, cuType, mtype, lengs[i], precs[i])
            fields.append(field)
        return fields

    def exportFinish(self, result):
        QMessageBox.information(self, u'新建基站结果', u'数据导出到Excel表完成,请查看')

    def exportError(self, e, erStr):
        QMessageBox.information(self, u'新建结果', u'生成基站时,发生错误,请重试+' + erStr)
Ejemplo n.º 8
0
class ScanRecordTable(QGroupBox):
    """ GUI component. Displays a list of previous scan results. Selecting a scan causes
    details of the scan to appear in other GUI components (list of barcodes in the barcode
    table and image of the puck in the image frame).
    """
    COLUMNS = [
        'Date', 'Time', 'Plate Barcode', 'Plate Type', 'Valid', 'Invalid',
        'Empty'
    ]

    def __init__(self, barcode_table, image_frame, options,
                 to_run_on_table_clicked):
        super(ScanRecordTable, self).__init__()

        # Read the store from file
        self._store = Store(options.store_directory.value(),
                            options.store_capacity, FileManager())
        self._options = options

        self._barcodeTable = barcode_table
        self._imageFrame = image_frame

        self.setTitle("Scan Records")
        self._init_ui(to_run_on_table_clicked)

        self._load_store_records()

    def _init_ui(self, to_run_on_table_clicked):
        # Create record table - lists all the records in the store
        self._table = QTableWidget()
        self._table.setFixedWidth(440)
        self._table.setFixedHeight(600)
        self._table.setColumnCount(len(self.COLUMNS))
        self._table.setHorizontalHeaderLabels(self.COLUMNS)
        self._table.setColumnWidth(0, 70)
        self._table.setColumnWidth(1, 55)
        self._table.setColumnWidth(2, 85)
        self._table.setColumnWidth(3, 70)
        self._table.setColumnWidth(4, 45)
        self._table.setColumnWidth(5, 50)
        self._table.setColumnWidth(6, 45)
        self._table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self._table.cellPressed.connect(to_run_on_table_clicked)
        self._table.cellPressed.connect(self._record_selected)

        # Delete button - deletes selected records
        btn_delete = QtGui.QPushButton('Delete')
        btn_delete.setToolTip('Delete selected scan/s')
        btn_delete.resize(btn_delete.sizeHint())
        btn_delete.clicked.connect(self._delete_selected_records)

        hbox = QHBoxLayout()
        hbox.setSpacing(10)
        hbox.addWidget(btn_delete)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self._table)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def add_record_frame(self, holder_barcode, plate, holder_img, pins_img):
        """ Add a new scan frame - creates a new record if its a new puck, else merges with previous record"""
        self._store.merge_record(holder_barcode, plate, holder_img, pins_img)
        self._load_store_records()
        if self._options.scan_clipboard.value():
            self._barcodeTable.copy_to_clipboard()

    def _load_store_records(self):
        """ Populate the record table with all of the records in the store.
        """
        self._table.clearContents()
        self._table.setRowCount(self._store.size())

        for n, record in enumerate(self._store.records):
            items = [
                record.date, record.time, record.holder_barcode,
                record.plate_type, record.num_valid_barcodes,
                record.num_unread_slots, record.num_empty_slots
            ]

            if (record.num_valid_barcodes +
                    record.num_empty_slots) == record.num_slots:
                color = self._options.col_ok()
            else:
                color = self._options.col_bad()

            color.a = 192
            for m, item in enumerate(items):
                new_item = QtGui.QTableWidgetItem(str(item))
                new_item.setBackgroundColor(color.to_qt())
                new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                self._table.setItem(n, m, new_item)

        # Display the first (most recent) record
        self._table.setCurrentCell(0, 0)
        self._record_selected()

    def _record_selected(self):
        """ Called when a row is selected, causes details of the selected record to be
        displayed (list of barcodes in the barcode table and image of the scan in the
        image frame).
        """
        try:
            row = self._table.selectionModel().selectedRows()[0].row()
            record = self._store.get_record(row)
            self._barcodeTable.populate(record.holder_barcode, record.barcodes)
            marked_image = record.marked_image(self._options)
            self._imageFrame.display_puck_image(marked_image)
        except IndexError:
            self._barcodeTable.clear()
            self._imageFrame.clear_frame(
                "Record table empty\nNothing to display")

    def _delete_selected_records(self):
        """ Called when the 'Delete' button is pressed. Deletes all of the selected records
        (and the associated images) from the store and from disk. Asks for user confirmation.
        """
        # Display a confirmation dialog to check that user wants to proceed with deletion
        quit_msg = "This operation cannot be undone.\nAre you sure you want to delete these record/s?"
        reply = QtGui.QMessageBox.warning(self, 'Confirm Delete', quit_msg,
                                          QtGui.QMessageBox.Yes,
                                          QtGui.QMessageBox.No)

        # If yes, find the appropriate records and delete them
        if reply == QtGui.QMessageBox.Yes:
            rows = self._table.selectionModel().selectedRows()
            records_to_delete = []
            for row in rows:
                index = row.row()
                record = self._store.get_record(index)
                records_to_delete.append(record)

            self._store.delete_records(records_to_delete)
            self._load_store_records()

    def is_latest_holder_barcode(self, holder_barcode):
        return self._store.is_latest_holder_barcode(holder_barcode)
Ejemplo n.º 9
0
class RLibraryBrowser(QDialog):

    def __init__(self, parent=None, paths=None):
        QDialog.__init__(self, parent)
        QShortcut(QKeySequence("Escape"), self, self.reject)
        self.setWindowTitle("manageR - Library Browser")
        self.resize(500, 500)
        port = robjects.r('tools:::httpdPort')[0]
        if not port > 0:
            robjects.r('tools::startDynamicHelp()')
            port = robjects.r('tools:::httpdPort')[0]
        robjects.r("""make.packages.html()""")
        host = "localhost"
        home = "/doc/html/packages.html"
        #splitter = QSplitter(self)
        #splitter.setOrientation(Qt.Vertical)
        #splitter.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        labels = QStringList(["Loaded", "Package",
                              "Title",  "Path"])
        self.parent = parent
        self.home = home
        self.packageTable = QTableWidget(0, 4, self)
        self.htmlViewer = HtmlBrowser(self, host, port, home, paths)
        #splitter.addWidget(self.packageTable)
        #splitter.addWidget(self.htmlViewer)
        vbox = QVBoxLayout(self)
        #hbox.addWidget(splitter)
        vbox.addWidget(self.packageTable)
        vbox.addWidget(self.htmlViewer)
        self.packageTable.setHorizontalHeaderLabels(labels)
        self.packageTable.setShowGrid(True)
        self.packageTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.packageTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.packageTable.setAlternatingRowColors(True)
        self.updatePackages()
        self.connect(self.packageTable,
            SIGNAL("itemChanged(QTableWidgetItem*)"), self.loadPackage)
        self.connect(self.packageTable,
            SIGNAL("itemDoubleClicked(QTableWidgetItem*)"), self.showPackage)

    def setSource(self, source):
        self.htmlViewer.setSource(source)

    def showPackage(self, item):
        row = item.row()
        tmp = self.packageTable.item(row, 1)
        package = tmp.text()
        home = QUrl(self.home)
        curr = QUrl("../../library/%s/html/00Index.html" % package)
        self.htmlViewer.setSource(home.resolved(curr))

    def loadPackage(self, item):
        row = item.row()
        tmp = self.packageTable.item(row, 1)
        package = tmp.text()
        if item.checkState() == Qt.Checked:
            command = "library(%s)" % package
        else:
            command = "detach('package:%s')" % package
        robjects.r(command)
        #self.emit(SIGNAL(...(command)

    def updatePackages(self):
        library_ = robjects.r.get('library', mode='function')
        packages_ = robjects.r.get('.packages', mode='function')
        loaded = list(packages_())
        packages = list(library_()[1])
        length = len(packages)
        self.packageTable.clearContents()
        #self.table.setRowCount(length/3)
        packageList = []
        for i in range(length/3):
            package = unicode(packages[i])
            if not package in packageList:
                packageList.append(package)
                self.packageTable.setRowCount(len(packageList))
                item = QTableWidgetItem("Loaded")
                item.setFlags(
                Qt.ItemIsUserCheckable|Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                if package in loaded:
                    item.setCheckState(Qt.Checked)
                else:
                    item.setCheckState(Qt.Unchecked)
                self.packageTable.setItem(i, 0, item)
                item = QTableWidgetItem(unicode(packages[i]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 1, item)
                item = QTableWidgetItem(unicode(packages[i+(2*(length/3))]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 2, item)
                item = QTableWidgetItem(unicode(packages[i+(length/3)]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 3, item)
        self.packageTable.resizeColumnsToContents()
Ejemplo n.º 10
0
class BarcodeTable(QGroupBox):
    """ GUI component. Displays a list of barcodes for the currently selected puck.
    """
    def __init__(self, options):
        super(BarcodeTable, self).__init__()

        self._barcodes = []

        self._options = options

        self.setTitle("Barcodes")
        self._init_ui()

    def _init_ui(self):
        # Create record table - lists all the records in the store
        self._table = QTableWidget()

        # Create barcode table - lists all the barcodes in a record
        self._table = QtGui.QTableWidget()
        self._table.setFixedWidth(110)
        self._table.setFixedHeight(600)
        self._table.setColumnCount(1)
        self._table.setRowCount(10)
        self._table.setHorizontalHeaderLabels(['Barcode'])
        self._table.setColumnWidth(0, 100)

        # Clipboard button - copy the selected barcodes to the clipboard
        self._btn_clipboard = QtGui.QPushButton('Copy To Clipboard')
        self._btn_clipboard.setToolTip(
            'Copy barcodes for the selected record to the clipboard')
        self._btn_clipboard.resize(self._btn_clipboard.sizeHint())
        self._btn_clipboard.clicked.connect(self.copy_selected_to_clipboard)
        self._btn_clipboard.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.setSpacing(10)
        hbox.addWidget(self._btn_clipboard)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self._table)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def populate(self, barcodes):
        """ Called when a new row is selected on the record table. Displays all of the
        barcodes from the selected record in the barcode table. By default, valid barcodes are
        highlighted green, invalid barcodes are highlighted red, and empty slots are grey.
        """
        num_slots = len(barcodes)
        self._table.clearContents()
        self._table.setRowCount(num_slots)

        for index, barcode in enumerate(barcodes):
            # Select appropriate background color
            if barcode == NOT_FOUND_SLOT_SYMBOL:
                color = self._options.col_bad()
            elif barcode == EMPTY_SLOT_SYMBOL:
                color = self._options.col_empty()
            else:
                color = self._options.col_ok()

            color.a = 192

            # Set table item
            barcode = QtGui.QTableWidgetItem(barcode)
            barcode.setBackgroundColor(color.to_qt())
            barcode.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self._table.setItem(index, 0, barcode)

        self._barcodes = barcodes[:]
        for i, barcode in enumerate(self._barcodes):
            if barcode in [NOT_FOUND_SLOT_SYMBOL, EMPTY_SLOT_SYMBOL]:
                self._barcodes[i] = ""

        self._update_button_state()

    def _update_button_state(self):
        if self._barcodes is None or len(self._barcodes) == 0:
            self._btn_clipboard.setEnabled(False)
        else:
            self._btn_clipboard.setEnabled(True)

    def copy_selected_to_clipboard(self):
        """ Called when the copy to clipboard button is pressed. Copies the list/s of
        barcodes for the currently selected records to the clipboard so that the user
        can paste it elsewhere.
        """
        sep = os.linesep
        if self._barcodes:
            pyperclip.copy(sep.join(self._barcodes))
Ejemplo n.º 11
0
class BarcodeTable(QGroupBox):
    """ GUI component. Displays a list of barcodes for the currently selected puck.
    """
    def __init__(self, options):
        super(BarcodeTable, self).__init__()

        self._barcodes = []

        self._options = options

        self.setTitle("Barcodes")
        self._init_ui()

    def _init_ui(self):
        # Create record table - lists all the records in the store
        self._table = QTableWidget()

        # Create barcode table - lists all the barcodes in a record
        self._table = QtGui.QTableWidget()
        self._table.setFixedWidth(110)
        self._table.setFixedHeight(600)
        self._table.setColumnCount(1)
        self._table.setRowCount(10)
        self._table.setHorizontalHeaderLabels(['Barcode'])
        self._table.setColumnWidth(0, 100)

        # Clipboard button - copy the selected barcodes to the clipboard
        self._btn_clipboard = QtGui.QPushButton('Copy To Clipboard')
        self._btn_clipboard.setToolTip('Copy barcodes for the selected record to the clipboard')
        self._btn_clipboard.resize(self._btn_clipboard.sizeHint())
        self._btn_clipboard.clicked.connect(self.copy_selected_to_clipboard)
        self._btn_clipboard.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.setSpacing(10)
        hbox.addWidget(self._btn_clipboard)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self._table)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def populate(self, barcodes):
        """ Called when a new row is selected on the record table. Displays all of the
        barcodes from the selected record in the barcode table. By default, valid barcodes are
        highlighted green, invalid barcodes are highlighted red, and empty slots are grey.
        """
        num_slots = len(barcodes)
        self._table.clearContents()
        self._table.setRowCount(num_slots)

        for index, barcode in enumerate(barcodes):
            # Select appropriate background color
            if barcode == NOT_FOUND_SLOT_SYMBOL:
                color = self._options.col_bad()
            elif barcode == EMPTY_SLOT_SYMBOL:
                color = self._options.col_empty()
            else:
                color = self._options.col_ok()

            color.a = 192

            # Set table item
            barcode = QtGui.QTableWidgetItem(barcode)
            barcode.setBackgroundColor(color.to_qt())
            barcode.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self._table.setItem(index, 0, barcode)

        self._barcodes = barcodes[:]
        for i, barcode in enumerate(self._barcodes):
            if barcode in [NOT_FOUND_SLOT_SYMBOL, EMPTY_SLOT_SYMBOL]:
                self._barcodes[i] = ""

        self._update_button_state()

    def _update_button_state(self):
        if self._barcodes is None or len(self._barcodes) == 0:
            self._btn_clipboard.setEnabled(False)
        else:
            self._btn_clipboard.setEnabled(True)

    def copy_selected_to_clipboard(self):
        """ Called when the copy to clipboard button is pressed. Copies the list/s of
        barcodes for the currently selected records to the clipboard so that the user
        can paste it elsewhere.
        """
        sep = os.linesep
        if self._barcodes:
            pyperclip.copy(sep.join(self._barcodes))
Ejemplo n.º 12
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.scriptPath, self.scriptArgs = "", []
        self.profilerPath, self.tempPath = profilerPath, tempPath
        self.output = " ERROR: FAIL: No output ! "

        self.process = QProcess()
        self.process.finished.connect(self.on_process_finished)
        self.process.error.connect(self.on_process_error)

        self.tabWidget, self.stat = QTabWidget(), QWidget()
        self.tabWidget.tabCloseRequested.connect(lambda:
            self.tabWidget.setTabPosition(1)
            if self.tabWidget.tabPosition() == 0
            else self.tabWidget.setTabPosition(0))
        self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}')
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.vboxlayout1 = QVBoxLayout(self.stat)
        self.hboxlayout1 = QHBoxLayout()
        self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat)
        self.hboxlayout1.addWidget(self.filterTableLabel)
        self.filterTableLineEdit = QLineEdit(self.stat)
        self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ')
        self.hboxlayout1.addWidget(self.filterTableLineEdit)
        self.filterHintTableLabel = QLabel(" ? ", self.stat)
        self.hboxlayout1.addWidget(self.filterHintTableLabel)
        self.vboxlayout1.addLayout(self.hboxlayout1)
        self.tableWidget = QTableWidget(self.stat)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setColumnCount(8)
        self.tableWidget.setRowCount(2)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(7, item)
        self.tableWidget.itemDoubleClicked.connect(
                                        self.on_tableWidget_itemDoubleClicked)
        self.vboxlayout1.addWidget(self.tableWidget)
        self.tabWidget.addTab(self.stat, " ? ")

        self.source = QWidget()
        self.gridlayout = QGridLayout(self.source)
        self.scintillaWarningLabel = QLabel(
            "QScintilla is not installed!. Falling back to basic text edit!.",
            self.source)
        self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2)
        self.sourceTreeWidget = QTreeWidget(self.source)
        self.sourceTreeWidget.setAlternatingRowColors(True)
        self.sourceTreeWidget.itemActivated.connect(
                                        self.on_sourceTreeWidget_itemActivated)
        self.sourceTreeWidget.itemClicked.connect(
                                          self.on_sourceTreeWidget_itemClicked)
        self.sourceTreeWidget.itemDoubleClicked.connect(
                                          self.on_sourceTreeWidget_itemClicked)

        self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1)
        self.sourceTextEdit = QTextEdit(self.source)
        self.sourceTextEdit.setReadOnly(True)
        self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1)
        self.tabWidget.addTab(self.source, " ? ")

        self.result = QWidget()
        self.vlayout = QVBoxLayout(self.result)
        self.globalStatGroupBox = QGroupBox(self.result)
        self.hboxlayout = QHBoxLayout(self.globalStatGroupBox)
        self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.totalTimeLcdNumber.setNumDigits(7)
        self.totalTimeLcdNumber.display(1000000)
        self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.totalTimeLcdNumber)
        self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>",
                                 self.globalStatGroupBox)
        self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum,
                                      QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.tTimeLabel)
        self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.numCallLcdNumber.setNumDigits(7)
        self.numCallLcdNumber.display(1000000)
        self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.numCallLcdNumber)
        self.numCallLabel = QLabel("<b>Number of calls</b>",
                                   self.globalStatGroupBox)
        self.numCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.numCallLabel)
        self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.primCallLcdNumber.setNumDigits(7)
        self.primCallLcdNumber.display(1000000)
        self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.primCallLcdNumber)
        self.primCallLabel = QLabel("<b>Primitive calls (%)</b>",
                                    self.globalStatGroupBox)
        self.primCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.primCallLabel)
        self.vlayout.addWidget(self.globalStatGroupBox)
        try:
            from PyKDE4.kdeui import KRatingWidget
            self.rating = KRatingWidget(self.globalStatGroupBox)
            self.rating.setToolTip('Profiling Performance Rating')
        except ImportError:
            pass
        self.tabWidget.addTab(self.result, " Get Results ! ")

        self.resgraph = QWidget()
        self.vlayout2 = QVBoxLayout(self.result)
        self.graphz = QGroupBox(self.resgraph)
        self.hboxlayout2 = QHBoxLayout(self.graphz)
        try:
            from PyKDE4.kdeui import KLed
            KLed(self.graphz)
        except ImportError:
            pass
        self.hboxlayout2.addWidget(QLabel('''
            Work in Progress  :)  Not Ready Yet'''))
        self.vlayout2.addWidget(self.graphz)
        self.tabWidget.addTab(self.resgraph, " Graphs and Charts ")

        self.pathz = QWidget()
        self.vlayout3 = QVBoxLayout(self.pathz)
        self.patz = QGroupBox(self.pathz)
        self.hboxlayout3 = QVBoxLayout(self.patz)
        self.profilepath = QLineEdit(profilerPath)
        self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open')
        self.getprofile.setToolTip('Dont touch if you dont know what are doing')
        self.getprofile.clicked.connect(lambda: self.profilepath.setText(str(
            QFileDialog.getOpenFileName(self.patz, ' Open the profile.py file ',
            path.expanduser("~"), ';;(profile.py)'))))
        self.hboxlayout3.addWidget(QLabel(
            '<center><b>Profile.py Python Library Full Path:</b></center>'))
        self.hboxlayout3.addWidget(self.profilepath)
        self.hboxlayout3.addWidget(self.getprofile)

        self.argGroupBox = QGroupBox(self.pathz)
        self.hbxlayout = QHBoxLayout(self.argGroupBox)
        self.argLineEdit = QLineEdit(self.argGroupBox)
        self.argLineEdit.setToolTip('Not touch if you dont know what are doing')
        self.argLineEdit.setPlaceholderText(
            'Dont touch if you dont know what are doing')
        self.hbxlayout.addWidget(QLabel('<b>Additional Profile Arguments:</b>'))
        self.hbxlayout.addWidget(self.argLineEdit)
        self.hboxlayout3.addWidget(self.argGroupBox)

        self.vlayout3.addWidget(self.patz)
        self.tabWidget.addTab(self.pathz, " Paths and Configs ")

        self.outp = QWidget()
        self.vlayout4 = QVBoxLayout(self.outp)
        self.outgro = QGroupBox(self.outp)
        self.outgro.setTitle(" MultiProcessing Output Logs ")
        self.hboxlayout4 = QVBoxLayout(self.outgro)
        self.outputlog = QTextEdit()
        self.outputlog.setText('''
        I do not fear computers, I fear the lack of them.   -Isaac Asimov ''')
        self.hboxlayout4.addWidget(self.outputlog)
        self.vlayout4.addWidget(self.outgro)
        self.tabWidget.addTab(self.outp, " Logs ")

        self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"),
                                           'New Profiling', self)
        self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"),
                                          'Open Profiling', self)
        self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean', self)
        self.actionClean.triggered.connect(lambda: self.clearContent)
        self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About', self)
        self.actionAbout.triggered.connect(lambda: QMessageBox.about(self.dock,
            __doc__, ', '.join((__doc__, __license__, __author__, __email__))))
        self.actionSave_profile = QAction(QIcon.fromTheme("document-save"),
                                          'Save Profiling', self)
        self.actionManual = QAction(QIcon.fromTheme("help-contents"),
                                    'Help', self)
        self.actionManual.triggered.connect(lambda:
                    open_new_tab('http://docs.python.org/library/profile.html'))

        self.tabWidget.setCurrentIndex(2)

        self.globalStatGroupBox.setTitle("Global Statistics")
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText("Number of Calls")
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText("Total Time")
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText("Cumulative Time")
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText("Filename")
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText("Line")
        item = self.tableWidget.horizontalHeaderItem(7)
        item.setText("Function")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat),
                                  "Statistics per Function")

        self.sourceTreeWidget.headerItem().setText(0, "Source files")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.source),
                                  "Sources Navigator")
        #######################################################################

        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(self.tabWidget)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        QToolBar(self.dock).addActions((self.actionNew_profiling,
            self.actionClean, self.actionSave_profile, self.actionLoad_profile,
            self.actionManual, self.actionAbout))

        self.actionNew_profiling.triggered.connect(
                                        self.on_actionNew_profiling_triggered)
        self.actionLoad_profile.triggered.connect(
                                        self.on_actionLoad_profile_triggered)
        self.actionSave_profile.triggered.connect(
                                        self.on_actionSave_profile_triggered)

        self.locator.get_service('misc').add_widget(self.dock,
                            QIcon.fromTheme("document-open-recent"), __doc__)

        if QSCI:
            # Scintilla source editor management
            self.scintillaWarningLabel.setText(' QScintilla is Ready ! ')
            layout = self.source.layout()
            layout.removeWidget(self.sourceTextEdit)
            self.sourceTextEdit = Qsci.QsciScintilla(self.source)
            layout.addWidget(self.sourceTextEdit, 0, 1)
            doc = self.sourceTextEdit
            doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit))
            doc.setReadOnly(True)
            doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine)
            doc.setEdgeColumn(80)
            doc.setEdgeColor(QColor("#FF0000"))
            doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle)
            doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch)
            doc.setCaretLineVisible(True)
            doc.setMarginLineNumbers(1, True)
            doc.setMarginWidth(1, 25)
            doc.setTabWidth(4)
            doc.setEolMode(Qsci.QsciScintilla.EolUnix)
            self.marker = {}
            for color in COLORS:
                mnr = doc.markerDefine(Qsci.QsciScintilla.Background)
                doc.setMarkerBackgroundColor(color, mnr)
                self.marker[color] = mnr
        self.currentSourcePath = None

        # Connect table and tree filter edit signal to unique slot
        self.filterTableLineEdit.textEdited.connect(
                                            self.on_filterLineEdit_textEdited)

        # Timer to display filter hint message
        self.filterHintTimer = QTimer(self)
        self.filterHintTimer.setSingleShot(True)
        self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout)

        # Timer to start search
        self.filterSearchTimer = QTimer(self)
        self.filterSearchTimer.setSingleShot(True)
        self.filterSearchTimer.timeout.connect(
                                            self.on_filterSearchTimer_timeout)

        self.tabLoaded = {}
        for i in range(10):
            self.tabLoaded[i] = False
        self.backgroundTreeMatchedItems = {}
        self.resizeWidgetToContent(self.tableWidget)

    def on_actionNew_profiling_triggered(self):
        self.clearContent()
        self.scriptPath = str(QFileDialog.getOpenFileName(self.dock,
            "Choose your script to profile", path.expanduser("~"),
            "Python (*.py *.pyw)"))
        commandLine = [self.profilerPath, "-o", self.tempPath,
                       self.scriptPath] + self.scriptArgs
        commandLine = " ".join(commandLine)
        ##if self.termCheckBox.checkState() == Qt.Checked:
        #termList = ["xterm", "aterm"]
        #for term in termList:
            #termPath = which(term)
            #if termPath:
                #break
        #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \
                      #% (termPath, commandLine)
        self.process.start(commandLine)
        if not self.process.waitForStarted():
            print((" ERROR: {} failed!".format(commandLine)))
            return

    def on_process_finished(self, exitStatus):
        ' whan the process end '
        print((" INFO: OK: QProcess is %s" % self.process.exitCode()))
        self.output = self.process.readAll().data()
        if not self.output:
            self.output = " ERROR: FAIL: No output ! "
        self.outputlog.setText(self.output + str(self.process.exitCode()))
        if path.exists(self.tempPath):
            self.setStat(self.tempPath)
            remove(self.tempPath)
        else:
            self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.")
        self.tabWidget.setCurrentIndex(2)

    def on_process_error(self, error):
        ' when the process fail, I hope you never see this '
        print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ")
        if error == QProcess.FailedToStart:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ")
        elif error == QProcess.Crashed:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ")
        else:
            self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ")

    def on_actionLoad_profile_triggered(self):
        """Load a previous profile sessions"""
        statPath = str(QFileDialog.getOpenFileName(self.dock,
            "Open profile dump", path.expanduser("~"), "Profile file (*)"))
        if statPath:
            self.clearContent()
            print(' INFO: OK: Loading profiling from ' + statPath)
            self.setStat(statPath)

    def on_actionSave_profile_triggered(self):
        """Save a profile sessions"""
        statPath = str(QFileDialog.getSaveFileName(self.dock,
                "Save profile dump", path.expanduser("~"), "Profile file (*)"))
        if statPath:
            #TODO: handle error case and give feelback to user
            print(' INFO: OK: Saving profiling to ' + statPath)
            self.stat.save(statPath)

    #=======================================================================#
    # Common parts                                                          #
    #=======================================================================#

    def on_tabWidget_currentChanged(self, index):
        """slot for tab change"""
        # Kill search and hint timer if running to avoid cross effect
        for timer in (self.filterHintTimer, self.filterSearchTimer):
            if timer.isActive():
                timer.stop()
        if not self.stat:
            #No stat loaded, nothing to do
            return
        self.populateTable()
        self.populateSource()

    def on_filterLineEdit_textEdited(self, text):
        """slot for filter change (table or tree"""
        if self.filterSearchTimer.isActive():
            # Already runnning, stop it
            self.filterSearchTimer.stop()
        # Start timer
        self.filterSearchTimer.start(300)

    def on_filterHintTimer_timeout(self):
        """Timeout to warn user about text length"""
        print("timeout")
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            label = self.filterHintTableLabel
        label.setText("Type > 2 characters to search")

    def on_filterSearchTimer_timeout(self):
        """timeout to start search"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            text = self.filterTableLineEdit.text()
            label = self.filterHintTableLabel
            edit = self.filterTableLineEdit
            widget = self.tableWidget
        else:
            print("Unknow tab for filterSearch timeout !")

        print(("do search for %s" % text))
        if not len(text):
            # Empty keyword, just clean all
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")
            self.warnUSer(True, edit)
            self.clearSearch()
            return
        if len(text) < 2:
            # Don't filter if text is too short and tell it to user
            self.filterHintTimer.start(600)
            return
        else:
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")

        # Search
        self.clearSearch()
        matchedItems = []
        if tab == TAB_FUNCTIONSTAT:
            # Find items
            matchedItems = widget.findItems(text, Qt.MatchContains)
            widget.setSortingEnabled(False)
            matchedRows = [item.row() for item in matchedItems]
            # Hide matched items
            header = widget.verticalHeader()
            for row in range(widget.rowCount()):
                if row not in matchedRows:
                    header.hideSection(row)
            widget.setSortingEnabled(True)
        else:
            print(" Unknow tab for filterSearch timeout ! ")

        print(("got %s members" % len(matchedItems)))
        self.warnUSer(matchedItems, edit)
        self.resizeWidgetToContent(widget)

    def resizeWidgetToContent(self, widget):
        """Resize all columns according to content"""
        for i in range(widget.columnCount()):
            widget.resizeColumnToContents(i)

    def clearSearch(self):
        """Clean search result
        For table, show all items
        For tree, remove colored items"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            header = self.tableWidget.verticalHeader()
            if header.hiddenSectionCount():
                for i in range(header.count()):
                    if header.isSectionHidden(i):
                        header.showSection(i)

    def clearContent(self):
        # Clear tabs
        self.tableWidget.clearContents()
        self.sourceTreeWidget.clear()
        # Reset LCD numbers
        for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber,
                          self.primCallLcdNumber):
            lcdNumber.display(1000000)
        # Reset stat
        self.pstat = None
        # Disable save as menu
        self.actionSave_profile.setEnabled(False)
        # Mark all tabs as unloaded
        for i in range(10):
            self.tabLoaded[i] = False

    def warnUSer(self, result, inputWidget):
        palette = inputWidget.palette()
        if result:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 255, 255))
        else:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 136, 138))
        inputWidget.setPalette(palette)
        inputWidget.update()

    def setStat(self, statPath):
        self.stat = Stat(path=statPath)
        # Global stat update
        self.totalTimeLcdNumber.display(self.stat.getTotalTime())
        self.numCallLcdNumber.display(self.stat.getCallNumber())
        self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio())
        # Refresh current tab
        self.on_tabWidget_currentChanged(self.tabWidget.currentIndex())
        # Activate save as menu
        self.actionSave_profile.setEnabled(True)
        try:
            self.rating.setMaxRating(10)
            self.rating.setRating(
                                int(self.stat.getPrimitiveCallRatio()) / 10 - 1)
        except:
            pass

    #========================================================================#
    # Statistics table                                                      #
    #=======================================================================#

    def populateTable(self):
        row = 0
        rowCount = self.stat.getStatNumber()
        progress = QProgressDialog("Populating statistics table...",
                                         "Abort", 0, 2 * rowCount)
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setRowCount(rowCount)

        progress.setWindowModality(Qt.WindowModal)
        for (key, value) in self.stat.getStatItems():
            #ncalls
            item = StatTableWidgetItem(str(value[0]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_NCALLS, item)
            colorTableItem(item, self.stat.getCallNumber(), value[0])
            #total time
            item = StatTableWidgetItem(str(value[2]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[2])
            #per call (total time)
            if value[0] != 0:
                tPerCall = str(value[2] / value[0])
                cPerCall = str(value[3] / value[0])
            else:
                tPerCall = ""
                cPerCall = ""
            item = StatTableWidgetItem(tPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TPERCALL, item)
            colorTableItem(item, 100.0 * self.stat.getTotalTime() /
                           self.stat.getCallNumber(), tPerCall)
            #per call (cumulative time)
            item = StatTableWidgetItem(cPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CPERCALL, item)
            colorTableItem(item, 100.0 * self.stat.getTotalTime() /
                           self.stat.getCallNumber(), cPerCall)
            #cumulative time
            item = StatTableWidgetItem(str(value[3]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[3])
            #Filename
            self.tableWidget.setItem(row, STAT_FILENAME,
                                        StatTableWidgetItem(str(key[0])))
            #Line
            item = StatTableWidgetItem(str(key[1]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_LINE, item)
            #Function name
            self.tableWidget.setItem(row, STAT_FUNCTION,
                                        StatTableWidgetItem(str(key[2])))
            row += 1
            # Store it in stat hash array
            self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT)
            progress.setValue(row)
            if progress.wasCanceled():
                return

        for i in range(self.tableWidget.rowCount()):
            progress.setValue(row + i)
            for j in range(self.tableWidget.columnCount()):
                item = self.tableWidget.item(i, j)
                if item:
                    item.setFlags(Qt.ItemIsEnabled)

        self.tableWidget.setSortingEnabled(True)
        self.resizeWidgetToContent(self.tableWidget)
        progress.setValue(2 * rowCount)

    def on_tableWidget_itemDoubleClicked(self, item):
        matchedItems = []
        filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text())
        if not filename or filename.startswith("<"):
            # No source code associated, return immediatly
            return
        function = self.tableWidget.item(item.row(), STAT_FUNCTION).text()
        line = self.tableWidget.item(item.row(), STAT_LINE).text()

        self.on_tabWidget_currentChanged(TAB_SOURCE)  # load source tab
        function = "%s (%s)" % (function, line)
        fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains,
                                                  SOURCE_FILENAME)
        print(("find %s father" % len(fathers)))
        for father in fathers:
            findItems(father, function, SOURCE_FILENAME, matchedItems)
        print(("find %s items" % len(matchedItems)))

        if matchedItems:
            self.tabWidget.setCurrentIndex(TAB_SOURCE)
            self.sourceTreeWidget.scrollToItem(matchedItems[0])
            self.on_sourceTreeWidget_itemClicked(matchedItems[0],
                                                 SOURCE_FILENAME)
            matchedItems[0].setSelected(True)
        else:
            print("oups, item found but cannot scroll to it !")

    #=======================================================================#
    # Source explorer                                                      #
    #=====================================================================#

    def populateSource(self):
        items = {}
        for stat in self.stat.getStatKeys():
            source = stat[0]
            function = "%s (%s)" % (stat[2], stat[1])
            if source in ("", "profile") or source.startswith("<"):
                continue
            # Create the function child
            child = QTreeWidgetItem([function])
            # Store it in stat hash array
            self.stat.setStatLink(child, stat, TAB_SOURCE)
            if source in items:
                father = items[source]
            else:
                # Create the father
                father = QTreeWidgetItem([source])
                items[source] = father
            father.addChild(child)
        self.sourceTreeWidget.setSortingEnabled(False)
        for value in list(items.values()):
            self.sourceTreeWidget.addTopLevelItem(value)
        self.sourceTreeWidget.setSortingEnabled(True)

    def on_sourceTreeWidget_itemActivated(self, item, column):
        self.on_sourceTreeWidget_itemClicked(item, column)

    def on_sourceTreeWidget_itemClicked(self, item, column):
        line = 0
        parent = item.parent()
        if QSCI:
            doc = self.sourceTextEdit
        if parent:
            pathz = parent.text(column)
            result = match("(.*) \(([0-9]+)\)", item.text(column))
            if result:
                try:
                    function = str(result.group(1))
                    line = int(result.group(2))
                except ValueError:
                    # We got garbage... falling back to line 0
                    pass
        else:
            pathz = item.text(column)
        pathz = path.abspath(str(pathz))
        if self.currentSourcePath != pathz:
            # Need to load source
            self.currentSourcePath == pathz
            try:
                if QSCI:
                    doc.clear()
                    doc.insert(file(pathz).read())
                else:
                    self.sourceTextEdit.setPlainText(file(pathz).read())
            except IOError:
                QMessageBox.warning(self,
                                     "Error", "Source file could not be found",
                                     QMessageBox.Ok)
                return

            if QSCI:
                for function, line in [(i[2], i[1]
                           ) for i in self.stat.getStatKeys() if i[0] == pathz]:
                    # expr, regexp, case sensitive, whole word, wrap, forward
                    doc.findFirst("def", False, True, True, False, True, line,
                                  0, True)
                    end, foo = doc.getCursorPosition()
                    time = self.stat.getStatTotalTime((pathz, line, function))
                    colorSource(doc, self.stat.getTotalTime(), time, line, end,
                                self.marker)
        if QSCI:
            doc.ensureLineVisible(line)
Ejemplo n.º 13
0
class SentenceFillDlg(QDialog, ui_sentencefilldlg.Ui_SentenceFillDlg):
	
	def __init__(self, tableName, rangeValues, parent=None):
		super(SentenceFillDlg, self).__init__(parent)
		self.tableName = tableName
		self.rangeValues = rangeValues
		self.setupUi(self)
		self.initUI()
		
	def initUI(self):
		fontLabel = QFont('SansSerif', 14)
		
		self.setMinimumSize(1200, 600)
		self.resize(1200, 600)
		
		self.sentenceToFillTable = QTableWidget(5, 1, self)
		self.sentenceToFillTable.setGeometry(QRect(70, 60, 800, 400))
		
		self.sentenceToFillTable.setColumnCount(1)
		
		item = QTableWidgetItem()
		item.setText('Sentences To Match')
		font = QFont()
		font.setBold(True)
		font.setWeight(75)
		item.setFont(font)
		self.sentenceToFillTable.setHorizontalHeaderItem(0, item)
		self.sentenceToFillTable.resizeColumnsToContents()
		self.sentenceToFillTable.horizontalHeader().setStretchLastSection(True)
		self.sentenceToFillTable.verticalHeader().setStretchLastSection(True)
		
		self.sentenceList = []
		self.getSentencesFromDatabase()
		
		# split the sentences into chunks of 5
		# Map to hold the anwers
		self.rightWordList = {}
		
		self.iteration = 0
		self.sentenceMasterList = []
		self.sentenceSlaveList = []
		
		if len(self.sentenceList) > 0:			
			for sentence in self.sentenceList:
				if len(self.sentenceSlaveList) < 5:
					self.sentenceSlaveList.append(sentence)
				else:
					self.sentenceMasterList.append(self.sentenceSlaveList)
					self.sentenceSlaveList = []
					self.sentenceSlaveList.append(sentence)
					
			if len(self.sentenceSlaveList) <= 5:
				self.sentenceMasterList.append(self.sentenceSlaveList)
				
			self.maxIteration = len(self.sentenceMasterList)
		
		
		## set the row height
		self.tableHeightSize = 0
		## Only if there is atleast one sentence fetched from the database
		if len(self.sentenceList) > 0:			
			for index in range(0, 5):
				if len(self.sentenceList[index]) < 150:
					self.sentenceToFillTable.verticalHeader().resizeSection(index, 80)
					self.tableHeightSize = self.tableHeightSize + 90
				elif len(self.sentenceList[index]) < 200:
					self.sentenceToFillTable.verticalHeader().resizeSection(index, 100)
					self.tableHeightSize = self.tableHeightSize + 100
				else:
					self.sentenceToFillTable.verticalHeader().resizeSection(index, 120)
					self.tableHeightSize = self.tableHeightSize + 120
			
				
			# split words from databse into chunks of 5
		
			self.refIteration = 0
			self.refWordMasterList = []
			self.refWordSlaveList = []
			for wordList in self.wordMap.values():
				if len(self.refWordSlaveList) < 5:
					self.refWordSlaveList.append(wordList)
				else:
					self.refWordMasterList.append(self.refWordSlaveList)
					self.refWordSlaveList = []
					self.refWordSlaveList.append(wordList)
			
			if len(self.refWordSlaveList) <= 5:
				self.refWordMasterList.append(self.refWordSlaveList)
				
			self.refMaxIteration = len(self.refWordMasterList)
		
			self.insertSentencesInTable()
		
		self.connect(self.sentenceToFillTable, SIGNAL("cellClicked(int, int)"), self.itemSelect)
		
		# create next, submit and close buttons
		self.nextButton = QPushButton('Next', self)
		self.nextButton.move(170, 520)
		self.nextButton.setEnabled(False)  
		
		self.submitButton = QPushButton('Submit', self)
		self.submitButton.move(380, 520)
		
		self.closeButton = QPushButton('Close', self)
		self.closeButton.move(600, 520)
		
		self.connect(self.closeButton, SIGNAL('clicked()'), self.closeClicked)
		
		self.connect(self.submitButton, SIGNAL('clicked()'), self.onSubmitClicked)
		
		self.connect(self.nextButton, SIGNAL('clicked()'), self.onNextClicked)
		
		self.setWindowTitle('Sentence Fill')
		
		#self.setGeometry(10, 80, 1100, 750)


	def getSentencesFromDatabase(self):
		self.twoTypeList = data.Data().getSentencesFromDatabase(self.tableName, self.rangeValues)
		if len(self.twoTypeList) == 2:
			self.sentenceList = self.twoTypeList[0]
			self.wordMap = self.twoTypeList[1]

	def closeClicked(self):
		reply = QMessageBox.question(self,
					"Fill the Sentences",
					"You want to close the application",
					QMessageBox.Yes | QMessageBox.No)
		if reply == QMessageBox.Yes:
			self.reject()
			
	def onNextClicked(self):
		if not self.iteration < self.maxIteration:
			QMessageBox.information(self,
					"Fill the Sentences",
					"All Sentences are matched",
					QMessageBox.Ok)
		else:
			self.sentenceToFillTable.clearContents()
			## Fetch the next records
			self.refIteration = self.refIteration + 1
			self.rightWordList = {}
			## clear the contents of the combo box
			self.wordListComboBox.clear()
			self.insertSentencesInTable()
	
	# validate whether the user has matched the blanks with a value during next and submit button clicks
	def onNextSubmitValidation(self):
		self.textNotFilled = False
		for row in range(0, len(self.currentSentenceListInTable)):
			if self.sentenceToFillTable.item(row, 0).text() == self.currentSentenceListInTable[row]:
				self.textNotFilled = True
		if self.textNotFilled:
			QMessageBox.information(self,
						"Fill the sentences",
						"Match all the sentences in the table",
						QMessageBox.Ok)
			self.nextButton.setEnabled(False)
			
			
	def onSubmitClicked(self):
		self.wordsMatched = True
		self.allWordsMatched = True
		brushRed = QBrush(QColor(255,0,0))
		brushRed.setStyle(Qt.SolidPattern)
		
		brushGreen = QBrush(QColor(0,255,0))
		brushGreen.setStyle(Qt.SolidPattern)
		
		# validate whether the user all matched the blanks with a value
		#self.onNextSubmitValidation()
		textNotFilled = False
		for row in range(0, len(self.currentSentenceListInTable)):
			if self.sentenceToFillTable.item(row, 0).text() == self.currentSentenceListInTable[row]:
				textNotFilled = True
		if textNotFilled:
			QMessageBox.information(self,
						"Fill the sentences",
						"Match all the sentences in the table",
						QMessageBox.Ok)
		else:
			splittedSentence = []
			foundWordInSentence = ""
			self.rightWordListCopy = self.rightWordList
			for row in range(0, len(self.currentSentenceListInTable)):
				sentenceFilled = str(self.sentenceToFillTable.item(row, 0).text())
				newSplittedSentence = [word.strip() for word in sentenceFilled.split()]
				splittedSentence = []
				for word in newSplittedSentence:
					match = re.search(r'\w+', word)
					if match:
						splittedSentence.append(str(match.group()))
				
				wordList = self.rightWordListCopy[row]
				
				if len(wordList) > 1:
					firstWord = wordList[0].strip()
					secondWord = wordList[1].strip()
					if ' ' in firstWord:
						for word in firstWord.split():
							if word not in splittedSentence:
								self.wordsMatched = False
					else:
						if firstWord not in splittedSentence:
							self.wordsMatched = False
					
					if self.wordsMatched: ## check is valid only if the first word is matched
						if ' ' in secondWord:
							for word in secondWord.split():
								if word not in splittedSentence:
									self.wordsMatched = False
						else:
							if secondWord not in splittedSentence:
								self.wordsMatched = False
				elif len(wordList) == 1:
					word = wordList[0].strip()
					if word not in splittedSentence:
						self.wordsMatched = False
				
				if self.wordsMatched:
					self.sentenceToFillTable.item(row, 0).setBackground(brushGreen)
				else:
					self.sentenceToFillTable.item(row, 0).setBackground(brushRed)
					self.allWordsMatched = False
				
				self.wordsMatched = True
					
			if self.allWordsMatched:
				self.nextButton.setEnabled(True)
				QMessageBox.information(self,
								"Fill the sentences",
								"All sentences are matched",
								QMessageBox.Ok)

	def insertSentencesInTable(self):
		if self.iteration < self.maxIteration:
			cellList = []
			self.col = 0
			self.currentSentenceListInTable = self.sentenceMasterList[self.iteration]
			for sentence in self.currentSentenceListInTable:
				item = QTableWidgetItem(QString(sentence))
				item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
								Qt.ItemIsEnabled))
				cellList.append(item)
			cellList.reverse()
			
			for index in range(0, len(self.currentSentenceListInTable)):
				self.sentenceToFillTable.setItem(index, self.col, cellList.pop())
				
			self.sentenceToFillTable.setRowCount(len(self.sentenceMasterList[self.iteration]))
			
			self.sentenceToFillTable.setFixedHeight(self.tableHeightSize)
			
			# increment the count for the next button click
			self.iteration = self.iteration + 1
			
	def createComboBox(self, rowIndex):
		self.xAxis = 1000
		self.yAxis = 80
		
		if self.refIteration < self.refMaxIteration:
			wordListWithFiveArrays = self.refWordMasterList[self.refIteration]
			requiredWordList = wordListWithFiveArrays[rowIndex]
			
			## Create a combo box
			self.wordListComboBox = QComboBox(self)
			self.wordListComboBox.setGeometry(900, 80, 100, 20)
			self.connect(self.wordListComboBox, SIGNAL("currentIndexChanged(int)"),
							self.wordSelected)
			self.wordListComboBox.show()
			
			## save the right word
			if len(requiredWordList) > 0:
				if rowIndex not in self.rightWordList.keys():
					if len(requiredWordList) > 0:
						wordList = requiredWordList[0].split('&')
						self.rightWordList[rowIndex] = wordList

			## insert words in the combo box
			random.shuffle(requiredWordList)
			random.shuffle(requiredWordList)
			
			self.wordListComboBox.addItem('         ')
			self.wordListComboBox.addItems(requiredWordList)
	
	def wordSelected(self):
		## Avoid the blank option
		if len(str(self.wordListComboBox.currentText()).strip()) > 0:
			sentence = self.currentSentenceListInTable[self.selectedSentenceIndex]
			splittedText = sentence.split('-')
			if len(splittedText) == 2:
				item = QTableWidgetItem(QString(splittedText[0] +
						str(self.wordListComboBox.currentText()) + ' ' + splittedText[1].strip()))
				item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | 
								Qt.ItemIsEnabled))
				self.sentenceToFillTable.setItem(self.selectedSentenceIndex, 0, item)
			elif len(splittedText) > 2:
				wordsFromCombobox = str(self.wordListComboBox.currentText()).split('&')
				item = QTableWidgetItem(QString(splittedText[0] + wordsFromCombobox[0]
							+ splittedText[1] + wordsFromCombobox[1] + ' ' + splittedText[2].strip()))
				item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | 
							Qt.ItemIsEnabled))
				self.sentenceToFillTable.setItem(self.selectedSentenceIndex, 0, item)
	
	def createIndexForWords(self):
		self.indexForWords = {}
		self.nextIndex = 0
		for word in self.refWordListForIndex:
			if self.nextIndex == 5:
				break
			self.indexForWords[word] = self.nextIndex
			self.nextIndex = self.nextIndex + 1
	
	def itemSelect(self,rowIndex):
		self.createComboBox(rowIndex)
		self.selectedSentenceIndex = rowIndex
Ejemplo n.º 14
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)

        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)

        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView

        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)

        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)
        self.table.setHorizontalHeaderLabels(
            ['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)

        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows)
        self.table.doubleClicked.connect(self._captureDoubleClick)

        layout.addWidget(self.table, 1, 0, 3, 2)

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)

        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)

        # Set dialog layout
        self.setLayout(layout)

    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value

        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames[
                'Standard Object Features']:
            box = QMessageBox(
                QMessageBox.Warning, 'Warning',
                'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                QMessageBox.NoButton, self)
            box.show()
            return

        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        # Compute object features and number of labels per frame
        def compute_features():
            features = self.topLevelOperatorView.ObjectFeatures([]).wait()
            labels = self.topLevelOperatorView.LabelInputs([]).wait()
            return features, labels

        req = Request(compute_features)
        req.notify_finished(self._populateTable)
        req.submit()

    @threadRouted
    def _populateTable(self, features_and_labels):
        features, labels = features_and_labels
        self.progressBar.hide()
        self.computeButton.setEnabled(True)

        for frame, objectFeatures in features.iteritems():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())

            # Get max and min object areas
            areas = objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])

            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[frame])

            # Load fram number
            item = QTableWidgetItem(str(frame))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 0, item)

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(maxObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 1, item)

            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(minObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 2, item)

            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(
                str("{: .01f}".format(labelNum)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 3, item)

        # Resize column size to fit dialog size
        self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch)

        # Sort by max object area
        self.table.setSortingEnabled(True)
        self.table.sortByColumn(1)

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()

        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Ejemplo n.º 15
0
class RemoveSentencesDlg(QDialog):
	
	def __init__(self):
		super(RemoveSentencesDlg, self).__init__()
		self.removeList = {}
		self.initUI()
		
	def initUI(self):
		## create a font type for the label
		fontLabel = QFont('SansSerif', 14)
		## create a label 
		self.label = QLabel(self)
		self.label.setAutoFillBackground(True)
		self.label.setAlignment(Qt.AlignCenter)
		self.label.setGeometry(QRect(200, 10, 400, 40))
		self.label.setFont(fontLabel)
		
		## set the text for the Label
		self.label.setText('Remove the Sentences')
		
		## Create a Table to hold all the sentences
		self.sentenceTable = QTableWidget(self)
		## set the size and the position of the table
		self.sentenceTable.setGeometry(QRect(10, 60, 800, 400))
		
		## set the column count for the table
		self.sentenceTable.setColumnCount(1)
		
		sentenceHeaderList = ['Sentences From Table']
		
		self.sentenceTable.setHorizontalHeaderLabels(sentenceHeaderList)
		self.sentenceTable.resizeColumnsToContents()
		self.sentenceTable.horizontalHeader().setStretchLastSection(True)
		self.sentenceTable.verticalHeader().setStretchLastSection(True)
		
		# Create a Remove button
		self.removeButton = QPushButton('Remove', self)
		self.removeButton.move(350, 600)
		
		# Create a close button
		self.closeButton = QPushButton('Close', self)
		self.closeButton.move(450, 600)
		
		## Create signal for the remove button 
		self.connect(self.removeButton, SIGNAL("clicked()"), self.onRemoveClicked)
		
		## Create signal for the close button
		self.connect(self.closeButton, SIGNAL("clicked()"), self.closeClicked)
		
		## Create signal for the sentence table
		self.connect(self.sentenceTable, SIGNAL('cellClicked(int, int)'), self.sentenceStateChanged)
		
		## Get sentences from the database table
		self.getSentencesFromDatabase()
		
		
		self.setGeometry(800, 800, 900, 650)
		
	def getSentencesFromDatabase(self):
		## returns the sentence and the corresponding word associated with it
		self.twoTypeList = data.Data().getSentencesFromDatabase()
		if len(self.twoTypeList) == 2:
			self.sentenceList = self.twoTypeList[0]
			
		## load the sentences in the Table Widget
		self.loadSentencesInTable()
	
	def loadSentencesInTable(self):
		self.col = 0
		if len(self.sentenceList) > 0:
			self.sentenceTable.setRowCount(len(self.sentenceList))
			cellList = []
			## Create QTableWidgetItems from the sentence list
			for sentence in self.sentenceList:
				item = QTableWidgetItem(QString(sentence))
				item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
								Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
				item.setCheckState(Qt.Unchecked)
				cellList.append(item)
			cellList.reverse()
			# set the widget items in the table
			for item in range(0, len(self.sentenceList)):
				self.sentenceTable.setItem(item, self.col, cellList.pop())
			
			for index in range(0, len(self.sentenceList)):
				self.sentenceTable.verticalHeader().resizeSection(index, 100)
			
			if len(self.sentenceList) == 5:
				self.sentenceTable.setFixedHeight(500)
			if len(self.sentenceList) == 4:
				self.sentenceTable.setFixedHeight(400)
			elif len(self.sentenceList) == 3:
				self.sentenceTable.setFixedHeight(300)
			elif len(self.sentenceList) == 2:
				self.sentenceTable.setFixedHeight(200)
			elif len(self.sentenceList) == 1:
				self.sentenceTable.setFixedHeight(100)
		else:
			self.sentenceTable.clearContents()
		
	def sentenceStateChanged(self, row, col):
		if (self.sentenceTable.item(row, col).checkState() == 2):
			self.removeList[row] = self.sentenceTable.item(row, col).text()
			self.sentenceTable.item(row, col).setFlags(Qt.ItemFlags(Qt.ItemIsEditable |
									Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable))
		else:
			self.sentenceTable.item(row,col).setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
									Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
			del self.removeList[row]
	
	def onRemoveClicked(self):
		if len(self.removeList) == 0:
			QMessageBox.information(self, 'Remove Sentences',
					'Select the Sentences to Delete')
		else:
			reply = QMessageBox.question(self,
						'Remove Sentences',
						'You want to delete the selected sentences',
						QMessageBox.Yes | QMessageBox.No)
			if reply == QMessageBox.Yes:
				for sentence in self.removeList:
					if sentence in self.sentenceList:
						self.sentenceList.remove(sentence)
				
				## clear the contents of the Table
				self.sentenceTable.clearContents()
				
				cellList = []
				## Add the new entries into the table
				for sentence in self.sentenceList:
					item = QTableWidgetItem(QString(sentence))
					item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable |
									Qt.ItemIsUserCheckable | Qt.ItemIsEnabled))
					item.setCheckState(Qt.Unchecked)
					cellList.append(item)
				cellList.reverse()
				
				for index in range(0, len(self.sentenceList)):
					self.sentenceTable.setItem(index, self.col, cellList.pop())
					
				self.sentenceTable.setRowCount(len(self.sentenceList))
				
				deleteSentences = []
				for sentence in self.removeList.values():
					deleteSentences.append(sentence)
				
				rowsDeletec = data.Data().deleteSentencesFromDatabase(deleteSentences)
				self.getSentencesFromDatabase()
				
				self.removeList = {}
	
	def closeClicked(self):
		reply = QMessageBox.question(self,
				"Remove Sentences",
				"Do you want to close the application",
				QMessageBox.Yes | QMessageBox.No)
		if reply == QMessageBox.Yes:
			self.reject()
Ejemplo n.º 16
0
class MainWidget(QMainWindow):


    def __init__(self, parent=None):
        super(MainWidget, self).__init__(
                parent,
                windowTitle='GithubRemote',
                windowIcon=QIcon(image_path('git.png')),
                geometry=QRect(300, 300, 600, 372))

        self.repo_pixmap = QPixmap(image_path('book_16.png'))
        self.big_repo_pixmap = QPixmap(image_path('book_32.png'))
        self.repo_fork_pixmap = QPixmap(image_path('book_fork_16.png'))
        self.star_pixmap = QPixmap(image_path('star_16.png'))
        self.big_star_pixmap = QPixmap(image_path('star_32.png'))
        self.fork_pixmap = QPixmap(image_path('fork_16.png'))
        self.eye_pixmap = QPixmap(image_path('eye_16.png'))

        self.github = None        

        # Actions

        self.repoAddAction = QAction(
                QIcon(image_path('plus_48.png')),
                '&Add Repo', self,
                statusTip='Add a new repo')
        self.repoAddAction.triggered.connect(self.repoAdd)
        
        self.repoRemoveAction = QAction(
                QIcon(image_path('minus.png')),
                '&Remove Repo', self,
                statusTip='Remove repo')
        self.repoRemoveAction.triggered.connect(self.repoRemove)

        self.repoRefreshAction = QAction(
                QIcon(image_path('refresh.png')),
                'Refresh', self,
                statusTip='Refresh list of repos')
        self.repoRefreshAction.triggered.connect(self.reposRefresh)
        self.repoRefreshAction.triggered.connect(self.starsRefresh)

        self.addAccountAction = QAction(
                'Add Account', self,
                statusTip='Add Account')
        self.addAccountAction.triggered.connect(self.addAccount)

        # userPushButton - Displays the current active username and 
        # image on the top right of the toolbar.
        
        self.userButtonMenu = UserButtonMenu(32,32)

        # ToolBar

        self.toolBar = self.addToolBar('Main')
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolBar.addAction(self.repoAddAction)
        self.toolBar.addAction(self.repoRemoveAction)
        self.toolBar.addAction(self.repoRefreshAction)
        self.toolBar.addWidget(spacer)
        self.toolBar.addWidget(self.userButtonMenu)

        # Menu

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        actionMenu = menuBar.addMenu('&Action')
        fileMenu.addAction(self.addAccountAction)
        actionMenu.addAction(self.repoAddAction)
        actionMenu.addAction(self.repoRemoveAction)
        actionMenu.addAction(self.repoRefreshAction)

        # StatusBar

        statusBar = self.statusBar()
        self.setStatusBar(statusBar)

        # reposTableWidget - Displays a list of the users repositories

        self.reposTableWidget = QTableWidget(0, 5,
                selectionBehavior = QAbstractItemView.SelectRows,
                selectionMode = QAbstractItemView.SingleSelection,
                editTriggers = QAbstractItemView.NoEditTriggers,
                itemSelectionChanged = self.actionsUpdate)
        self.reposTableWidget.horizontalHeader().setResizeMode(
                QHeaderView.ResizeToContents)
        self.reposTableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
        self.reposTableWidget.horizontalHeader().setVisible(False)
        self.reposTableWidget.verticalHeader().setVisible(False)
        self.reposTableWidget.setShowGrid(False)
        self.reposTableWidget.verticalHeader().setMinimumSectionSize(25)

        # repoTab - Layout
        reposTab = QWidget()
        reposTabLayout = QVBoxLayout(reposTab)
        reposTabLayout.addWidget(self.reposTableWidget)
        reposTab.setLayout(reposTabLayout)

        # starsTableWidget - Displays a list of the users repositories

        self.starsTableWidget = QTableWidget(0, 5,
                selectionBehavior = QAbstractItemView.SelectRows,
                selectionMode = QAbstractItemView.SingleSelection,
                editTriggers = QAbstractItemView.NoEditTriggers,
                itemSelectionChanged = self.actionsUpdate)
        self.starsTableWidget.horizontalHeader().setResizeMode(
                QHeaderView.ResizeToContents)
        self.starsTableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
        self.starsTableWidget.horizontalHeader().setVisible(False)
        self.starsTableWidget.verticalHeader().setVisible(False)
        self.starsTableWidget.setShowGrid(False)
        self.starsTableWidget.verticalHeader().setMinimumSectionSize(25)

        # repoTab - Layout
        starsTab = QWidget()
        starsTabLayout = QVBoxLayout(starsTab)
        starsTabLayout.addWidget(self.starsTableWidget)
        starsTab.setLayout(starsTabLayout)
        
        # Tab Widget
        self.tabs = QTabWidget()
        self.tabs.setTabBar(FlippedTabBar(self))
        self.tabs.addTab(reposTab, QIcon(self.big_repo_pixmap), "repos")
        self.tabs.addTab(starsTab, QIcon(self.big_star_pixmap), "stars")
        self.tabs.setTabPosition(QTabWidget.West)

        # Layout

        self.setCentralWidget(self.tabs)
        self.actionsUpdate()
        self.show()
        
        # Update

        self.loadUserMenu()
        if self.activeUserAction:
            self.activeUserAction.setVisible(False)
        self.authenticate()
        self.actionsUpdate()
        self.reposRefresh()
        self.starsRefresh()
        self.updateImage()

    
    @waiting_effects
    def updateImage(self):

        try:
            url = self.github.get_user().avatar_url
        except (GithubException, AttributeError): 
            return 
        data = urllib.urlopen(url).read()
        pixmap = QPixmap()
        pixmap.loadFromData(data)
        self.activeUserAction.setIcon(QIcon(pixmap))
        self.userButtonMenu.setPixmap(pixmap)
        self.userButtonMenu.setText(self.github.get_user().login)
   
    @waiting_effects
    def loadUserMenu(self):
        
        action = None
        for _, username, token in generate_tokens(CONFIG_PATH, 'github'):
            
            try:
                url = Github(token).get_user().avatar_url
            except (GithubException, AttributeError): 
                action = QAction(username, self, triggered=self.changeActive)
                self.userButtonMenu.addAction(action)
                continue
            data = urllib.urlopen(url).read()
            pixmap = QPixmap()
            pixmap.loadFromData(data)
            action = QAction(QIcon(pixmap), username, self,
                    triggered=self.changeActive)
            action.setIconVisibleInMenu(True)
            self.userButtonMenu.addAction(action)
        
        self.activeUserAction = action
    
    def changeActive(self):

        sender = self.sender()

        self.activeUserAction.setVisible(True)
        self.activeUserAction = sender
        self.activeUserAction.setVisible(False)
        self.authenticate()
        self.actionsUpdate()
        self.reposRefresh()
        self.starsRefresh()
        self.updateImage()

    @waiting_effects
    def reposRefresh(self):

        self.reposTableWidget.clearContents()

        try:
            repos = self.github.get_user().get_repos()
            self.reposTableWidget.setRowCount(self.github.get_user().public_repos)
        except (GithubException, AttributeError):
            return
        for row, repo in enumerate(repos):
            imageLabel = QLabel()
            if repo.fork:
                imageLabel.setPixmap(self.repo_fork_pixmap)
            else:
                imageLabel.setPixmap(self.repo_pixmap)
            imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            imageLabel.setMargin(5)

            self.reposTableWidget.setCellWidget(row, 0, imageLabel)
            label = QLabel('<b>{}</b><br />{}'.format(
                        str(repo.name), str(repo.description)))
            label.setAlignment(Qt.AlignVCenter)
            label.setMargin(5)
            label.setWordWrap(True)
            self.reposTableWidget.setCellWidget(row, 1, label)
            self.reposTableWidget.setItem(row, 2, 
                    QTableWidgetItem(QIcon(self.star_pixmap), str(repo.stargazers_count)))
            self.reposTableWidget.setItem(row, 3, 
                    QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count)))
            self.reposTableWidget.setItem(row, 4, 
                    QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count)))

        self.reposTableWidget.resizeRowsToContents()

    @waiting_effects
    def starsRefresh(self):

        self.starsTableWidget.clearContents()

        try:
            starred = self.github.get_user().get_starred()
            self.starsTableWidget.setRowCount(self.github.get_user().public_repos)
        except (GithubException, AttributeError):
            return
        for row, repo in enumerate(starred):
            imageLabel = QLabel()
            if repo.fork:
                imageLabel.setPixmap(self.repo_fork_pixmap)
            else:
                imageLabel.setPixmap(self.repo_pixmap)
            imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            imageLabel.setMargin(5)

            self.starsTableWidget.setCellWidget(row, 0, imageLabel)
            label = QLabel(u'<b>{}/{}</b><br />{}'.format(
                unicode(repo.owner.login), unicode(repo.name), unicode(repo.description)))
            label.setAlignment(Qt.AlignVCenter)
            label.setMargin(5)
            label.setWordWrap(True)
            self.starsTableWidget.setCellWidget(row, 1, label)
            self.starsTableWidget.setItem(row, 2, 
                    QTableWidgetItem(QIcon(self.star_pixmap), '0'))
            self.starsTableWidget.setItem(row, 3, 
                    QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count)))
            self.starsTableWidget.setItem(row, 4, 
                    QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count)))

        self.starsTableWidget.resizeRowsToContents()

    @waiting_effects
    def authenticate(self):
        
        if self.activeUserAction:
            username = str(self.activeUserAction.text())
            token = load_token(CONFIG_PATH, 'github', username) 
            self.github = Github(token)
        else:
            self.github = None

    
    def actionsUpdate(self):
        # TODO disable if no user is logged in
        if self.github is None:
            self.repoAddAction.setEnabled(False)
            self.repoRemoveAction.setEnabled(False)
            self.repoRefreshAction.setEnabled(False)
        else:
            self.repoAddAction.setEnabled(True)
            self.repoRefreshAction.setEnabled(True)
            if self._isARepoSelected():
                self.repoRemoveAction.setEnabled(True)
            else:
                self.repoRemoveAction.setEnabled(False)

    def addAccount(self):
        wizard = AddAccountWizard(self)
        if wizard.exec_():
            username = str(wizard.field('username').toString())
            token = str(wizard.field('token').toString())
            store_token(CONFIG_PATH, 'github', username, token)
            self.authenticate()
            self.reposRefresh()
            self.updateImage()
            self.actionsUpdate()

    def repoAdd(self):
        wizard = AddRepoWizard(self.github, self)
        if wizard.exec_():
            self.github.get_user().create_repo(
                str(wizard.field('name').toString()),
                description=str(wizard.field('description').toString()),
                private=bool(wizard.field('private').toBool()),
                auto_init=bool(wizard.field('auto_init').toBool()),
                gitignore_template=str(wizard.field('gitignore').toString()),
                homepage=str(wizard.field('homepage').toString()),
                has_wiki=bool(wizard.field('has_wiki').toBool()),
                has_downloads=bool(wizard.field('has_downloads').toBool()),
                has_issues=bool(wizard.field('has_issues').toBool()))
            self.reposRefresh()
    
    def repoRemove(self):
        
        row = self._selectedRepoRow()
        name = self.reposTableWidget.item(row, 0).text()
        dialog = RepoRemoveDialog(self.github, name)
        if dialog.exec_():
            self.github.get_user().get_repo(str(name)).delete()
            self.reposRefresh()

    def _isARepoSelected(self):
        """ Return True if a repo is selected else False """
        if len(self.reposTableWidget.selectedItems()) > 0:
            return True
        else:
            return False

    def _selectedRepoRow(self):
        """ Return the currently select repo """
        # TODO - figure out what happens if no repo is selected
        selectedModelIndexes = \
            self.reposTableWidget.selectionModel().selectedRows()
        for index in selectedModelIndexes:
            return index.row()
Ejemplo n.º 17
0
class DataItemWidget(QWidget):
    __EXTRA_COLUMN_WIDTH = 20

    def __init__(self, me_cls, data):
        QWidget.__init__(self)
        self.__me_cls = me_cls
        self.__setup_ui()
        self.__data = data
        self.__init_data()
        self.__connect_slot()

    def __setup_ui(self):

        v_layout = QVBoxLayout()

        self.__tool_widget = ToolWidget()

        self.__tool_widget.setMaximumHeight(40)

        self.__data_table_widget = QTableWidget()
        self.__data_table_widget.horizontalHeader().setStretchLastSection(True)
        self.__data_table_widget.horizontalHeader().setResizeMode(
            0, QHeaderView.Fixed)

        v_layout.setSpacing(0)
        v_layout.setContentsMargins(0, 0, 0, 0)
        v_layout.addWidget(self.__tool_widget, 0)
        v_layout.addWidget(self.__data_table_widget, 1)
        self.setLayout(v_layout)

    def __connect_slot(self):
        pass
        #self.connect(self.__tool_widget,SIGNAL('refresh_btn_clicked()'), self ,SLOT('__on_refresh_signal()'))

    def __init_data(self):

        self.__data_table_widget.clearContents()

        # init header
        #self.__colume_names = yt_connection.get_table_colume_names(self.__table_name)
        self.__colume_names = [x.field.name for x in self.__me_cls.attributes]
        #self.__colume_names.insert(0,'entity_id')

        #print self.__colume_names

        self.__data_table_widget.setColumnCount(len(self.__colume_names))
        head_list = QStringList()
        for colume in self.__colume_names:
            head_list << colume

        self.__data_table_widget.setHorizontalHeaderLabels(head_list)

        # default the header column both sides are coverd, these codes add __EXTRA_COLUMN_WIDTH to the header column width
        # and reise column width in function self.__adjust_table_colume()
        self.__data_table_widget.horizontalHeader().setResizeMode(
            QHeaderView.ResizeToContents)
        self.__record_colume_header_width()
        self.__data_table_widget.horizontalHeader().setResizeMode(
            QHeaderView.Interactive)

        self.__record_colume_header_width()

        show_data = []
        for entity_id, value in self.__data.items():
            item = value.obj_data.copy()
            item['managed_entity_id'] = entity_id
            show_data.append(item)

        self.__update_table(show_data)

        # init data
        # data = yt_connection.get_table_data(self.__table_name)
        #
        # self.__update_table(data)
        self.__adjust_table_colume()

    def __record_colume_header_width(self):
        count = self.__data_table_widget.columnCount()
        self.__column_widths = []
        for i in range(count):
            self.__column_widths.append(
                self.__data_table_widget.columnWidth(i) +
                self.__EXTRA_COLUMN_WIDTH)

    '''
    data like this
    [
    {u'direction': 'to-lport', 
    u'name': '[]', 
    u'priority': '100', 
    u'log': 'true', 
    u'action': 'drop', 
    u'external_ids': '{"neutron:lport"="5fb77332-2035-4f72-8e57-7415b02489c9"}', 
    u'match': '"outport==\\"inside-vm2\\""', 
    u'severity': '[]',
    'uuid': '2890a832-1c83-4b8e-8b40-2928817012cc'}
    ]

    '''

    def __update_table(self, data):
        self.__data_table_widget.clearContents()

        row_num = 0
        for row in data:
            self.__data_table_widget.insertRow(row_num)
            colume_num = 0
            for colume in self.__colume_names:
                if row.has_key(colume):
                    item_str = str(row[colume])
                else:
                    item_str = 'None'
                table_wid_item = QTableWidgetItem(item_str)
                table_wid_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)

                self.__data_table_widget.setItem(row_num, colume_num,
                                                 table_wid_item)
                colume_num += 1
            row_num += 1

    def __clear_table_data(self):
        row_count = self.__data_table_widget.rowCount()
        rev = [i for i in range(row_count)]
        rev.reverse()
        for i in rev:
            self.__data_table_widget.removeRow(i)

    def __adjust_table_colume(self):
        self.__data_table_widget.resizeColumnsToContents()
        count = self.__data_table_widget.columnCount()
        for i in range(count):
            col_wid = self.__data_table_widget.columnWidth(i)
            if col_wid < self.__column_widths[i]:
                self.__data_table_widget.setColumnWidth(
                    i, self.__column_widths[i])
Ejemplo n.º 18
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)
        
        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)
        
        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView
        
        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout() 
        layout.setContentsMargins(10, 10, 10, 10)
                       
        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)   
        self.table.setHorizontalHeaderLabels(['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)     
        
        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows);
        self.table.doubleClicked.connect(self._captureDoubleClick)
                
        layout.addWidget(self.table, 1, 0, 3, 2) 

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)
        
        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)
        
        # Set dialog layout
        self.setLayout(layout)       


    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value
        
        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames['Standard Object Features']:
            box = QMessageBox(QMessageBox.Warning,
                  'Warning',
                  'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                  QMessageBox.NoButton,
                  self)
            box.show()
            return 
        
        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        def compute_features_for_frame(tIndex, t, features): 
            # Compute features and labels (called in parallel from request pool)
            roi = [slice(None) for i in range(len(self.topLevelOperatorView.LabelImages.meta.shape))]
            roi[tIndex] = slice(t, t+1)
            roi = tuple(roi)

            frame = self.topLevelOperatorView.SegmentationImages(roi).wait()           
            frame = frame.squeeze().astype(numpy.uint32, copy=False)
            
            # Dirty trick: We don't care what we're passing here for the 'image' parameter,
            # but vigra insists that we pass *something*, so we'll cast the label image as float32.
            features[t] = vigra.analysis.extractRegionFeatures(frame.view(numpy.float32),
                                                               frame,
                                                               ['Count'],
                                                               ignoreLabel=0)
            
        tIndex = self.topLevelOperatorView.SegmentationImages.meta.axistags.index('t')
        tMax = self.topLevelOperatorView.SegmentationImages.meta.shape[tIndex]     
        
        features = {}
        labels = {}

        def compute_all_features():
            # Compute features in parallel
            pool = RequestPool()
            for t in range(tMax):
                pool.add( Request( partial(compute_features_for_frame, tIndex, t, features) ) )
            pool.wait()
            
        # Compute labels
        labels = self.topLevelOperatorView.LabelInputs([]).wait()
            
        req = Request(compute_all_features)
        req.notify_finished( partial(self._populateTable, features, labels) )
        req.submit()

    @threadRouted
    def _populateTable(self, features, labels, *args):
        self.progressBar.hide()
        self.computeButton.setEnabled(True)
                
        for time, feature in features.iteritems():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())
            
            # Get max and min object areas
            areas = feature['Count']#objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])
            
            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[time])
            
            # Load fram number
            item = QTableWidgetItem(str(time))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 0, item) 

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(maxObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 1, item)
                
            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(minObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 2, item)
            
            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(str("{: .01f}".format(labelNum)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 3, item)
        
        # Resize column size to fit dialog size
        self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch)   
        
        # Sort by max object area
        self.table.setSortingEnabled(True)                         
        self.table.sortByColumn(1) 
        

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()
        
        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Ejemplo n.º 19
0
class FormTable(QWidget):

    # -------------------------------------------------------------------------------------
    # Form signal(s)
    closingFormTable = pyqtSignal()
    deletingFormTable = pyqtSignal()
    # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------
    # Method init
    def __init__(self, parent=None):

        # -------------------------------------------------------------------------------------
        # Constructor
        super(FormTable, self).__init__(parent)

        self.setWindowTitle('Section Table')

        oLayout = QVBoxLayout()

        self.TableWidget = QTableWidget()

        self.BtnSave = QPushButton('Save', self)
        self.BtnCancel = QPushButton('Cancel', self)

        # Define layout
        oLayout.addWidget(self.TableWidget)
        oLayout.addWidget(self.BtnSave)
        oLayout.addWidget(self.BtnCancel)

        # Set layout
        self.setLayout(oLayout)
        self.oLayout = oLayout

        # Define action(s)
        self.BtnSave.pressed.connect(self.saveTable)
        self.BtnCancel.pressed.connect(self.cancelTable)

        # Show widget
        self.show()
        # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------
    # Method to set data
    def setData(self, oData):
        # Check data table
        if oData:

            iDataRows = len(oData)
            iDataCols = len(oData[0])

            self.TableWidget.setRowCount(iDataRows)
            self.TableWidget.setColumnCount(iDataCols)

            self.TableWidget.setHorizontalHeaderLabels(oFormSectionHeader)

            oTableHeader = self.TableWidget.horizontalHeader()
            oTableHeader.setStretchLastSection(True)

            iNL = None
            for iID, a1oLine in enumerate(oData):

                if iNL is None:
                    iNL = len(a1oLine)
                    a2oTable = [[] for iL in range(iNL)]
                else:
                    pass

                for iElemID, oElemVal in enumerate(a1oLine):
                    a2oTable[iElemID].append(oElemVal)

                    oItem = QTableWidgetItem(oElemVal)
                    oItem.setFlags(Qt.ItemIsSelectable)
                    self.TableWidget.setItem(iID, iElemID, oItem)

            self.TableWidget.resizeColumnsToContents()
            self.TableWidget.update()
            #self.TableWidget.repaint()

            self.TableWidget.setEditTriggers(QAbstractItemView.CurrentChanged)

        else:
            # Nullity table object
            #self.TableWidget.setRowCount(0)
            #self.TableWidget.setColumnCount(0)
            self.TableWidget.clearContents()
            self.TableWidget.setItem(0, 0, QTableWidgetItem("No data here ... "))
            #self.TableWidget.setHorizontalHeaderLabels(oFormSectionHeader)

    # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------
    # Method to cancel table
    def cancelTable(self):
        self.deletingFormTable.emit()
    # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------
    # Method to save table object to ascii file
    def saveTable(self):
        # Select output filename
        sFilePath = str(QFileDialog.getSaveFileName(self, 'Save File', '', 'ASCII (*.txt)'))
        # Check file definition by user
        if sFilePath is not None:
            # Save data to file
            writeTableObj(sFilePath, self.TableWidget)
        else:
            pass

    # -------------------------------------------------------------------------------------

    # -------------------------------------------------------------------------------------
    # Method to close event (destroy QWidget); closing plugin will destroy table form too
    def closeEvent(self, oEvent):
        oEvent.accept()
        self.closingFormTable.emit()