Пример #1
0
 def __generateItem(self, status, path):
     """
     Private method to generate a status item in the status list.
     
     @param status status indicator (string)
     @param path path of the file or directory (string)
     """
     statusText = self.status[status]
     itm = QTreeWidgetItem(self.statusList, [
         "",
         statusText,
         path,
     ])
     
     itm.setTextAlignment(1, Qt.AlignHCenter)
     itm.setTextAlignment(2, Qt.AlignLeft)
 
     if status in "AMR":
         itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
         itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
     else:
         itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable)
     
     if statusText not in self.__statusFilters:
         self.__statusFilters.append(statusText)
Пример #2
0
 def refresh(self):
     """
     Public method to refresh the tree.
     """
     QApplication.setOverrideCursor(Qt.WaitCursor)
     self.__itemChangingBlock = True
     self.clear()
     
     boldFont = QFont()
     boldFont.setBold(True)
     
     self.__topItem = QTreeWidgetItem(self)
     self.__topItem.setText(0, self.__subscription.title())
     self.__topItem.setFont(0, boldFont)
     self.addTopLevelItem(self.__topItem)
     
     allRules = self.__subscription.allRules()
     
     index = 0
     for rule in allRules:
         item = QTreeWidgetItem(self.__topItem)
         item.setText(0, rule.filter())
         item.setData(0, Qt.UserRole, index)
         if self.__subscription.canEditRules():
             item.setFlags(item.flags() | Qt.ItemIsEditable)
         self.__adjustItemFeatures(item, rule)
         index += 1
     
     self.expandAll()
     self.showRule(None)
     self.__itemChangingBlock = False
     QApplication.restoreOverrideCursor()
     QApplication.processEvents()
Пример #3
0
    def generate_tree_model(self, data_dict):
        """Generate a tree model for specified dictionary

        :param data_dict: A dictionary
        :type data_dict: dict
        :return: list of QTreeWidgetItem
        :rtype list:
        """
        widget_items = []
        font = QFont()
        font.setBold(True)
        for key in data_dict.keys():
            entry = data_dict[key]
            key_item = QTreeWidgetItem()
            key_item.setText(0, str(key))
            key_item.setFont(0, font)
            if isinstance(entry, dict):
                items = self.generate_tree_model(entry)
                key_item.addChildren(items)
            else:
                # value_item = QTreeWidgetItem()
                key_item.setText(1, str(entry))
                key_item.setFlags(key_item.flags() | Qt.ItemIsEditable)
                # key_item.addChild(key_item)
            widget_items.append(key_item)

        return widget_items
Пример #4
0
    def _populate_repo_tree(self):
        """
        Initialize the tree widget of repos and volumes.
        """
        self._repo_treewidget.clear()
        
        if self._repos_info is None:
            return
        
        for repo_uuid, repo_info in sorted(self._repos_info.items()):
            if repo_info is None:
                continue
            repo_column_dict = collections.defaultdict(str)
            repo_column_dict["Alias"] = repo_info["Alias"]
            repo_column_dict["Details"] = "Created: " + repo_info["Created"]
            repo_column_dict["UUID"] = repo_uuid
            repo_column_values = [repo_column_dict[k] for k in TREEVIEW_COLUMNS]
            repo_item = QTreeWidgetItem( self._repo_treewidget, repo_column_values )
            repo_item.setData( 0, Qt.UserRole, (repo_uuid, "", "") )
            for data_name, data_info in repo_info["DataInstances"].items():
                data_instance_dict = collections.defaultdict(str)
                data_instance_dict["Alias"] = data_name
                typename = data_info["Base"]["TypeName"]
                data_instance_dict["TypeName"] = typename

                is_voxels = (typename in VOXEL_TYPENAMES)
                if is_voxels:
                    start_coord = data_info["Extended"]["MinPoint"]
                    if start_coord:
                        start_coord = tuple(start_coord)
                    stop_coord = data_info["Extended"]["MaxPoint"]
                    if stop_coord:
                        stop_coord = tuple(x+1 for x in stop_coord)
                    if start_coord and stop_coord:
                        shape = tuple(b - a for a,b in zip(start_coord, stop_coord))
                    else:
                        shape = None
                    data_instance_dict["Details"] = "Size={} | Start={} | Stop={}".format( shape, start_coord, stop_coord )

                data_column_values = [data_instance_dict[k] for k in TREEVIEW_COLUMNS]
                data_item = QTreeWidgetItem( repo_item, data_column_values )
                data_item.setData( 0, Qt.UserRole, (repo_uuid, data_name, typename) )

                # If we're in specify_new mode, only the
                # repo parent items are selectable.
                # Also, non-volume items aren't selectable.
                if self._mode == 'specify_new' or typename not in self._selectable_types:
                    flags = data_item.flags()
                    flags &= ~Qt.ItemIsSelectable
                    flags &= ~Qt.ItemIsEnabled
                    data_item.setFlags( flags )
        
        self._repo_treewidget.collapseAll()
        self._repo_treewidget.setSortingEnabled(True)

        if self._hostname in self._default_nodes:
            self._select_node_uuid(self._default_nodes[self._hostname])

        self._repo_treewidget.resizeColumnToContents(0)
        self._repo_treewidget.setFocus()
Пример #5
0
 def addRule(self, filter=""):
     """
     Public slot to add a new rule.
     
     @param filter filter to be added (string)
     """
     if not self.__subscription.canEditRules():
         return
     
     if not filter:
         filter = QInputDialog.getText(
             self,
             self.tr("Add Custom Rule"),
             self.tr("Write your rule here:"),
             QLineEdit.Normal)
         if filter == "":
             return
     
     from .AdBlockRule import AdBlockRule
     rule = AdBlockRule(filter, self.__subscription)
     offset = self.__subscription.addRule(rule)
     
     item = QTreeWidgetItem()
     item.setText(0, filter)
     item.setData(0, Qt.UserRole, offset)
     item.setFlags(item.flags() | Qt.ItemIsEditable)
     
     self.__itemChangingBlock = True
     self.__topItem.addChild(item)
     self.__itemChangingBlock = False
     
     self.__adjustItemFeatures(item, rule)
Пример #6
0
    def createItem(self, text, parent, index):
        after = None

        if index != 0:
            after = self.childAt(parent, index - 1)

        if parent is not None:
            item = QTreeWidgetItem(parent, after)
        else:
            item = QTreeWidgetItem(self, after)

        item.setText(0, text)
        item.setFlags(item.flags() | Qt.ItemIsEditable)
        return item
Пример #7
0
    def readSettings(self):
        entries = settings.readMarkColors()
        for name, color in entries.items():
            item = QTreeWidgetItem(self.markColorWidget)
            item.setFlags(item.flags() | Qt.ItemIsEditable)
            widget = ColorVignette(self)
            widget.setColor(color)
            widget.setMargins(2, 2, 2, 2)
            widget.setMayClearColor(False)
            self.markColorWidget.setItemWidget(item, 0, widget)
            item.setText(1, name)
        if not len(entries):
            self.removeItemButton.setEnabled(False)

        loadRecentFile = settings.loadRecentFile()
        self.loadRecentFileBox.setChecked(loadRecentFile)
    def propertyInserted(self, index, afterIndex):
        afterItem = self.m_indexToItem.get(afterIndex)
        parentItem = self.m_indexToItem.get(index.parent())

        newItem = 0
        if (parentItem):
            newItem = QTreeWidgetItem(parentItem, afterItem)
        else:
            newItem = QTreeWidgetItem(self.m_treeWidget, afterItem)

        self.m_itemToIndex[newItem] = index
        self.m_indexToItem[index] = newItem

        newItem.setFlags(newItem.flags() | Qt.ItemIsEditable)
        newItem.setExpanded(True)

        self.updateItem(newItem)
Пример #9
0
 def _updateLayerAttributes(self, notification=None):
     self.layerSetWidget.clear()
     if self._font is None:
         return
     layerSet = self._font.layers
     if layerSet is None:
         return
     for layer in layerSet:
         item = QTreeWidgetItem(self.layerSetWidget)
         item.setFlags(item.flags() | Qt.ItemIsEditable)
         item.setText(0, layer.name)
         widget = ColorVignette(self)
         color = layer.color
         if color is not None:
             color = QColor.fromRgbF(*tuple(color))
         widget.setColor(color)
         widget.setMargins(2, 2, 2, 2)
         widget.setMayClearColor(False)
         widget.colorChanged.connect(self.writeLayerColor)
         widget.setProperty("layer", layer)
         self.layerSetWidget.setItemWidget(item, 1, widget)
     self.layerSetWidget.setColumnWidth(1, 100)
Пример #10
0
    def addItem(self):
        def mangleNewName():
            name = self.tr("New")
            index = 0
            while self.markColorWidget.findItems(name, Qt.MatchExactly, 1):
                index += 1
                name = "{0} ({1})".format(name, index)
            return name

        # TODO: not DRY with ctor
        item = QTreeWidgetItem(self.markColorWidget)
        item.setFlags(item.flags() | Qt.ItemIsEditable)
        widget = ColorVignette(self)
        widget.setColor(QColor(Qt.white))
        widget.setMargins(2, 2, 2, 2)
        widget.setMayClearColor(False)
        self.markColorWidget.setItemWidget(item, 0, widget)
        item.setText(1, mangleNewName())

        self.markColorWidget.setCurrentItem(item)
        self.markColorWidget.editItem(item, 1)
        self.removeItemButton.setEnabled(True)
Пример #11
0
 def __createItem(self, file, line, text, start, end, replTxt="", md5=""):
     """
     Private method to create an entry in the file list.
     
     @param file filename of file (string)
     @param line line number (integer)
     @param text text found (string)
     @param start start position of match (integer)
     @param end end position of match (integer)
     @param replTxt text with replacements applied (string)
     @keyparam md5 MD5 hash of the file (string)
     """
     if self.__lastFileItem is None:
         # It's a new file
         self.__lastFileItem = QTreeWidgetItem(self.findList, [file])
         self.__lastFileItem.setFirstColumnSpanned(True)
         self.__lastFileItem.setExpanded(True)
         if self.__replaceMode:
             self.__lastFileItem.setFlags(
                 self.__lastFileItem.flags() |
                 Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate))
             # Qt bug:
             # item is not user checkable if setFirstColumnSpanned
             # is True (< 4.5.0)
         self.__lastFileItem.setData(0, self.md5Role, md5)
     
     itm = QTreeWidgetItem(self.__lastFileItem)
     itm.setTextAlignment(0, Qt.AlignRight)
     itm.setData(0, Qt.DisplayRole, line)
     itm.setData(1, Qt.DisplayRole, text)
     itm.setData(0, self.lineRole, line)
     itm.setData(0, self.startRole, start)
     itm.setData(0, self.endRole, end)
     itm.setData(0, self.replaceRole, replTxt)
     if self.__replaceMode:
         itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable))
         itm.setCheckState(0, Qt.Checked)
         self.replaceButton.setEnabled(True)
Пример #12
0
    def __init__(self,MainWindow, headers, apiKey,checkBoxState):
        super(Ui_OtherWindow,self).__init__()

        self.ScRate = GetSystemMetrics(0)/1920
        self.mainWindow = MainWindow
        self.headers = headers  
        
        self.mainWindow.setObjectName("MainWindow")
        self.mainWindow.resize(350*self.ScRate, 393*self.ScRate)
        self.mainWindow.setMinimumSize(QSize(350*self.ScRate, 393*self.ScRate))
        self.mainWindow.setMaximumSize(QSize(350*self.ScRate, 393*self.ScRate))
        self.mainWindow.setWindowFlags(self.mainWindow.windowFlags() & ~Qt.WindowCloseButtonHint)
        self.mainWindow.setWindowIcon(QIcon(Icons["Standart"]))

        self.mainWindow = MainWindow
        self.headers = headers
        

        self.centralwidget = QWidget(self.mainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.verticalLayout_4 = QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.label = QLabel(self.centralwidget)
        font = QFont()
        font.setPointSize(10*self.ScRate)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.verticalLayout_4.addWidget(self.label)
        self.lineEdit = QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout_4.addWidget(self.lineEdit)
        self.verticalLayout.addLayout(self.verticalLayout_4)
        self.label_2 = QLabel(self.centralwidget)
        font = QFont()
        font.setPointSize(10*self.ScRate)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.verticalLayout.addWidget(self.label_2)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.treeWidget = QTreeWidget(self.centralwidget)
        self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeWidget.customContextMenuRequested.connect(self.on_context_menu)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth())
        self.treeWidget.setSizePolicy(sizePolicy)
        self.treeWidget.setObjectName("treeWidget")
        for i in range(len(self.headers)):
            item_0 = QTreeWidgetItem(self.treeWidget)
            item_0.setFlags(item_0.flags() | Qt.ItemIsEditable)
        self.horizontalLayout.addWidget(self.treeWidget)
        self.verticalLayout_2 = QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.gridLayout.addLayout(self.verticalLayout, 0, 0, 3, 1)
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setContentsMargins(150, -1, -1, -1)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")

        self.pushButton_2 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth())
        self.pushButton_2.setSizePolicy(sizePolicy)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_2.addWidget(self.pushButton_2)

        self.pushButton = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_2.addWidget(self.pushButton)
        self.gridLayout.addLayout(self.horizontalLayout_2, 7, 0, 1, 1)
        spacerItem = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem, 4, 0, 1, 1)
        self.checkBox = QCheckBox(self.centralwidget)
        self.checkBox.setChecked(eval(checkBoxState))
        font = QFont()
        font.setFamily("MS Shell Dlg 2")
        font.setPointSize(9)
        font.setItalic(False)
        self.checkBox.setFont(font)
        self.checkBox.setObjectName("checkBox")
        self.gridLayout.addWidget(self.checkBox, 3, 0, 1, 1)
        self.mainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self.mainWindow)
        self.menubar.setGeometry(QRect(0, 0, 350*self.ScRate, 26*self.ScRate))
        self.menubar.setObjectName("menubar")
        self.mainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(self.mainWindow)
        self.statusbar.setObjectName("statusbar")
        self.mainWindow.setStatusBar(self.statusbar)

        self.create_popup_menu()
        self.pushButton.clicked.connect(self.saveBtn)
        self.pushButton_2.clicked.connect(self.cancel)
        self.mainWindow.keyPressEvent = self.keyPressEvent

        if type(apiKey) == list:
            try:
                self.lineEdit.setText(apiKey[0])
            except IndexError:
                self.lineEdit.setText("")
        else:
            self.lineEdit.setText(apiKey)
        self.retranslateUi(self.mainWindow)
        self.treeWidget.resizeColumnToContents(0)


        root = self.treeWidget.invisibleRootItem()
        child_count = root.childCount()
        for i in range(child_count):
            item = root.child(i)
            url = item.text(0)
            if url == "İsim" or url == "Telefon No (Örn 9053xx..)":
                item.setFlags(item.flags() & ~Qt.ItemIsEditable)

            if url == "Mesaj Durumu":
                item.setHidden(True)

        QMetaObject.connectSlotsByName(self.mainWindow)
Пример #13
0
 def handleDict(self, dict_data, tree, tree_dict={}, new=False):
     # We can actually have numerous structures, here.
     # Why not keep track of it, for now?
     # We want to do a reverse lookup
     #ddc = copy.copy(dict_data)
     #ddc = dict_data
     con = False
     oldKeyTree = None
     #for key, val in sorted(ddc.items(), key= lambda x: str(x)):
     od = {}
     # This sped it up quite a bit.
     try:
         #od = OrderedDict(sorted(ddc.items(), key= lambda i: self.parent.mpl_dict['keyOrder'].index(i[0])))
         #od = OrderedDict(sorted(ddc.items(), key= lambda i: self.parent.mpl_dict['keyOrder'].index(i[0])))
         od_keys = sorted(
             dict_data.keys(),
             key=lambda i: self.parent.mpl_dict['keyOrder'].index(i[0]))
     except:
         # Default to alphabetical order
         #od = OrderedDict(sorted(ddc.items(), key= lambda x: str(x)))
         od_keys = sorted(dict_data.keys(), key=lambda x: str(x))
     for key in od_keys:
         val = dict_data[key]
         if type(key) == str and len(key) >= 6:
             #if key[0:7] != 'keyTree' and key[0:7] != 'valTree':
             if key not in self.parent.mpl_dict['hidden_keys']:
                 con = True
             else:
                 con = False
         else:
             con = True
         if con:
             try:
                 keyTree = tree_dict['keyTree.{}'.format(key)]
                 keyTree.setText(0, str(key))
             except Exception:
                 # This behavior ensures that we insert the new tree item at
                 # the location specified in the abov dictionary.  Seems to work.
                 if oldKeyTree is not None:
                     keyTree = QTreeWidgetItem(tree, oldKeyTree)
                     keyTree.setText(0, str(key))
                 else:
                     keyTree = QTreeWidgetItem(tree, [str(key)])
                 keyTree.oldValue = [str(key)]
                 tree_dict['keyTree.{}'.format(key)] = keyTree
             '''if 'keyTree.{}'.format(key) not in tree_dict or new:
                 keyTree = QTreeWidgetItem(tree, [str(key)])
                 keyTree.oldValue = [str(key)]
                 tree_dict['keyTree.{}'.format(key)] = keyTree
             else:
                 keyTree = tree_dict['keyTree.{}'.format(key)]
                 keyTree.setText(0, str(key))'''
             oldKeyTree = keyTree
             if key == 'Figures':
                 self.figures = keyTree
             if type(val) == h5py._hl.group.Group:
                 #tree_dict[key] =
                 # This is a normal HDF5 group.  Treat it appropriately.
                 if key not in tree_dict:
                     tree_dict[key] = {}
                 self.handleDict(val,
                                 keyTree,
                                 new=new,
                                 tree_dict=tree_dict[key])
             if type(val) == dict:
                 if key not in tree_dict:
                     tree_dict[key] = {}
                 self.handleDict(val,
                                 keyTree,
                                 new=new,
                                 tree_dict=tree_dict[key])
             elif type(val) == h5py._hl.dataset.Dataset:
                 # Let's handle 2 and 3 dimensional data for now.  Anything more than that and it just... well, it won't plot anyway.
                 # I know this shouldn't go into the handlDict function, but hey.  At least rename it.
                 sdict = {}
                 if len(val.shape) == 2:
                     # Assume time is the first dimension.
                     for i in range(0, val.shape[1]):
                         if val.dtype.names is not None:
                             sdict[i] = {}
                             for iv, v in enumerate(val.dtype.names):
                                 # Why the f**k is this so slow?
                                 sdict[i][v] = str(val.shape)
                         else:
                             sdict[i] = str(val.shape)
                 if len(val.shape) == 3:
                     # Assume time is the first dimension.
                     for i in range(0, val.shape[1]):
                         for j in range(0, val.shape[2]):
                             if val.dtype.names is not None:
                                 sdict[(i, j)] = {}
                                 for iv, v in enumerate(val.dtype.names):
                                     # Why the f**k is this so slow?
                                     sdict[(i, j)][v] = str(val.shape)
                             else:
                                 sdict[(i, j)] = str(val.shape)
                 if key not in tree_dict:
                     tree_dict[key] = {}
                 self.handleDict(sdict,
                                 keyTree,
                                 new=new,
                                 tree_dict=tree_dict[key])
             else:
                 # We want this to be like rows, not columns
                 if self.rows:
                     if type(val) == list:
                         for iv, v in enumerate(val):
                             if self.editable:
                                 keyTree.setFlags(
                                     keyTree.flags()
                                     | QtCore.Qt.ItemIsEditable)
                             keyTree.setText(iv + 1, str(v))
                             keyTree.oldValue.append((str(v)))
                             self.col += iv
                     else:
                         if self.editable:
                             keyTree.setFlags(keyTree.flags()
                                              | QtCore.Qt.ItemIsEditable)
                         keyTree.setText(1, str(val))
                         keyTree.oldValue.append((str(val)))
     self.tree.setColumnCount(self.col)
Пример #14
0
    def __generateItem(self, status, propStatus, locked, history, switched,
                       lockinfo, uptodate, revision, change, author, path):
        """
        Private method to generate a status item in the status list.
        
        @param status status indicator (string)
        @param propStatus property status indicator (string)
        @param locked locked indicator (string)
        @param history history indicator (string)
        @param switched switched indicator (string)
        @param lockinfo lock indicator (string)
        @param uptodate up to date indicator (string)
        @param revision revision string (string)
        @param change revision of last change (string)
        @param author author of the last change (string)
        @param path path of the file or directory (string)
        """
        if (self.__nonverbose and status == " " and propStatus == " "
                and locked == " " and history == " " and switched == " "
                and lockinfo == " " and uptodate == " "
                and self.currentChangelist == ""):
            return

        if revision == "":
            rev = ""
        else:
            try:
                rev = int(revision)
            except ValueError:
                rev = revision
        if change == "":
            chg = ""
        else:
            try:
                chg = int(change)
            except ValueError:
                chg = change
        statusText = self.status[status]

        itm = QTreeWidgetItem(self.statusList)
        itm.setData(0, Qt.DisplayRole, "")
        itm.setData(1, Qt.DisplayRole, self.currentChangelist)
        itm.setData(2, Qt.DisplayRole, statusText)
        itm.setData(3, Qt.DisplayRole, self.propStatus[propStatus])
        itm.setData(4, Qt.DisplayRole, self.locked[locked])
        itm.setData(5, Qt.DisplayRole, self.history[history])
        itm.setData(6, Qt.DisplayRole, self.switched[switched])
        itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo])
        itm.setData(8, Qt.DisplayRole, self.uptodate[uptodate])
        itm.setData(9, Qt.DisplayRole, rev)
        itm.setData(10, Qt.DisplayRole, chg)
        itm.setData(11, Qt.DisplayRole, author)
        itm.setData(12, Qt.DisplayRole, path)

        itm.setTextAlignment(1, Qt.AlignLeft)
        itm.setTextAlignment(2, Qt.AlignHCenter)
        itm.setTextAlignment(3, Qt.AlignHCenter)
        itm.setTextAlignment(4, Qt.AlignHCenter)
        itm.setTextAlignment(5, Qt.AlignHCenter)
        itm.setTextAlignment(6, Qt.AlignHCenter)
        itm.setTextAlignment(7, Qt.AlignHCenter)
        itm.setTextAlignment(8, Qt.AlignHCenter)
        itm.setTextAlignment(9, Qt.AlignRight)
        itm.setTextAlignment(10, Qt.AlignRight)
        itm.setTextAlignment(11, Qt.AlignLeft)
        itm.setTextAlignment(12, Qt.AlignLeft)

        if status in "ADM" or propStatus in "M":
            itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
            itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
        else:
            itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable)

        self.hidePropertyStatusColumn = (self.hidePropertyStatusColumn
                                         and propStatus == " ")
        self.hideLockColumns = (self.hideLockColumns and locked == " "
                                and lockinfo == " ")
        self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " "
        self.hideHistoryColumn = self.hideHistoryColumn and history == " "
        self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " "

        if statusText not in self.__statusFilters:
            self.__statusFilters.append(statusText)
Пример #15
0
class Waterfall(QWidget, waterfall.Ui_Waterfall):

    plot_settings_signal = QtCore.pyqtSignal(
        list)  #send list of plotting params
    updated_rectangles_signal = QtCore.pyqtSignal(
        list)  #send list of updated artists for redrawing

    def __init__(self, parent):
        super(Waterfall, self).__init__(parent)
        self.setupUi(self)

        self.get_settings()

        #Button functions
        self.btn_apply_general_settings.clicked.connect(self.send_settings)
        self.btn_apply_keys_and_colors_settings.clicked.connect(
            self.send_settings)
        self.patient_tree = self.create_patient_tree()
        self.data_viewer_container.addWidget(self.patient_tree)
        self.btn_color_test.clicked.connect(self.get_color)

    def get_color(self):
        self.color = QColorDialog.getColor()  #returns a color object
        print(color)

    def get_settings(self):
        # try:
        #     with shelve.open('WaterfallSettings') as shelfFile:
        #         self.keys_and_colors = shelfFile['keys_and_colors']
        #         shelfFile.close()
        # except:
        #     #set and use default settings
        #     self.keys_and_colors = {
        #                             'CR':'#03945D',
        #                             'PR':'#B1EE97',
        #                             'PD':'#FF6F69',
        #                             'SD':'#707070',
        #                             'a':'r',
        #                             'b':'g',
        #                             'c':'b'
        #                             }
        #     with shelve.open('WaterfallSettings') as shelfFile:
        #         shelfFile['keys_and_colors'] = self.keys_and_colors
        #         shelfFile.close()
        self.keys_and_colors = {
            'CR': '#03945D',
            'PR': '#B1EE97',
            'PD': '#FF6F69',
            'SD': '#707070',
            'a': '#FF0000',
            'b': '#00FF00',
            'c': '#0000FF'
        }

    def on_waterfall_data_signal(self, signal):
        self.waterfall_data = signal['waterfall_data']  #pandas dataframe

    def on_generated_rectangles_signal(self, signal):
        self.rectangles_received = signal[0]
        self.add_items()  #display in table
        self.btn_apply_general_settings.setEnabled(True)
        self.btn_finalize_plot.setEnabled(True)
        self.btn_apply_keys_and_colors_settings.setEnabled(True)

    def send_settings(self):
        '''
        Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created.
        
        '''
        self.general_settings = [
            self.plot_title.text(),
            self.x_label.text(),
            self.y_label.text(),
            [
                self.twenty_percent_line.isChecked(),
                self.thirty_percent_line.isChecked(),
                self.zero_percent_line.isChecked()
            ],
            [
                self.display_responses_as_text.isChecked(),
                self.display_responses_as_color.isChecked(),
                self.use_custom_keys.isChecked()
            ],
            self.include_table.isChecked(),
            self.show_cancer_type.isChecked(),
            self.get_updated_color_coding()
        ]
        self.plot_settings_signal.emit(self.general_settings)

    def create_patient_tree(self):
        '''
        Create QTreeWidget populated with a patient's data for the DataEntry dialog.
        Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog.
        '''
        self.tree = QTreeWidget()
        self.root = self.tree.invisibleRootItem()
        self.headers = [
            'Patient #',
            'Best response %',
            'Response',
            'Cancer',
            'Color key',
        ]
        self.headers_item = QTreeWidgetItem(self.headers)
        self.tree.setColumnCount(len(self.headers))
        self.tree.setHeaderItem(self.headers_item)
        self.root.setExpanded(True)
        self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        self.tree.clear()  #clear prior to entering items, prevent aggregation
        i = 0
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            self.rect_item = QTreeWidgetItem(self.root)
            self.rect_params = [
                self.waterfall_data['Patient number'][i],
                rect.get_height(), self.waterfall_data['Overall response'][i],
                self.waterfall_data['Cancer'][i]
            ]
            for col in range(0, 4):
                self.rect_item.setText(col, str(self.rect_params[col]))
                self.rect_item.setTextAlignment(col, 4)
            self.tree.setItemWidget(
                self.rect_item, 4,
                CustomCombo(self, self.keys_and_colors, rect.get_label()))
            self.rect_item.setFlags(self.rect_item.flags()
                                    | QtCore.Qt.ItemIsEditable)
            i += 1

    def get_updated_color_coding(self):
        tmp_updated_color_coding = []
        self.root = self.tree.invisibleRootItem()
        child_count = self.root.childCount()
        #return list of keys (children are iterated in order they were entered, which agrees with order of patient data in waterfall_data lists)
        return [
            self.tree.itemWidget(self.root.child(i), 4).currentText()
            for i in range(child_count)
        ]

    def on_updated_tree_item(self):
        #update the rectangle which was edited
        pass
Пример #16
0
    def populate_available_terms(self):
        """
        Runs at start up and when volume is changed. Poulates the avaible annotation terms
        """

        self.ui.treeWidgetAvailableTerms.clear()

        vol = self.controller.current_annotation_volume()
        if not vol or None in (vol.annotations.stage, vol.annotations.center):
            # info_dialog(self, 'Chose centre and stage', 'You must choose a centre and stage from the options tab')
            return

        self.ui.lineEditCentre.setText(vol.annotations.center)
        self.ui.lineEditStage.setText(vol.annotations.stage)

        def setup_option_box_signal(box_: QComboBox, child_: QTreeWidgetItem):
            """
            Connect the Qcombobox to a slot
            """
            box_.activated.connect(partial(self.update_annotation, child_, box_))
            # Setup signal so when combobox is only opened, it sets the selection to that column
            box_.highlighted.connect(partial(self.on_box_highlight, child))

        header_labels = QTreeWidgetItem(['', 'term', 'name', 'option', 'done?'])

        self.ui.treeWidgetAvailableTerms.setHeaderItem(header_labels)

        parent = QTreeWidgetItem(self.ui.treeWidgetAvailableTerms)
        parent.setText(0, '')
        parent.setFlags(parent.flags())
        parent.setExpanded(True)

        header = self.ui.treeWidgetAvailableTerms.header()

        # Set root column to invisible
        self.ui.treeWidgetAvailableTerms.setColumnWidth(0, 0)
        header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)

        # For each annotation set an info row in the annotations table
        for i, ann in enumerate(sorted(vol.annotations, key=lambda an_: an_.order)):

            child = QTreeWidgetItem(parent)
            child.setText(1, ann.term)
            child.setText(3, ann.name)
            option = ann.selected_option
            # color = OPTION_COLOR_MAP[option]
            parent.addChild(child)

            # Set up the parameter option combobox and highlight the currently selected one
            options_box = QComboBox()
            options_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)

            for opt in ann.options:
                options_box.addItem(opt)

            options_box.setCurrentIndex(options_box.findText(option))  # 060818  Louise's bug option is a bool not a str

            # Setup combobox selection signal
            setup_option_box_signal(options_box, child)
            self.ui.treeWidgetAvailableTerms.setItemWidget(child, 2, options_box)

            done_checkbox = QtWidgets.QCheckBox()
            done_checkbox.setChecked(ann.looked_at)

            done_checkbox.stateChanged.connect(partial(self.parameter_done_signal, child, done_checkbox))
            self.ui.treeWidgetAvailableTerms.setItemWidget(child, 4, done_checkbox)

        # Set the roi coords to None
        self.roi_highlight_off_signal.emit()
Пример #17
0
    def addChild(self, parent, title, data, flags=Qt.NoItemFlags):
        item = QTreeWidgetItem(parent, [title])
        item.setFlags(item.flags() | Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable | flags)
        item.setData(self.colVALUE, Qt.DisplayRole, data)

        return item
class Waterfall(QWidget, waterfall.Ui_Waterfall):
    
    plot_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params
    updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing

    def __init__(self, parent):
        super(Waterfall,self).__init__(parent)
        self.setupUi(self)
        
        self.test = {'a':'red','b':'green','c':'blue'}
        #Button functions
        self.btn_apply_general_settings.clicked.connect(self.send_settings)
        self.btn_apply_keys_and_colors_settings.clicked.connect(self.send_settings)
        self.patient_tree = self.create_patient_tree()
        self.data_viewer_container.addWidget(self.patient_tree)
        self.btn_color_test.clicked.connect(self.get_color)
        self.get_settings()

    def get_color(self):
        

    def get_settings(self):
        try:
            with shelve.open('WaterfallSettings') as shelfFile: 
                self.keys_and_colors = shelfFile['keys_and_colors']
                shelfFile.close()
        except:
            #default
            self.keys_and_colors = {
                                    'CR':'#03945D',
                                    'PR':'#B1EE97',
                                    'PD':'#FF6F69',
                                    'SD':'#707070'}

    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        
    def on_generated_rectangles_signal(self,signal):
        self.rectangles_received = signal[0]
        self.add_items() #display in table

    def send_settings(self,signal):
        '''
        Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created.
        '''
        self.list_general_settings = [
                                        self.plot_title.text(),
                                        self.x_label.text(),
                                        self.y_label.text(),
                                        self.twenty_percent_line.isChecked(),
                                        self.thirty_percent_line.isChecked(),
                                        self.zero_percent_line.isChecked(),
                                        self.display_responses_as_text.isChecked()
                                    ]
        self.plot_settings_signal.emit([self.list_general_settings,self.keys_and_colors_settings])
        

    def create_patient_tree(self):
            '''
            Create QTreeWidget populated with a patient's data for the DataEntry dialog.
            Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog.
            '''
            self.tree = QTreeWidget()
            self.root = self.tree.invisibleRootItem()
            self.headers = [
                            'Patient #',
                            'Best response %',
                            'Response',
                            'Cancer',
                            'Color key',
                            ]
            self.headers_item = QTreeWidgetItem(self.headers)
            self.tree.setColumnCount(len(self.headers))
            self.tree.setHeaderItem(self.headers_item)
            self.root.setExpanded(True)
            self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tree.header().setStretchLastSection(False)
            return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        self.tree.clear() #clear prior to entering items, prevent aggregation
        i=0
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            self.rect_item = QTreeWidgetItem(self.root)
            self.rect_params = [
                                self.waterfall_data['Patient number'][i], 
                                rect.get_height(),
                                self.waterfall_data['Overall response'][i],
                                self.waterfall_data['Cancer'][i]
                                ]
            for col in range(0,4):
                self.rect_item.setText(col,str(self.rect_params[col]))
                self.rect_item.setTextAlignment(col,4)
            self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.keys_and_colors))
            self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable)
            i+=1
        
    def on_updated_tree_item(self):
        #update the rectangle which was edited
        pass

class WaterfallPlotter(QWidget):

    generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree

    def __init__(self,parent):
        super(WaterfallPlotter,self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas,self)

        self.btn_plot = QPushButton('Default Plot')
        self.btn_plot.clicked.connect(self.default_plot)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.btn_plot)
        self.setLayout(self.layout)
    
    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        self.btn_plot.setEnabled(True)

    def on_general_settings_signal(self,signal):
        try:
            hasattr(self,'ax')
            self.ax.set_title(signal[0])
            self.ax.set_xlabel(signal[1])
            self.ax.set_ylabel(signal[2])
            self.canvas.draw()
        except Exception as e:
            print(e)
            
    def default_plot(self):
        '''
        Plot waterfall data
        '''
        self.figure.clear()
        self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change']))
        self.ax = self.figure.add_subplot(111)
        self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
        self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
        self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')
        self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
        self.rects = self.ax.bar(self.rect_locations,self.waterfall_data['Best response percent change'])
        self.auto_label_responses(self.ax, self.rects, self.waterfall_data)
        #self.plot_table()
        self.canvas.draw()
        self.ax.hold(False) #rewrite the plot when plot() called
        self.generated_rectangles_signal.emit([self.rects])
            
    def plot_table(self):
        rows = ['%s' % x for x in self.waterfall_data.keys()]
        rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows
        columns = self.waterfall_data['Patient number'] #patient numbers
        cell_text = []
        for row in rows:
            cell_text_temp = []
            for col in range(len(columns)):
                cell_text_temp.append(self.waterfall_data[row][col])
            cell_text.append(cell_text_temp)
        the_table = plt.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center')
        plt.subplots_adjust(bottom=0.15,left=0.5)
        self.ax.set_xlim(-0.5,len(columns)-0.5)
        plt.tick_params(
                        axis='x',          # changes apply to the x-axis
                        which='both',      # both major and minor ticks are affected
                        bottom='off',      # ticks along the bottom edge are off
                        top='off',         # ticks along the top edge are off
                        labelbottom='off'
                        ) # labels along the bottom edge are off
    
    def update_plot(self):
        '''
        TODO
        '''
        pass
                    
    def auto_label_responses(self, ax, rects, waterfall_data):
        '''Add labels above/below bars'''
        i = 0
        for rect in rects:
            height = rect.get_height()
            if height >= 0:
                valign = 'bottom'
            else:
                valign = 'top'
                
            ax.text(rect.get_x() + rect.get_width()/2., height,
                    '%s' % waterfall_data['Overall response'][i], ha='center', va=valign)
            i+=1
Пример #19
0
    def loadStep(self):
        """Bring in a step file as a 'disposable' treelib.Tree() structure.

        Each node of the tree contains the following tuple:
        (Name, UID, ParentUID, {Data})
        where the Data dictionary is:
        {'a': (isAssy?),
         'l': (TopLoc_Location),
         'c': (Quantity_Color),
         's': (TopoDS_Shape)}
        This format makes it convenient to:
        1. Build the assy, part, name and color dictionaries using uid keys,
        2. Display the model with all its component parts correctly located and
        3. Build the Part/Assy tree view GUI (QTreeWidget).

        Each QTreeWidgetItem is required to have a unique identifier. This means
        that multiple instances of the same CAD geometry will each have different
        uid's.
        """
        prompt = 'Select STEP file to import'
        fnametuple = QFileDialog.getOpenFileName(
            None, prompt, './', "STEP files (*.stp *.STP *.step)")
        fname, _ = fnametuple
        logger.debug("Load file name: %s", fname)
        if not fname:
            print("Load step cancelled")
            return
        name = os.path.basename(fname).split('.')[0]
        nextUID = self._currentUID
        stepImporter = stepXD.StepImporter(fname, nextUID)
        self.doc = stepImporter.doc  # <class 'OCC.Core.TDocStd.TDocStd_Document'>
        tree = stepImporter.tree
        tempTreeDict = {
        }  # uid:asyPrtTreeItem (used temporarily during unpack)
        treedump = tree.expand_tree(mode=tree.DEPTH)
        for uid in treedump:  # type(uid) == int
            node = tree.get_node(uid)
            name = node.tag
            itemName = [name, str(uid)]
            parentUid = node.bpointer
            if node.data['a']:  # Assembly
                if not parentUid:  # This is the top level item
                    parentItem = self.treeViewRoot
                else:
                    parentItem = tempTreeDict[parentUid]
                item = QTreeWidgetItem(parentItem, itemName)
                item.setFlags(item.flags() | Qt.ItemIsTristate
                              | Qt.ItemIsUserCheckable)
                self.treeView.expandItem(item)
                tempTreeDict[uid] = item
                Loc = node.data['l']  # Location object
                self._assyDict[uid] = Loc
            else:  # Part
                # add item to asyPrtTree treeView
                if not parentUid:  # This is the top level item
                    parentItem = self.treeViewRoot
                else:
                    parentItem = tempTreeDict[parentUid]
                item = QTreeWidgetItem(parentItem, itemName)
                item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
                item.setCheckState(0, Qt.Checked)
                tempTreeDict[uid] = item
                color = node.data['c']
                shape = node.data['s']
                # Update dictionaries
                self._partDict[uid] = shape
                self._nameDict[uid] = name
                if color:
                    c = OCC.Display.OCCViewer.rgb_color(
                        color.Red(), color.Green(), color.Blue())
                else:
                    c = OCC.Display.OCCViewer.rgb_color(.2, .1,
                                                        .1)  # default color
                self._colorDict[uid] = c
                self.activePartUID = uid  # Set as active part
                self.activePart = shape
                self.drawList.append(uid)  # Add to draw list

        keyList = tempTreeDict.keys()
        keyList = list(keyList)
        keyList.sort()
        maxUID = keyList[-1]
        self._currentUID = maxUID
        self.redraw()
Пример #20
0
class FindFileDialog(QDialog, Ui_FindFileDialog):
    """
    Class implementing a dialog to search for text in files.
    
    The occurrences found are displayed in a QTreeWidget showing the filename,
    the linenumber and the found text. The file will be opened upon a double
    click onto the respective entry of the list.
    
    @signal sourceFile(str, int, str, int, int) emitted to open a source file
        at a line
    @signal designerFile(str) emitted to open a Qt-Designer file
    """
    sourceFile = pyqtSignal(str, int, str, int, int)
    designerFile = pyqtSignal(str)
    
    lineRole = Qt.UserRole + 1
    startRole = Qt.UserRole + 2
    endRole = Qt.UserRole + 3
    replaceRole = Qt.UserRole + 4
    md5Role = Qt.UserRole + 5
    
    def __init__(self, project, replaceMode=False, parent=None):
        """
        Constructor
        
        @param project reference to the project object
        @param replaceMode flag indicating the replace dialog mode (boolean)
        @param parent parent widget of this dialog (QWidget)
        """
        super(FindFileDialog, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(Qt.Window)
        
        self.dirPicker.setMode(E5PathPickerModes.DirectoryMode)
        self.dirPicker.setInsertPolicy(QComboBox.InsertAtTop)
        self.dirPicker.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLength)
        
        self.__replaceMode = replaceMode
        
        self.stopButton = \
            self.buttonBox.addButton(self.tr("Stop"),
                                     QDialogButtonBox.ActionRole)
        self.stopButton.setEnabled(False)
        
        self.findButton = \
            self.buttonBox.addButton(self.tr("Find"),
                                     QDialogButtonBox.ActionRole)
        self.findButton.setEnabled(False)
        self.findButton.setDefault(True)
        
        if self.__replaceMode:
            self.replaceButton.setEnabled(False)
            self.setWindowTitle(self.tr("Replace in Files"))
        else:
            self.replaceLabel.hide()
            self.replacetextCombo.hide()
            self.replaceButton.hide()
        
        self.findProgressLabel.setMaximumWidth(550)
        
        self.findtextCombo.setCompleter(None)
        self.replacetextCombo.setCompleter(None)
        
        self.searchHistory = Preferences.toList(
            Preferences.Prefs.settings.value(
                "FindFileDialog/SearchHistory"))
        self.replaceHistory = Preferences.toList(
            Preferences.Prefs.settings.value(
                "FindFileDialog/ReplaceHistory"))
        self.dirHistory = Preferences.toList(
            Preferences.Prefs.settings.value(
                "FindFileDialog/DirectoryHistory"))
        self.findtextCombo.addItems(self.searchHistory)
        self.replacetextCombo.addItems(self.replaceHistory)
        self.dirPicker.addItems(self.dirHistory)
        
        self.project = project
        
        self.findList.headerItem().setText(self.findList.columnCount(), "")
        self.findList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.__section0Size = self.findList.header().sectionSize(0)
        self.findList.setExpandsOnDoubleClick(False)
        if self.__replaceMode:
            font = Preferences.getEditorOtherFonts("MonospacedFont")
            self.findList.setFont(font)

        # Qt Designer form files
        self.filterForms = r'.*\.ui$'
        self.formsExt = ['*.ui']
        
        # Corba interface files
        self.filterInterfaces = r'.*\.idl$'
        self.interfacesExt = ['*.idl']
        
        # Qt resources files
        self.filterResources = r'.*\.qrc$'
        self.resourcesExt = ['*.qrc']
        
        self.__cancelSearch = False
        self.__lastFileItem = None
        self.__populating = False
        
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenuRequested)
        
    def __createItem(self, file, line, text, start, end, replTxt="", md5=""):
        """
        Private method to create an entry in the file list.
        
        @param file filename of file (string)
        @param line line number (integer)
        @param text text found (string)
        @param start start position of match (integer)
        @param end end position of match (integer)
        @param replTxt text with replacements applied (string)
        @keyparam md5 MD5 hash of the file (string)
        """
        if self.__lastFileItem is None:
            # It's a new file
            self.__lastFileItem = QTreeWidgetItem(self.findList, [file])
            self.__lastFileItem.setFirstColumnSpanned(True)
            self.__lastFileItem.setExpanded(True)
            if self.__replaceMode:
                self.__lastFileItem.setFlags(
                    self.__lastFileItem.flags() |
                    Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate))
                # Qt bug:
                # item is not user checkable if setFirstColumnSpanned
                # is True (< 4.5.0)
            self.__lastFileItem.setData(0, self.md5Role, md5)
        
        itm = QTreeWidgetItem(self.__lastFileItem)
        itm.setTextAlignment(0, Qt.AlignRight)
        itm.setData(0, Qt.DisplayRole, line)
        itm.setData(1, Qt.DisplayRole, text)
        itm.setData(0, self.lineRole, line)
        itm.setData(0, self.startRole, start)
        itm.setData(0, self.endRole, end)
        itm.setData(0, self.replaceRole, replTxt)
        if self.__replaceMode:
            itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable))
            itm.setCheckState(0, Qt.Checked)
            self.replaceButton.setEnabled(True)
        
    def show(self, txt=""):
        """
        Public method to enable/disable the project button.
        
        @param txt text to be shown in the searchtext combo (string)
        """
        if self.project and self.project.isOpen():
            self.projectButton.setEnabled(True)
        else:
            self.projectButton.setEnabled(False)
            self.dirButton.setChecked(True)
            
        self.findtextCombo.setEditText(txt)
        self.findtextCombo.lineEdit().selectAll()
        self.findtextCombo.setFocus()
        
        if self.__replaceMode:
            self.findList.clear()
            self.replacetextCombo.setEditText("")
        
        super(FindFileDialog, self).show()
        
    def on_findtextCombo_editTextChanged(self, text):
        """
        Private slot to handle the editTextChanged signal of the find
        text combo.
        
        @param text (ignored)
        """
        self.__enableFindButton()
        
    def on_replacetextCombo_editTextChanged(self, text):
        """
        Private slot to handle the editTextChanged signal of the replace
        text combo.
        
        @param text (ignored)
        """
        self.__enableFindButton()
        
    def on_dirPicker_editTextChanged(self, text):
        """
        Private slot to handle the textChanged signal of the directory
        picker.
        
        @param text (ignored)
        """
        self.__enableFindButton()
        
    @pyqtSlot()
    def on_projectButton_clicked(self):
        """
        Private slot to handle the selection of the project radio button.
        """
        self.__enableFindButton()
        
    @pyqtSlot()
    def on_dirButton_clicked(self):
        """
        Private slot to handle the selection of the project radio button.
        """
        self.__enableFindButton()
        
    @pyqtSlot()
    def on_filterCheckBox_clicked(self):
        """
        Private slot to handle the selection of the file filter check box.
        """
        self.__enableFindButton()
        
    @pyqtSlot(str)
    def on_filterEdit_textEdited(self, text):
        """
        Private slot to handle the textChanged signal of the file filter edit.
        
        @param text (ignored)
        """
        self.__enableFindButton()
        
    def __enableFindButton(self):
        """
        Private slot called to enable the find button.
        """
        if self.findtextCombo.currentText() == "" or \
           (self.__replaceMode and
            self.replacetextCombo.currentText() == "") or \
           (self.dirButton.isChecked() and
            (self.dirPicker.currentText() == "" or
             not os.path.exists(os.path.abspath(
                self.dirPicker.currentText())))) or \
           (self.filterCheckBox.isChecked() and self.filterEdit.text() == ""):
            self.findButton.setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        else:
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)
        
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.findButton:
            self.__doSearch()
        elif button == self.stopButton:
            self.__stopSearch()
        
    def __stripEol(self, txt):
        """
        Private method to strip the eol part.
        
        @param txt line of text that should be treated (string)
        @return text with eol stripped (string)
        """
        return txt.replace("\r", "").replace("\n", "")
        
    def __stopSearch(self):
        """
        Private slot to handle the stop button being pressed.
        """
        self.__cancelSearch = True
        
    def __doSearch(self):
        """
        Private slot to handle the find button being pressed.
        """
        if self.__replaceMode and \
           not e5App().getObject("ViewManager").checkAllDirty():
            return
        
        self.__cancelSearch = False
        
        if self.filterCheckBox.isChecked():
            fileFilter = self.filterEdit.text()
            fileFilterList = \
                ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*"))
                 for filter in fileFilter.split(";")]
            filterRe = re.compile("|".join(fileFilterList))
        
        if self.projectButton.isChecked():
            if self.filterCheckBox.isChecked():
                files = [self.project.getRelativePath(file)
                         for file in
                         self.__getFileList(
                             self.project.getProjectPath(), filterRe)]
            else:
                files = []
                if self.sourcesCheckBox.isChecked():
                    files += self.project.pdata["SOURCES"]
                if self.formsCheckBox.isChecked():
                    files += self.project.pdata["FORMS"]
                if self.interfacesCheckBox.isChecked():
                    files += self.project.pdata["INTERFACES"]
                if self.resourcesCheckBox.isChecked():
                    files += self.project.pdata["RESOURCES"]
        elif self.dirButton.isChecked():
            if not self.filterCheckBox.isChecked():
                filters = []
                if self.sourcesCheckBox.isChecked():
                    filters.extend(
                        ["^{0}$".format(
                            assoc.replace(".", "\.").replace("*", ".*"))
                         for assoc in list(
                             Preferences.getEditorLexerAssocs().keys())
                         if assoc not in self.formsExt + self.interfacesExt])
                if self.formsCheckBox.isChecked():
                    filters.append(self.filterForms)
                if self.interfacesCheckBox.isChecked():
                    filters.append(self.filterInterfaces)
                if self.resourcesCheckBox.isChecked():
                    filters.append(self.filterResources)
                filterString = "|".join(filters)
                filterRe = re.compile(filterString)
            files = self.__getFileList(
                os.path.abspath(self.dirPicker.currentText()),
                filterRe)
        elif self.openFilesButton.isChecked():
            vm = e5App().getObject("ViewManager")
            vm.checkAllDirty()
            files = vm.getOpenFilenames()
        
        self.findList.clear()
        QApplication.processEvents()
        QApplication.processEvents()
        self.findProgress.setMaximum(len(files))
        
        # retrieve the values
        reg = self.regexpCheckBox.isChecked()
        wo = self.wordCheckBox.isChecked()
        cs = self.caseCheckBox.isChecked()
        ct = self.findtextCombo.currentText()
        if reg:
            txt = ct
        else:
            txt = re.escape(ct)
        if wo:
            txt = "\\b{0}\\b".format(txt)
        flags = re.UNICODE | re.LOCALE
        if not cs:
            flags |= re.IGNORECASE
        try:
            search = re.compile(txt, flags)
        except re.error as why:
            E5MessageBox.critical(
                self,
                self.tr("Invalid search expression"),
                self.tr("""<p>The search expression is not valid.</p>"""
                        """<p>Error: {0}</p>""").format(str(why)))
            self.stopButton.setEnabled(False)
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)
            return
        # reset the findtextCombo
        if ct in self.searchHistory:
            self.searchHistory.remove(ct)
        self.searchHistory.insert(0, ct)
        self.findtextCombo.clear()
        self.findtextCombo.addItems(self.searchHistory)
        Preferences.Prefs.settings.setValue(
            "FindFileDialog/SearchHistory",
            self.searchHistory[:30])
        
        if self.__replaceMode:
            replTxt = self.replacetextCombo.currentText()
            if replTxt in self.replaceHistory:
                self.replaceHistory.remove(replTxt)
            self.replaceHistory.insert(0, replTxt)
            self.replacetextCombo.clear()
            self.replacetextCombo.addItems(self.replaceHistory)
            Preferences.Prefs.settings.setValue(
                "FindFileDialog/ReplaceHistory",
                self.replaceHistory[:30])
        
        if self.dirButton.isChecked():
            searchDir = self.dirPicker.currentText()
            if searchDir in self.dirHistory:
                self.dirHistory.remove(searchDir)
            self.dirHistory.insert(0, searchDir)
            self.dirPicker.clear()
            self.dirPicker.addItems(self.dirHistory)
            Preferences.Prefs.settings.setValue(
                "FindFileDialog/DirectoryHistory",
                self.dirHistory[:30])
        
        # set the button states
        self.stopButton.setEnabled(True)
        self.stopButton.setDefault(True)
        self.findButton.setEnabled(False)
        
        # now go through all the files
        self.__populating = True
        self.findList.setUpdatesEnabled(False)
        progress = 0
        breakSearch = False
        occurrences = 0
        fileOccurrences = 0
        for file in files:
            self.__lastFileItem = None
            found = False
            if self.__cancelSearch or breakSearch:
                break
            
            self.findProgressLabel.setPath(file)
            
            if self.projectButton.isChecked():
                fn = os.path.join(self.project.ppath, file)
            else:
                fn = file
            # read the file and split it into textlines
            try:
                text, encoding, hash = Utilities.readEncodedFileWithHash(fn)
                lines = text.splitlines(True)
            except (UnicodeError, IOError):
                progress += 1
                self.findProgress.setValue(progress)
                continue
            
            # now perform the search and display the lines found
            count = 0
            for line in lines:
                if self.__cancelSearch:
                    break
                
                count += 1
                contains = search.search(line)
                if contains:
                    occurrences += 1
                    found = True
                    start = contains.start()
                    end = contains.end()
                    if self.__replaceMode:
                        rline = search.sub(replTxt, line)
                    else:
                        rline = ""
                    line = self.__stripEol(line)
                    if len(line) > 1024:
                        line = "{0} ...".format(line[:1024])
                    if self.__replaceMode:
                        if len(rline) > 1024:
                            rline = "{0} ...".format(line[:1024])
                        line = "- {0}\n+ {1}".format(
                            line, self.__stripEol(rline))
                    self.__createItem(file, count, line, start, end,
                                      rline, hash)
                    
                    if self.feelLikeCheckBox.isChecked():
                        fn = os.path.join(self.project.ppath, file)
                        self.sourceFile.emit(fn, count, "", start, end)
                        QApplication.processEvents()
                        breakSearch = True
                        break
                
                QApplication.processEvents()
            
            if found:
                fileOccurrences += 1
            progress += 1
            self.findProgress.setValue(progress)
        
        if not files:
            self.findProgress.setMaximum(1)
            self.findProgress.setValue(1)
        
        resultFormat = self.tr("{0} / {1}", "occurrences / files")
        self.findProgressLabel.setPath(resultFormat.format(
            self.tr("%n occurrence(s)", "", occurrences),
            self.tr("%n file(s)", "", fileOccurrences)))
        
        self.findList.setUpdatesEnabled(True)
        self.findList.sortItems(self.findList.sortColumn(),
                                self.findList.header().sortIndicatorOrder())
        self.findList.resizeColumnToContents(1)
        if self.__replaceMode:
            self.findList.header().resizeSection(0, self.__section0Size + 30)
        self.findList.header().setStretchLastSection(True)
        self.__populating = False
        
        self.stopButton.setEnabled(False)
        self.findButton.setEnabled(True)
        self.findButton.setDefault(True)
        
        if breakSearch:
            self.close()
        
    def on_findList_itemDoubleClicked(self, itm, column):
        """
        Private slot to handle the double click on a file item.
        
        It emits the signal
        sourceFile or designerFile depending on the file extension.
        
        @param itm the double clicked tree item (QTreeWidgetItem)
        @param column column that was double clicked (integer) (ignored)
        """
        if itm.parent():
            file = itm.parent().text(0)
            line = itm.data(0, self.lineRole)
            start = itm.data(0, self.startRole)
            end = itm.data(0, self.endRole)
        else:
            file = itm.text(0)
            line = 1
            start = 0
            end = 0
        
        if self.project:
            fn = os.path.join(self.project.ppath, file)
        else:
            fn = file
        if fn.endswith('.ui'):
            self.designerFile.emit(fn)
        else:
            self.sourceFile.emit(fn, line, "", start, end)
        
    def __getFileList(self, path, filterRe):
        """
        Private method to get a list of files to search.
        
        @param path the root directory to search in (string)
        @param filterRe regular expression defining the filter
            criteria (regexp object)
        @return list of files to be processed (list of strings)
        """
        path = os.path.abspath(path)
        files = []
        for dirname, _, names in os.walk(path):
            files.extend([os.path.join(dirname, f)
                          for f in names
                          if re.match(filterRe, f)]
                         )
        return files
        
    def setSearchDirectory(self, searchDir):
        """
        Public slot to set the name of the directory to search in.
        
        @param searchDir name of the directory to search in (string)
        """
        self.dirButton.setChecked(True)
        self.dirPicker.setEditText(Utilities.toNativeSeparators(searchDir))
        
    def setOpenFiles(self):
        """
        Public slot to set the mode to search in open files.
        """
        self.openFilesButton.setChecked(True)
        
    @pyqtSlot()
    def on_replaceButton_clicked(self):
        """
        Private slot to perform the requested replace actions.
        """
        self.findProgress.setMaximum(self.findList.topLevelItemCount())
        self.findProgress.setValue(0)
        
        progress = 0
        for index in range(self.findList.topLevelItemCount()):
            itm = self.findList.topLevelItem(index)
            if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]:
                file = itm.text(0)
                origHash = itm.data(0, self.md5Role)
                
                self.findProgressLabel.setPath(file)
                
                if self.projectButton.isChecked():
                    fn = os.path.join(self.project.ppath, file)
                else:
                    fn = file
                
                # read the file and split it into textlines
                try:
                    text, encoding, hash = \
                        Utilities.readEncodedFileWithHash(fn)
                    lines = text.splitlines(True)
                except (UnicodeError, IOError) as err:
                    E5MessageBox.critical(
                        self,
                        self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not read the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""")
                        .format(fn, str(err))
                    )
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue
                
                # Check the original and the current hash. Skip the file,
                # if hashes are different.
                if origHash != hash:
                    E5MessageBox.critical(
                        self,
                        self.tr("Replace in Files"),
                        self.tr(
                            """<p>The current and the original hash of the"""
                            """ file <b>{0}</b> are different. Skipping it."""
                            """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>""")
                        .format(fn, origHash, hash)
                    )
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue
                
                # replace the lines authorized by the user
                for cindex in range(itm.childCount()):
                    citm = itm.child(cindex)
                    if citm.checkState(0) == Qt.Checked:
                        line = citm.data(0, self.lineRole)
                        rline = citm.data(0, self.replaceRole)
                        lines[line - 1] = rline
                
                # write the file
                txt = "".join(lines)
                try:
                    Utilities.writeEncodedFile(fn, txt, encoding)
                except (IOError, Utilities.CodingError, UnicodeError) as err:
                    E5MessageBox.critical(
                        self,
                        self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not save the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""")
                        .format(fn, str(err))
                    )
            
            progress += 1
            self.findProgress.setValue(progress)
        
        self.findProgressLabel.setPath("")
        
        self.findList.clear()
        self.replaceButton.setEnabled(False)
        self.findButton.setEnabled(True)
        self.findButton.setDefault(True)
        
    def __contextMenuRequested(self, pos):
        """
        Private slot to handle the context menu request.
        
        @param pos position the context menu shall be shown (QPoint)
        """
        menu = QMenu(self)
        
        menu.addAction(self.tr("Open"), self.__openFile)
        menu.addAction(self.tr("Copy Path to Clipboard"),
                       self.__copyToClipboard)
        
        menu.exec_(QCursor.pos())
        
    def __openFile(self):
        """
        Private slot to open the currently selected entry.
        """
        itm = self.findList.selectedItems()[0]
        self.on_findList_itemDoubleClicked(itm, 0)
        
    def __copyToClipboard(self):
        """
        Private method to copy the path of an entry to the clipboard.
        """
        itm = self.findList.selectedItems()[0]
        if itm.parent():
            fn = itm.parent().text(0)
        else:
            fn = itm.text(0)
        
        cb = QApplication.clipboard()
        cb.setText(fn)
class Waterfall(QWidget, waterfall.Ui_Waterfall):
    
    plot_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params
    updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing

    def __init__(self, parent):
        super(Waterfall,self).__init__(parent)
        self.setupUi(self)
        
        self.get_settings()
        #self.send_settings()

        #Button functions
        self.btn_apply_general_settings.clicked.connect(self.send_settings)
        self.btn_apply_keys_and_colors_settings.clicked.connect(self.send_settings)
        self.patient_tree = self.create_patient_tree()
        self.data_viewer_container.addWidget(self.patient_tree)
        self.btn_color_test.clicked.connect(self.get_color)
        
    def get_color(self):
        self.color = QColorDialog.getColor() #returns a color object
        print(color)

    def get_settings(self):
        try:
            with shelve.open('WaterfallSettings') as shelfFile: 
                self.keys_and_colors = shelfFile['keys_and_colors']
                shelfFile.close()
        except:
            #set and use default settings
            self.keys_and_colors = {
                                    'CR':'#03945D',
                                    'PR':'#B1EE97',
                                    'PD':'#FF6F69',
                                    'SD':'#707070'}
            with shelve.open('WaterfallSettings') as shelfFile:
                shelfFile['keys_and_colors'] = self.keys_and_colors
                shelfFile.close()
        
    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        
    def on_generated_rectangles_signal(self,signal):
        self.rectangles_received = signal[0]
        self.add_items() #display in table
        self.btn_apply_general_settings.setEnabled(True)
        self.btn_finalize_plot.setEnabled(True)
        self.btn_apply_keys_and_colors_settings.setEnabled(True)

    def send_settings(self):
        '''
        Emit both general plot settings, and color labeling settings. These are the settings to be used when the plot is created.
        '''
        print(self.get_updated_color_coding()
        self.general_settings = [
                                        self.plot_title.text(),
                                        self.x_label.text(),
                                        self.y_label.text(),
                                        [self.twenty_percent_line.isChecked(),
                                        self.thirty_percent_line.isChecked(),
                                        self.zero_percent_line.isChecked()],
                                        [self.display_responses_as_text.isChecked(),
                                        self.display_responses_as_color.isChecked(),
                                        self.display_no_responses.isChecked()],
                                        self.include_table.isChecked(),
                                        self.show_cancer_type.isChecked()
                                    ]
        self.plot_settings_signal.emit(self.general_settings)

    def create_patient_tree(self):
        '''
        Create QTreeWidget populated with a patient's data for the DataEntry dialog.
        Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog.
        '''
        self.tree = QTreeWidget()
        self.root = self.tree.invisibleRootItem()
        self.headers = [
                        'Patient #',
                        'Best response %',
                        'Response',
                        'Cancer',
                        'Color key',
                        ]
        self.headers_item = QTreeWidgetItem(self.headers)
        self.tree.setColumnCount(len(self.headers))
        self.tree.setHeaderItem(self.headers_item)
        self.root.setExpanded(True)
        self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        self.tree.clear() #clear prior to entering items, prevent aggregation
        i=0
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            self.rect_item = QTreeWidgetItem(self.root)
            self.rect_params = [
                                self.waterfall_data['Patient number'][i], 
                                rect.get_height(),
                                self.waterfall_data['Overall response'][i],
                                self.waterfall_data['Cancer'][i]
                                ]
            for col in range(0,4):
                self.rect_item.setText(col,str(self.rect_params[col]))
                self.rect_item.setTextAlignment(col,4)
            self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.keys_and_colors,self.waterfall_data['Overall response'][i]))
            self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable)
            i+=1

    def get_updated_color_coding(self):
        tmp_updated_color_coding = []
        self.root = self.tree.invisibleRootItem()
        child_count = self.root.childCount()
        # for i in range(child_count):
        #     child_item = self.root.child(i)
        #     self.tree.itemWidget(self.root.child(i),4).currentText()
        return [self.tree.itemWidget(self.root.child(i),4).currentText() for i in range(child_count)]

    def on_updated_tree_item(self):
        #update the rectangle which was edited
        pass

class WaterfallPlotter(QWidget):

    generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree

    def __init__(self,parent):
        super(WaterfallPlotter,self).__init__(parent)

        self.get_settings()
        self.settings_update = False

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas,self)

        self.btn_plot = QPushButton('Default Plot')
        self.btn_plot.clicked.connect(self.default_plot)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.btn_plot)
        self.setLayout(self.layout)
        
    
    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        self.btn_plot.setEnabled(True)

    def get_settings(self):
        try:
            with shelve.open('WaterfallSettings') as shelfFile: 
                self.keys_and_colors = shelfFile['keys_and_colors']
                shelfFile.close()
        except:
            #set and use default settings
            self.keys_and_colors = {
                                    'CR':'#03945D',
                                    'PR':'#B1EE97',
                                    'PD':'#FF6F69',
                                    'SD':'#707070'}
            with shelve.open('WaterfallSettings') as shelfFile:
                shelfFile['keys_and_colors'] = self.keys_and_colors
                shelfFile.close()

    def on_general_settings_signal(self,signal):
        self.gen_settings = signal
        self.settings_update = True
        self.default_plot()
    
    def get_bar_colors(self,responses):
        return [self.keys_and_colors[x] for x in responses]

    def default_plot(self):
        '''
        Plot waterfall data
        '''            
        self.figure.clear()
        self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change']))
        self.ax = self.figure.add_subplot(111)
        self.bar_colors = self.get_bar_colors(self.waterfall_data['Overall response'])

        if self.settings_update == False:
            self.ax.tick_params(
                            axis='x',          # changes apply to the x-axis
                            which='both',      # both major and minor ticks are affected
                            bottom='on',      # ticks along the bottom edge are off
                            top='on',         # ticks along the top edge are off
                            labelbottom='on'
                            ) # labels along the bottom edge are off
            self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
            self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
            self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')
            self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
            self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors)

        else:
            #settings were updated, we received them and stored in variable self.gen_settings
            self.ax.set_title(self.gen_settings[0])
            self.ax.set_xlabel(self.gen_settings[1])
            self.ax.set_ylabel(self.gen_settings[2])
            if self.gen_settings[3][0]:
                self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
            if self.gen_settings[3][1]:
                self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
            if self.gen_settings[3][2]:
                self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')

            if self.gen_settings[4][0] and ~self.gen_settings[6]:
                #show responses as labels, default color bars
                #legend depends on user specified keys
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'])
                self.add_labels(self.ax, self.rects, self.waterfall_data, 1)
            elif self.gen_settings[4][1]:
                #color bars with response type
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors)
                self.patches = []
                for key in self.keys_and_colors.keys():
                    self.patches.append(mpatches.Patch(color = self.keys_and_colors[key],label=key))
                self.ax.legend(handles=self.patches)
            else:
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'])
            
            if self.gen_settings[5]:
                self.plot_table()
            
            if self.gen_settings[6] and ~self.gen_settings[4][0]:
                self.add_labels(self.ax, self.rects, self.waterfall_data, 0)
            
            if ~self.gen_settings[4][1]:
                #response not shown as color coding, custom color code the bars
                pass

        self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
        self.canvas.draw()
        self.generated_rectangles_signal.emit([self.rects])
            
    def plot_table(self):
        rows = ['%s' % x for x in self.waterfall_data.keys()]
        rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows
        columns = self.waterfall_data['Patient number'] #patient numbers
        cell_text = []
        for row in rows:
            cell_text_temp = []
            for col in range(len(columns)):
                cell_text_temp.append(self.waterfall_data[row][col])
            cell_text.append(cell_text_temp)
        the_table = self.ax.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center', colLoc='center')
        plt.subplots_adjust(bottom=0.15,left=0.5)
        self.ax.set_xlim(-0.5,len(columns)-0.5)
        self.ax.tick_params(
                        axis='x',          # changes apply to the x-axis
                        which='both',      # both major and minor ticks are affected
                        bottom='off',      # ticks along the bottom edge are off
                        top='off',         # ticks along the top edge are off
                        labelbottom='off'
                        ) # labels along the bottom edge are off
    
    def update_plot(self):
        '''
        TODO
        '''
        pass
                    
    def add_labels(self, ax, rects, waterfall_data, label_type):
        '''
        Add labels above/below bars. label_type == 1 --> display responses; == 0 --> display cancer type
        '''
        i = 0
        if label_type:
            for rect in rects:
                height = rect.get_height()
                if height >= 0:
                    valign = 'bottom'
                else:
                    valign = 'top'
                    
                ax.text(rect.get_x() + rect.get_width()/2., height,
                        '%s' % waterfall_data['Overall response'][i], ha='center', va=valign)
                i+=1
        else:
            for rect in rects:
                height = rect.get_height()
                if height >= 0:
                    valign = 'top'
                    hgt = -1
                else:
                    valign = 'bottom'
                    hgt = 1

                ax.text(rect.get_x() + rect.get_width()/2., hgt,
                        '%s' % waterfall_data['Cancer'][i], ha='center', va=valign, rotation='vertical')
                i+=1   
Пример #22
0
    def load_data_func(self):
        calibration_prefixes, sample_prefixes = self.get_prefixes_from_tables()

        # Load drift data
        drift_path = self.load_drift_file_lineEdit.text()
        self.datasets.read_drift_data(drift_path)

        drift_data = self.datasets.get_drift_data()
        self.driftDataModel = PandasModel(drift_data)
        self.driftDataTableView.setModel(self.driftDataModel)
        self.driftDataTableView.show()

        # Fill session tree
        session_files = self.datasets.get_session_dict()
        unique_sessions = self.datasets.get_sessions()

        tree = self.sessionTreeWidget
        tree.clear()

        for s in unique_sessions:
            session_item = QTreeWidgetItem(tree)
            session_item.setText(0, s)
            session_item.setFlags(session_item.flags() | Qt.ItemIsTristate
                                  | Qt.ItemIsUserCheckable)

            files = session_files[s]
            for f in files:
                file_item = QTreeWidgetItem(session_item)
                file_item.setFlags(file_item.flags() | Qt.ItemIsUserCheckable)
                file_item.setText(0, f)
                file_item.setCheckState(0, Qt.Unchecked)

        tree.setHeaderLabel("Session")

        self.sessionTreeWidget.doubleClicked.connect(
            self.onSessionTreeDoubleClick)

        # Load calibration data
        calibration_path = self.load_calibration_file_lineEdit.text()
        self.datasets.read_calibration_data(calibration_path)

        calibration_data = self.datasets.get_calibration_data()
        self.calibrationDataModel = PandasModel(calibration_data)
        self.calibrationDataTableView.setModel(self.calibrationDataModel)
        self.calibrationDataTableView.show()

        # Load datasets
        datasets_path = self.load_dir_lineEdit.text()
        self.datasets.read_datasets(datasets_path)

        # Load elements tree
        tree = self.labelElementsTreeWidget
        tree.clear()
        elements = [
            e
            for e in next(iter(self.datasets.get_datasets().values())).columns
            if e.lower() not in ['time', 'delay']
        ]
        for e in elements:
            item = QTreeWidgetItem(tree)
            item.setText(0, e)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            if e.lower()[:4] in ['mg24', 'ca43', 'ca44']:
                item.setCheckState(0, Qt.Checked)
            else:
                item.setCheckState(0, Qt.Unchecked)
Пример #23
0
    def _populate_repo_tree(self):
        """
        Initialize the tree widget of repos and volumes.
        """
        self._repo_treewidget.clear()

        if self._repos_info is None:
            return

        for repo_uuid, repo_info in sorted(self._repos_info.items()):
            if repo_info is None:
                continue
            repo_column_dict = collections.defaultdict(str)
            repo_column_dict["Alias"] = repo_info["Alias"]
            repo_column_dict["Details"] = "Created: " + repo_info["Created"]
            repo_column_dict["UUID"] = repo_uuid
            repo_column_values = [
                repo_column_dict[k] for k in TREEVIEW_COLUMNS
            ]
            repo_item = QTreeWidgetItem(self._repo_treewidget,
                                        repo_column_values)
            repo_item.setData(0, Qt.UserRole, (repo_uuid, "", ""))
            for data_name, data_info in repo_info["DataInstances"].items():
                data_instance_dict = collections.defaultdict(str)
                data_instance_dict["Alias"] = data_name
                typename = data_info["Base"]["TypeName"]
                data_instance_dict["TypeName"] = typename

                is_voxels = (typename in VOXEL_TYPENAMES)
                if is_voxels:
                    start_coord = data_info["Extended"]["MinPoint"]
                    if start_coord:
                        start_coord = tuple(start_coord)
                    stop_coord = data_info["Extended"]["MaxPoint"]
                    if stop_coord:
                        stop_coord = tuple(x + 1 for x in stop_coord)
                    if start_coord and stop_coord:
                        shape = tuple(b - a
                                      for a, b in zip(start_coord, stop_coord))
                    else:
                        shape = None
                    data_instance_dict[
                        "Details"] = "Size={} | Start={} | Stop={}".format(
                            shape, start_coord, stop_coord)

                data_column_values = [
                    data_instance_dict[k] for k in TREEVIEW_COLUMNS
                ]
                data_item = QTreeWidgetItem(repo_item, data_column_values)
                data_item.setData(0, Qt.UserRole,
                                  (repo_uuid, data_name, typename))

                # If we're in specify_new mode, only the
                # repo parent items are selectable.
                # Also, non-volume items aren't selectable.
                if self._mode == 'specify_new' or typename not in self._selectable_types:
                    flags = data_item.flags()
                    flags &= ~Qt.ItemIsSelectable
                    flags &= ~Qt.ItemIsEnabled
                    data_item.setFlags(flags)

        self._repo_treewidget.collapseAll()
        self._repo_treewidget.setSortingEnabled(True)

        if self._hostname in self._default_nodes:
            self._select_node_uuid(self._default_nodes[self._hostname])

        self._repo_treewidget.resizeColumnToContents(0)
        self._repo_treewidget.setFocus()
Пример #24
0
    def populate_available_terms(self):
        """
        Runs when annotations tab is viewed and when volume is changed. Populates the avaible annotation terms.
        """

        self.ui.treeWidgetAvailableTerms.clear()

        vol = self.controller.current_annotation_volume()
        if not vol or None in (vol.annotations.stage, vol.annotations.center):
            # info_dialog(self, 'Chose centre and stage', 'You must choose a centre and stage from the options tab')
            return

        self.ui.lineEditCentre.setText(vol.annotations.center)
        self.ui.lineEditStage.setText(vol.annotations.stage.name)

        self.ui.lineEditModality.setText(vol.annotations.modality.value)

        def setup_option_box_signal(box_: QComboBox, child_: QTreeWidgetItem):
            """
            Connect the Qcombobox to a slot
            """
            box_.activated.connect(
                partial(self.update_annotation, child_, box_))
            # Setup signal so when combobox is only opened, it sets the selection to that column
            box_.highlighted.connect(partial(self.on_box_highlight, child))

        header_labels = QTreeWidgetItem(
            ['', 'term', 'name', 'option', 'done?'])

        self.ui.treeWidgetAvailableTerms.setHeaderItem(header_labels)

        parent = QTreeWidgetItem(self.ui.treeWidgetAvailableTerms)
        parent.setText(0, '')
        parent.setFlags(parent.flags())
        parent.setExpanded(True)

        header = self.ui.treeWidgetAvailableTerms.header()

        # Set root column to invisible
        self.ui.treeWidgetAvailableTerms.setColumnWidth(0, 0)
        header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)

        # For each annotation set an info row in the annotations table
        for i, ann in enumerate(
                sorted(vol.annotations, key=lambda an_: an_.order)):

            child = QTreeWidgetItem(parent)
            child.setText(1, ann.term)
            child.setText(3, ann.name)
            option = ann.selected_option
            # color = OPTION_COLOR_MAP[option]
            parent.addChild(child)

            # Set up the parameter option combobox and highlight the currently selected one
            options_box = QComboBox()
            options_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)

            for opt in ann.options:
                options_box.addItem(opt)

            options_box.setCurrentIndex(options_box.findText(
                option))  # 060818  Louise's bug option is a bool not a str

            # Setup combobox selection signal
            setup_option_box_signal(options_box, child)
            self.ui.treeWidgetAvailableTerms.setItemWidget(
                child, 2, options_box)

            done_checkbox = QtWidgets.QCheckBox()
            done_checkbox.setChecked(ann.looked_at)

            done_checkbox.stateChanged.connect(
                partial(self.parameter_done_signal, child, done_checkbox))
            self.ui.treeWidgetAvailableTerms.setItemWidget(
                child, 4, done_checkbox)

        # Set the roi coords to None
        self.roi_highlight_off_signal.emit()
Пример #25
0
class PatientTree(QTreeWidget):
    def __init__(self,pt):
        QWidget.__init__(self)
    
        self.tree = QTreeWidget()
        self.root = self.tree.invisibleRootItem()
        
        self.headers = [
                        'Exam',
                        'Follow-Up',
                        'Name',
                        'Description',
                        'Target',
                        'Sub-Type',
                        'Series',
                        'Slice#',
                        'RECIST Diameter (cm)'
                        ]

        self.headers_item = QTreeWidgetItem(self.headers)

        self.tree.setColumnCount(len(self.headers))
        self.tree.setHeaderItem(self.headers_item)
        self.root.setExpanded(True)

        self.addItems(self.root,pt)

        self.tree.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
    
        layout = QStackedLayout()
        layout.addWidget(self.tree)
        self.setLayout(layout)
    
    def addItems(self,parent,pt):
        '''
        Add items to the table from the patient object
        '''
        for key,exam in pt.exams.items():
            column = 0
            self.exam_item = QTreeWidgetItem(parent)
            self.exam_item.setText(column,', '.join([str(exam.date),str(exam.modality),str(exam.description)]))

            if exam.ignore == False:
                self.exam_item.setCheckState (column, QtCore.Qt.Checked)
            else:
                self.exam_item.setCheckState (column, QtCore.Qt.Unchecked)

            for lesion in exam.lesions:
                column = 1
                if lesion.params['Target'].lower() == 'target' or lesion.params['Target'].lower() == 'non-target':
                    self.param_list = [
                                        lesion.params['Follow-Up'],
                                        lesion.params['Name'],
                                        lesion.params['Description'],
                                        lesion.params['Target'],
                                        lesion.params['Sub-Type'],
                                        lesion.params['Series'],
                                        lesion.params['Slice#'],
                                        round(lesion.params['RECIST Diameter (mm)']/10,1)
                                        ]
                                        
                    self.lesion_item = QTreeWidgetItem(self.exam_item)
                    self.lesion_item.setCheckState(column,QtCore.Qt.Checked)
                    for param_str in self.param_list:
                        self.lesion_item.setText(column,str(self.param_list[column-1]))
                        self.lesion_item.setTextAlignment(column,4) #align center of column
                        column += 1
                    self.lesion_item.setFlags(self.lesion_item.flags() | QtCore.Qt.ItemIsEditable)
Пример #26
0
 def add_root_item(self):
     item = QTreeWidgetItem(self, ['New Item'])
     item.setFlags(item.flags() | Qt.ItemIsEditable)
     self.addTopLevelItem(item)
     self.setCurrentItem(item)
     self.editItem(item)
Пример #27
0
 def addItemToTreeView(self, name, uid):
     itemName = [name, str(uid)]
     item = QTreeWidgetItem(self.treeViewRoot, itemName)
     item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
     item.setCheckState(0, Qt.Checked)
Пример #28
0
class FindFileDialog(QDialog, Ui_FindFileDialog):
    """
    Class implementing a dialog to search for text in files.
    
    The occurrences found are displayed in a QTreeWidget showing the filename,
    the linenumber and the found text. The file will be opened upon a double
    click onto the respective entry of the list.
    
    @signal sourceFile(str, int, str, int, int) emitted to open a source file
        at a line
    @signal designerFile(str) emitted to open a Qt-Designer file
    """
    sourceFile = pyqtSignal(str, int, str, int, int)
    designerFile = pyqtSignal(str)

    lineRole = Qt.UserRole + 1
    startRole = Qt.UserRole + 2
    endRole = Qt.UserRole + 3
    replaceRole = Qt.UserRole + 4
    md5Role = Qt.UserRole + 5

    def __init__(self, project, replaceMode=False, parent=None):
        """
        Constructor
        
        @param project reference to the project object
        @param replaceMode flag indicating the replace dialog mode (boolean)
        @param parent parent widget of this dialog (QWidget)
        """
        super(FindFileDialog, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(Qt.Window)

        self.dirSelectButton.setIcon(UI.PixmapCache.getIcon("open.png"))

        self.__replaceMode = replaceMode

        self.stopButton = \
            self.buttonBox.addButton(self.tr("Stop"),
                                     QDialogButtonBox.ActionRole)
        self.stopButton.setEnabled(False)

        self.findButton = \
            self.buttonBox.addButton(self.tr("Find"),
                                     QDialogButtonBox.ActionRole)
        self.findButton.setEnabled(False)
        self.findButton.setDefault(True)

        if self.__replaceMode:
            self.replaceButton.setEnabled(False)
            self.setWindowTitle(self.tr("Replace in Files"))
        else:
            self.replaceLabel.hide()
            self.replacetextCombo.hide()
            self.replaceButton.hide()

        self.findProgressLabel.setMaximumWidth(550)

        self.findtextCombo.setCompleter(None)
        self.replacetextCombo.setCompleter(None)

        self.searchHistory = Preferences.toList(
            Preferences.Prefs.settings.value("FindFileDialog/SearchHistory"))
        self.replaceHistory = Preferences.toList(
            Preferences.Prefs.settings.value("FindFileDialog/ReplaceHistory"))
        self.dirHistory = Preferences.toList(
            Preferences.Prefs.settings.value(
                "FindFileDialog/DirectoryHistory"))
        self.findtextCombo.addItems(self.searchHistory)
        self.replacetextCombo.addItems(self.replaceHistory)
        self.dirCombo.addItems(self.dirHistory)

        self.project = project

        self.findList.headerItem().setText(self.findList.columnCount(), "")
        self.findList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.__section0Size = self.findList.header().sectionSize(0)
        self.findList.setExpandsOnDoubleClick(False)
        if self.__replaceMode:
            font = Preferences.getEditorOtherFonts("MonospacedFont")
            self.findList.setFont(font)

        # Qt Designer form files
        self.filterForms = r'.*\.ui$'
        self.formsExt = ['*.ui']

        # Corba interface files
        self.filterInterfaces = r'.*\.idl$'
        self.interfacesExt = ['*.idl']

        # Qt resources files
        self.filterResources = r'.*\.qrc$'
        self.resourcesExt = ['*.qrc']

        self.__cancelSearch = False
        self.__lastFileItem = None
        self.__populating = False

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenuRequested)

    def __createItem(self, file, line, text, start, end, replTxt="", md5=""):
        """
        Private method to create an entry in the file list.
        
        @param file filename of file (string)
        @param line line number (integer)
        @param text text found (string)
        @param start start position of match (integer)
        @param end end position of match (integer)
        @param replTxt text with replacements applied (string)
        @keyparam md5 MD5 hash of the file (string)
        """
        if self.__lastFileItem is None:
            # It's a new file
            self.__lastFileItem = QTreeWidgetItem(self.findList, [file])
            self.__lastFileItem.setFirstColumnSpanned(True)
            self.__lastFileItem.setExpanded(True)
            if self.__replaceMode:
                self.__lastFileItem.setFlags(
                    self.__lastFileItem.flags()
                    | Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate))
                # Qt bug:
                # item is not user checkable if setFirstColumnSpanned
                # is True (< 4.5.0)
            self.__lastFileItem.setData(0, self.md5Role, md5)

        itm = QTreeWidgetItem(self.__lastFileItem)
        itm.setTextAlignment(0, Qt.AlignRight)
        itm.setData(0, Qt.DisplayRole, line)
        itm.setData(1, Qt.DisplayRole, text)
        itm.setData(0, self.lineRole, line)
        itm.setData(0, self.startRole, start)
        itm.setData(0, self.endRole, end)
        itm.setData(0, self.replaceRole, replTxt)
        if self.__replaceMode:
            itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable))
            itm.setCheckState(0, Qt.Checked)
            self.replaceButton.setEnabled(True)

    def show(self, txt=""):
        """
        Public method to enable/disable the project button.
        
        @param txt text to be shown in the searchtext combo (string)
        """
        if self.project and self.project.isOpen():
            self.projectButton.setEnabled(True)
        else:
            self.projectButton.setEnabled(False)
            self.dirButton.setChecked(True)

        self.findtextCombo.setEditText(txt)
        self.findtextCombo.lineEdit().selectAll()
        self.findtextCombo.setFocus()

        if self.__replaceMode:
            self.findList.clear()
            self.replacetextCombo.setEditText("")

        super(FindFileDialog, self).show()

    def on_findtextCombo_editTextChanged(self, text):
        """
        Private slot to handle the editTextChanged signal of the find
        text combo.
        
        @param text (ignored)
        """
        self.__enableFindButton()

    def on_replacetextCombo_editTextChanged(self, text):
        """
        Private slot to handle the editTextChanged signal of the replace
        text combo.
        
        @param text (ignored)
        """
        self.__enableFindButton()

    def on_dirCombo_editTextChanged(self, text):
        """
        Private slot to handle the textChanged signal of the directory
        combo box.
        
        @param text (ignored)
        """
        self.__enableFindButton()

    @pyqtSlot()
    def on_projectButton_clicked(self):
        """
        Private slot to handle the selection of the project radio button.
        """
        self.__enableFindButton()

    @pyqtSlot()
    def on_dirButton_clicked(self):
        """
        Private slot to handle the selection of the project radio button.
        """
        self.__enableFindButton()

    @pyqtSlot()
    def on_filterCheckBox_clicked(self):
        """
        Private slot to handle the selection of the file filter check box.
        """
        self.__enableFindButton()

    @pyqtSlot(str)
    def on_filterEdit_textEdited(self, text):
        """
        Private slot to handle the textChanged signal of the file filter edit.
        
        @param text (ignored)
        """
        self.__enableFindButton()

    def __enableFindButton(self):
        """
        Private slot called to enable the find button.
        """
        if self.findtextCombo.currentText() == "" or \
           (self.__replaceMode and
            self.replacetextCombo.currentText() == "") or \
           (self.dirButton.isChecked() and
            (self.dirCombo.currentText() == "" or
             not os.path.exists(os.path.abspath(
                self.dirCombo.currentText())))) or \
           (self.filterCheckBox.isChecked() and self.filterEdit.text() == ""):
            self.findButton.setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        else:
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)

    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.findButton:
            self.__doSearch()
        elif button == self.stopButton:
            self.__stopSearch()

    def __stripEol(self, txt):
        """
        Private method to strip the eol part.
        
        @param txt line of text that should be treated (string)
        @return text with eol stripped (string)
        """
        return txt.replace("\r", "").replace("\n", "")

    def __stopSearch(self):
        """
        Private slot to handle the stop button being pressed.
        """
        self.__cancelSearch = True

    def __doSearch(self):
        """
        Private slot to handle the find button being pressed.
        """
        if self.__replaceMode and \
           not e5App().getObject("ViewManager").checkAllDirty():
            return

        self.__cancelSearch = False

        if self.filterCheckBox.isChecked():
            fileFilter = self.filterEdit.text()
            fileFilterList = \
                ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*"))
                 for filter in fileFilter.split(";")]
            filterRe = re.compile("|".join(fileFilterList))

        if self.projectButton.isChecked():
            if self.filterCheckBox.isChecked():
                files = [
                    self.project.getRelativePath(file)
                    for file in self.__getFileList(
                        self.project.getProjectPath(), filterRe)
                ]
            else:
                files = []
                if self.sourcesCheckBox.isChecked():
                    files += self.project.pdata["SOURCES"]
                if self.formsCheckBox.isChecked():
                    files += self.project.pdata["FORMS"]
                if self.interfacesCheckBox.isChecked():
                    files += self.project.pdata["INTERFACES"]
                if self.resourcesCheckBox.isChecked():
                    files += self.project.pdata["RESOURCES"]
        elif self.dirButton.isChecked():
            if not self.filterCheckBox.isChecked():
                filters = []
                if self.sourcesCheckBox.isChecked():
                    filters.extend([
                        "^{0}$".format(
                            assoc.replace(".", "\.").replace("*", ".*"))
                        for assoc in list(
                            Preferences.getEditorLexerAssocs().keys())
                        if assoc not in self.formsExt + self.interfacesExt
                    ])
                if self.formsCheckBox.isChecked():
                    filters.append(self.filterForms)
                if self.interfacesCheckBox.isChecked():
                    filters.append(self.filterInterfaces)
                if self.resourcesCheckBox.isChecked():
                    filters.append(self.filterResources)
                filterString = "|".join(filters)
                filterRe = re.compile(filterString)
            files = self.__getFileList(
                os.path.abspath(self.dirCombo.currentText()), filterRe)
        elif self.openFilesButton.isChecked():
            vm = e5App().getObject("ViewManager")
            vm.checkAllDirty()
            files = vm.getOpenFilenames()

        self.findList.clear()
        QApplication.processEvents()
        QApplication.processEvents()
        self.findProgress.setMaximum(len(files))

        # retrieve the values
        reg = self.regexpCheckBox.isChecked()
        wo = self.wordCheckBox.isChecked()
        cs = self.caseCheckBox.isChecked()
        ct = self.findtextCombo.currentText()
        if reg:
            txt = ct
        else:
            txt = re.escape(ct)
        if wo:
            txt = "\\b{0}\\b".format(txt)
        flags = re.UNICODE | re.LOCALE
        if not cs:
            flags |= re.IGNORECASE
        try:
            search = re.compile(txt, flags)
        except re.error as why:
            E5MessageBox.critical(
                self, self.tr("Invalid search expression"),
                self.tr("""<p>The search expression is not valid.</p>"""
                        """<p>Error: {0}</p>""").format(str(why)))
            self.stopButton.setEnabled(False)
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)
            return
        # reset the findtextCombo
        if ct in self.searchHistory:
            self.searchHistory.remove(ct)
        self.searchHistory.insert(0, ct)
        self.findtextCombo.clear()
        self.findtextCombo.addItems(self.searchHistory)
        Preferences.Prefs.settings.setValue("FindFileDialog/SearchHistory",
                                            self.searchHistory[:30])

        if self.__replaceMode:
            replTxt = self.replacetextCombo.currentText()
            if replTxt in self.replaceHistory:
                self.replaceHistory.remove(replTxt)
            self.replaceHistory.insert(0, replTxt)
            self.replacetextCombo.clear()
            self.replacetextCombo.addItems(self.replaceHistory)
            Preferences.Prefs.settings.setValue(
                "FindFileDialog/ReplaceHistory", self.replaceHistory[:30])

        if self.dirButton.isChecked():
            searchDir = self.dirCombo.currentText()
            if searchDir in self.dirHistory:
                self.dirHistory.remove(searchDir)
            self.dirHistory.insert(0, searchDir)
            self.dirCombo.clear()
            self.dirCombo.addItems(self.dirHistory)
            Preferences.Prefs.settings.setValue(
                "FindFileDialog/DirectoryHistory", self.dirHistory[:30])

        # set the button states
        self.stopButton.setEnabled(True)
        self.stopButton.setDefault(True)
        self.findButton.setEnabled(False)

        # now go through all the files
        self.__populating = True
        self.findList.setUpdatesEnabled(False)
        progress = 0
        breakSearch = False
        occurrences = 0
        fileOccurrences = 0
        for file in files:
            self.__lastFileItem = None
            found = False
            if self.__cancelSearch or breakSearch:
                break

            self.findProgressLabel.setPath(file)

            if self.projectButton.isChecked():
                fn = os.path.join(self.project.ppath, file)
            else:
                fn = file
            # read the file and split it into textlines
            try:
                text, encoding, hash = Utilities.readEncodedFileWithHash(fn)
                lines = text.splitlines(True)
            except (UnicodeError, IOError):
                progress += 1
                self.findProgress.setValue(progress)
                continue

            # now perform the search and display the lines found
            count = 0
            for line in lines:
                if self.__cancelSearch:
                    break

                count += 1
                contains = search.search(line)
                if contains:
                    occurrences += 1
                    found = True
                    start = contains.start()
                    end = contains.end()
                    if self.__replaceMode:
                        rline = search.sub(replTxt, line)
                    else:
                        rline = ""
                    line = self.__stripEol(line)
                    if len(line) > 1024:
                        line = "{0} ...".format(line[:1024])
                    if self.__replaceMode:
                        if len(rline) > 1024:
                            rline = "{0} ...".format(line[:1024])
                        line = "- {0}\n+ {1}".format(line,
                                                     self.__stripEol(rline))
                    self.__createItem(file, count, line, start, end, rline,
                                      hash)

                    if self.feelLikeCheckBox.isChecked():
                        fn = os.path.join(self.project.ppath, file)
                        self.sourceFile.emit(fn, count, "", start, end)
                        QApplication.processEvents()
                        breakSearch = True
                        break

                QApplication.processEvents()

            if found:
                fileOccurrences += 1
            progress += 1
            self.findProgress.setValue(progress)

        if not files:
            self.findProgress.setMaximum(1)
            self.findProgress.setValue(1)

        resultFormat = self.tr("{0} / {1}", "occurrences / files")
        self.findProgressLabel.setPath(
            resultFormat.format(self.tr("%n occurrence(s)", "", occurrences),
                                self.tr("%n file(s)", "", fileOccurrences)))

        self.findList.setUpdatesEnabled(True)
        self.findList.sortItems(self.findList.sortColumn(),
                                self.findList.header().sortIndicatorOrder())
        self.findList.resizeColumnToContents(1)
        if self.__replaceMode:
            self.findList.header().resizeSection(0, self.__section0Size + 30)
        self.findList.header().setStretchLastSection(True)
        self.__populating = False

        self.stopButton.setEnabled(False)
        self.findButton.setEnabled(True)
        self.findButton.setDefault(True)

        if breakSearch:
            self.close()

    def on_findList_itemDoubleClicked(self, itm, column):
        """
        Private slot to handle the double click on a file item.
        
        It emits the signal
        sourceFile or designerFile depending on the file extension.
        
        @param itm the double clicked tree item (QTreeWidgetItem)
        @param column column that was double clicked (integer) (ignored)
        """
        if itm.parent():
            file = itm.parent().text(0)
            line = itm.data(0, self.lineRole)
            start = itm.data(0, self.startRole)
            end = itm.data(0, self.endRole)
        else:
            file = itm.text(0)
            line = 1
            start = 0
            end = 0

        if self.project:
            fn = os.path.join(self.project.ppath, file)
        else:
            fn = file
        if fn.endswith('.ui'):
            self.designerFile.emit(fn)
        else:
            self.sourceFile.emit(fn, line, "", start, end)

    @pyqtSlot()
    def on_dirSelectButton_clicked(self):
        """
        Private slot to display a directory selection dialog.
        """
        directory = E5FileDialog.getExistingDirectory(
            self, self.tr("Select directory"), self.dirCombo.currentText(),
            E5FileDialog.Options(E5FileDialog.ShowDirsOnly))

        if directory:
            self.dirCombo.setEditText(Utilities.toNativeSeparators(directory))

    def __getFileList(self, path, filterRe):
        """
        Private method to get a list of files to search.
        
        @param path the root directory to search in (string)
        @param filterRe regular expression defining the filter
            criteria (regexp object)
        @return list of files to be processed (list of strings)
        """
        path = os.path.abspath(path)
        files = []
        for dirname, _, names in os.walk(path):
            files.extend([
                os.path.join(dirname, f) for f in names
                if re.match(filterRe, f)
            ])
        return files

    def setSearchDirectory(self, searchDir):
        """
        Public slot to set the name of the directory to search in.
        
        @param searchDir name of the directory to search in (string)
        """
        self.dirButton.setChecked(True)
        self.dirCombo.setEditText(Utilities.toNativeSeparators(searchDir))

    def setOpenFiles(self):
        """
        Public slot to set the mode to search in open files.
        """
        self.openFilesButton.setChecked(True)

    @pyqtSlot()
    def on_replaceButton_clicked(self):
        """
        Private slot to perform the requested replace actions.
        """
        self.findProgress.setMaximum(self.findList.topLevelItemCount())
        self.findProgress.setValue(0)

        progress = 0
        for index in range(self.findList.topLevelItemCount()):
            itm = self.findList.topLevelItem(index)
            if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]:
                file = itm.text(0)
                origHash = itm.data(0, self.md5Role)

                self.findProgressLabel.setPath(file)

                if self.projectButton.isChecked():
                    fn = os.path.join(self.project.ppath, file)
                else:
                    fn = file

                # read the file and split it into textlines
                try:
                    text, encoding, hash = \
                        Utilities.readEncodedFileWithHash(fn)
                    lines = text.splitlines(True)
                except (UnicodeError, IOError) as err:
                    E5MessageBox.critical(
                        self, self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not read the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""").format(
                                fn, str(err)))
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue

                # Check the original and the current hash. Skip the file,
                # if hashes are different.
                if origHash != hash:
                    E5MessageBox.critical(
                        self, self.tr("Replace in Files"),
                        self.tr(
                            """<p>The current and the original hash of the"""
                            """ file <b>{0}</b> are different. Skipping it."""
                            """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>""").
                        format(fn, origHash, hash))
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue

                # replace the lines authorized by the user
                for cindex in range(itm.childCount()):
                    citm = itm.child(cindex)
                    if citm.checkState(0) == Qt.Checked:
                        line = citm.data(0, self.lineRole)
                        rline = citm.data(0, self.replaceRole)
                        lines[line - 1] = rline

                # write the file
                txt = "".join(lines)
                try:
                    Utilities.writeEncodedFile(fn, txt, encoding)
                except (IOError, Utilities.CodingError, UnicodeError) as err:
                    E5MessageBox.critical(
                        self, self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not save the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""").format(
                                fn, str(err)))

            progress += 1
            self.findProgress.setValue(progress)

        self.findProgressLabel.setPath("")

        self.findList.clear()
        self.replaceButton.setEnabled(False)
        self.findButton.setEnabled(True)
        self.findButton.setDefault(True)

    def __contextMenuRequested(self, pos):
        """
        Private slot to handle the context menu request.
        
        @param pos position the context menu shall be shown (QPoint)
        """
        menu = QMenu(self)

        menu.addAction(self.tr("Open"), self.__openFile)
        menu.addAction(self.tr("Copy Path to Clipboard"),
                       self.__copyToClipboard)

        menu.exec_(QCursor.pos())

    def __openFile(self):
        """
        Private slot to open the currently selected entry.
        """
        itm = self.findList.selectedItems()[0]
        self.on_findList_itemDoubleClicked(itm, 0)

    def __copyToClipboard(self):
        """
        Private method to copy the path of an entry to the clipboard.
        """
        itm = self.findList.selectedItems()[0]
        if itm.parent():
            fn = itm.parent().text(0)
        else:
            fn = itm.text(0)

        cb = QApplication.clipboard()
        cb.setText(fn)
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)



        self.plot_title = 'f(R),f(R,Q),GR comparison for Mass and Radius'
        self.xlabel = "$R[km]$"
        self.ylabel = r'$M[M_\odot]$'
        self.xlim = (8.0, 20.0)

        tree = QTreeWidget()
        headerItem = QTreeWidgetItem()
        item = QTreeWidgetItem()

        tree_fRQ = QTreeWidget()
        headerItem_fRQ = QTreeWidgetItem()
        item_fRQ = QTreeWidgetItem()

        tree_GR = QTreeWidget()
        headerItem_GR = QTreeWidgetItem()
        item_GR = QTreeWidgetItem()

        tree_quantities = QTreeWidget()
        headerItem_quantities = QTreeWidgetItem()
        item_quantities = QTreeWidgetItem()

        self.quant_branch = QTreeWidgetItem(tree_quantities)
        self.quant_branch.setText(0, "Quantities")
        self.quant_branch.setFlags(self.quant_branch.flags() )
        # self.GR_branch.setCheckState(0, Qt.Unchecked)

        child = QTreeWidgetItem(self.quant_branch)
        child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
        child.setText(0, 'R-M')
        child.setCheckState(0, Qt.Checked)
        child.emitDataChanged()  # .connect(self.plot)

        child = QTreeWidgetItem(self.quant_branch)
        child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
        child.setText(0, 'rho-M')
        child.setCheckState(0, Qt.Unchecked)
        child.emitDataChanged()

        self.GR_branch = QTreeWidgetItem(tree_GR)
        self.GR_branch.setText(0, "GR")
        self.GR_branch.setFlags(self.GR_branch.flags() | Qt.ItemIsTristate  | Qt.ItemIsUserCheckable)
        #self.GR_branch.setCheckState(0, Qt.Unchecked)

        for x in range(len(glob.glob('Results/TOV_output_GR_*'))):
            child = QTreeWidgetItem(self.GR_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext =  GR_Modellist[x].EOS_type
            child.setText(0,checktext)
            child.setCheckState(0, Qt.Unchecked)
            child.emitDataChanged()# .connect(self.plot)

        self.fR_branch = QTreeWidgetItem(tree)
        self.fR_branch.setText(0,"fR")
        self.fR_branch.setFlags(self.fR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

        for x in range(len(glob.glob('Results/TOV_output_fR_*'))):
            child = QTreeWidgetItem(self.fR_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext = fR_Modellist[x].ID + fR_Modellist[x].EOS_type
            child.setText(0,checktext)
            child.setCheckState(0, Qt.Unchecked)
            child.emitDataChanged()# .connect(self.plot)

        #if(fRQ_branch.child(1).isSelected==1){print("hey hey")}

        self.fRQ_branch = QTreeWidgetItem(tree_fRQ)
        self.fRQ_branch.setText(0, "fRQ")
        self.fRQ_branch.setFlags(self.fRQ_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

        for x in range(len(glob.glob('Results/TOV_output_fRQ_*'))):
            child = QTreeWidgetItem(self.fRQ_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext = fRQ_Modellist[x].ID + fRQ_Modellist[x].EOS_type
            child.setText(0, checktext)
            child.setCheckState(0, Qt.Unchecked)
        print("checked?", self.fR_branch.child(0).isSelected())
        tree.itemChanged.connect(self.plot)
        tree_fRQ.itemChanged.connect(self.plot)
        tree_GR.itemChanged.connect(self.plot)
        tree_quantities.itemChanged.connect(self.quant_change)
        tree_quantities.itemChanged.connect(self.plot)



        #tree.show()

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        #self.button = QPushButton('Plot')
        #self.button.clicked.connect(self.plot)

        # set the layout
        self.layout = QVBoxLayout()

        self.sublayout1 = QVBoxLayout()
        self.sublayout2 = QHBoxLayout()
        plotBox = QHBoxLayout()
        plotBox.addLayout(self.sublayout1, 1)
        plotBox.addLayout(self.sublayout2, 4)
        bottomlayout = QHBoxLayout()
        #self.layout.addLayout()


        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas,1)
        #self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        #layout = QHBoxLayout()
        self.btn_rhoM = QCheckBox("rho-M")
        self.btn_RM = QCheckBox("R-M")
        self.btn_GR = QCheckBox("GR")
        self.btn_fR =  QCheckBox("fR")
        self.btn_fRQ = QCheckBox("fRQ")

        self.btn_fRs = []

        self.btn_rhoM.setChecked(False)
        self.btn_RM.setChecked(True)
        self.btn_GR.setChecked(False)
        self.btn_fR.setChecked(False)
        self.btn_fRQ.setChecked(False)

        #self.b1.stateChanged.connect(lambda: self.btnstate(self.b1))
        #self.btn_rhoM.stateChanged.connect(self.quant_change)
        #self.btn_RM.stateChanged.connect(self.quant_change)

        self.btn_rhoM.stateChanged.connect(self.plot)
        self.btn_RM.stateChanged.connect(self.plot)
        self.btn_GR.stateChanged.connect(self.plot)
        self.btn_fR.stateChanged.connect(self.plot)
        self.btn_fRQ.stateChanged.connect(self.plot)

        #self.layout.addWidget(self.btn_GR)
        #self.layout.addWidget(self.btn_fR)
        #self.layout.addWidget(self.btn_fRQ)
        self.sublayout2.addWidget(tree_quantities)
        self.sublayout2.addWidget(tree_GR)
        self.sublayout2.addWidget(tree)
        self.sublayout2.addWidget(tree_fRQ)
        self.layout.addLayout(plotBox)
Пример #30
0
class FindFileDialog(QDialog, Ui_FindFileDialog):
    """
    Class implementing a dialog to search for text in files.
    
    The occurrences found are displayed in a QTreeWidget showing the filename,
    the linenumber and the found text. The file will be opened upon a double
    click onto the respective entry of the list.
    
    @signal sourceFile(str, int, str, int, int) emitted to open a source file
        at a line
    @signal designerFile(str) emitted to open a Qt-Designer file
    """
    sourceFile = pyqtSignal(str, int, str, int, int)
    designerFile = pyqtSignal(str)

    lineRole = Qt.UserRole + 1
    startRole = Qt.UserRole + 2
    endRole = Qt.UserRole + 3
    replaceRole = Qt.UserRole + 4
    md5Role = Qt.UserRole + 5

    def __init__(self, parent=None, replaceMode=True, projectPath=None):
        """
        Constructor
        
        @param project reference to the project object
        @param replaceMode flag indicating the replace dialog mode (boolean)
        @param parent parent widget of this dialog (QWidget)
        """
        super(FindFileDialog, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(Qt.Window)

        
        self.dirPicker.setMode(E5PathPickerModes.DirectoryMode)
        self.dirPicker.setInsertPolicy(QComboBox.InsertAtTop)
        self.dirPicker.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLength)

        self.__replaceMode = replaceMode

        self.importButton = \
            self.buttonBox.addButton(self.tr("&Import"),
                                     QDialogButtonBox.ActionRole)

        self.exportButton = \
            self.buttonBox.addButton(self.tr("&Export"),
                                     QDialogButtonBox.ActionRole)

        self.stopButton = \
            self.buttonBox.addButton(self.tr("Stop"),
                                     QDialogButtonBox.ActionRole)
        self.stopButton.setEnabled(False)

        self.transButton = \
            self.buttonBox.addButton(self.tr("TransForm"),
                                     QDialogButtonBox.ActionRole)
        self.findButton = \
            self.buttonBox.addButton(self.tr("Find"),
                                     QDialogButtonBox.ActionRole)
        self.findButton.setEnabled(False)
        self.findButton.setDefault(True)
        
        if projectPath is not None:
            self.projectPath = projectPath.replace("\\","/")
            self.dirPicker.setPath(self.projectPath)        

        if self.__replaceMode:
            self.replaceButton.setEnabled(False)
            self.setWindowTitle(self.tr("Replace in Files"))
        else:
            self.replaceLabel.hide()
            self.replacetextCombo.hide()
            self.replaceButton.hide()

        self.findProgressLabel.setMaximumWidth(550)

        self.findList.headerItem().setText(self.findList.columnCount(), "")
        self.findList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.__section0Size = self.findList.header().sectionSize(0)
        self.findList.setExpandsOnDoubleClick(False)

        if self.__replaceMode:
            font = QFont()
            # font = Preferences.getEditorOtherFonts("MonospacedFont")
            self.findList.setFont(font)

        self.__cancelSearch = False
        self.__lastFileItem = None
        self.__populating = False

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenuRequested)

    def __createItem(self, file, line, text, start, end, replTxt="", md5=""):
        """
        Private method to create an entry in the file list.
        创建 Item
        @param file filename of file (string)
        @param line line number (integer)
        @param text text found (string)
        @param start start position of match (integer)
        @param end end position of match (integer)
        @param replTxt text with replacements applied (string)
        @keyparam md5 MD5 hash of the file (string)
        """
        if self.__lastFileItem is None:
            # It's a new file
            self.__lastFileItem = QTreeWidgetItem(self.findList, [file])
            self.__lastFileItem.setFirstColumnSpanned(True)
            self.__lastFileItem.setExpanded(True)
            if self.__replaceMode:
                self.__lastFileItem.setFlags(
                    self.__lastFileItem.flags() |
                    Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsTristate))
                # Qt bug:
                # item is not user checkable if setFirstColumnSpanned
                # is True (< 4.5.0)
            self.__lastFileItem.setData(0, self.md5Role, md5)

        itm = QTreeWidgetItem(self.__lastFileItem)
        itm.setTextAlignment(0, Qt.AlignRight)
        itm.setData(0, Qt.DisplayRole, line)
        itm.setData(1, Qt.DisplayRole, text)
        itm.setData(0, self.lineRole, line)
        itm.setData(0, self.startRole, start)
        itm.setData(0, self.endRole, end)
        itm.setData(0, self.replaceRole, replTxt)
        if self.__replaceMode:
            itm.setFlags(itm.flags() | Qt.ItemFlags(Qt.ItemIsUserCheckable))
            itm.setCheckState(0, Qt.Checked)
            self.replaceButton.setEnabled(True)

    def show(self, txt=""):
        """
        Public method to enable/disable the project button.
        
        @param txt text to be shown in the searchtext combo (string)
        """

        if self.__replaceMode:
            self.findList.clear()

        super(FindFileDialog, self).show()

    def resizeEvent(self, e):
        self.mdiArea.tileSubWindows()
        return super().resizeEvent(e)

    def on_dirPicker_editTextChanged(self, text):
        """
        Private slot to handle the textChanged signal of the directory
        picker.
        
        @param text (ignored)
        """
        self.enableFindButton(False, False)

    def enableFindButton(self, sub=None, close=None):
        """
        Private slot called to enable the find button.
        """

        def closeBtn():
            self.findButton.setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)

        def openBtn():
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)

        if self.dirPicker.currentText() == "":
            closeBtn()
        elif os.path.exists(os.path.abspath(self.dirPicker.currentText())) is False:
            closeBtn()
        elif sub is not None:
            if close is None:
                if sub.findtextCombo.currentText() == "" or (sub.filterEdit.text() == "") \
                        or (self.__replaceMode is False and sub.replacetextCombo.currentText() == ""):
                    closeBtn()
                else:
                    openBtn()
            elif close is True:
                subList = self.mdiArea.subWindowList()
                for sub_ in subList:
                    sub__ = sub_.widget()

                    if sub__ != sub:
                        if sub__.findtextCombo.currentText() == "" or (sub__.filterEdit.text() == ""):
                            closeBtn()
                            break
                        else:
                            openBtn()
                    else:
                        if len(subList) == 1:
                            closeBtn()
            elif close is False:

                for sub_ in self.mdiArea.subWindowList():
                    sub__ = sub_.widget()

                    if sub__.findtextCombo.currentText() == "" or (sub__.filterEdit.text() == ""):
                        closeBtn()
                        break
                    else:
                        openBtn()
        else:
            openBtn()

    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.findButton:
            self.findList.clear()
            self.__doSearch()
        elif button == self.stopButton:
            self.__stopSearch()
        elif button == self.importButton:
            self.clear_btn.click()
            fileName, ok = QFileDialog.getOpenFileName(self, "Open", "history.json", "Json (*.json)")
            if fileName == '':
                return
            else:
                self.loadFromFile(fileName)
        elif button == self.exportButton:
            fileName, ok = QFileDialog.getSaveFileName(self, "Save", "history.json", "Json (*.json)")
            if fileName == '':
                return
            else:
                self.saveToFile(fileName)
        elif button == self.transButton:
            for sub in self.mdiArea.subWindowList():
                sub = sub.widget()
                a, b = sub.findtextCombo.currentText(), sub.replacetextCombo.currentText()
                sub.findtextCombo.setCurrentText(b), sub.replacetextCombo.setCurrentText(a)

    def __stripEol(self, txt):
        """
        Private method to strip the eol part.
        
        @param txt line of text that should be treated (string)
        @return text with eol stripped (string)
        """
        return txt.replace("\r", "").replace("\n", "")

    def __stopSearch(self):
        """
        Private slot to handle the stop button being pressed.
        """

        self.__cancelSearch = True

    def __doSearch(self):
        """
        Private slot to handle the find button being pressed.
        搜索逻辑
        """
        # if self.__replaceMode and \
        #    not e5App().getObject("ViewManager").checkAllDirty():
        #     return

        self.__cancelSearch = False

        occurrences = 0
        progress = 0
        for sub in self.mdiArea.subWindowList():
            sub = sub.widget()
            fileFilter = sub.filterEdit.text()
            fileFilterList = \
                ["^{0}$".format(filter.replace(".", "\.").replace("*", ".*"))
                 for filter in fileFilter.split(";")]
            # *.qml -> .*\.qml
            filterRe = re.compile("|".join(fileFilterList))

            # 开始查找
            files = self.__getFileList(
                os.path.abspath(self.dirPicker.currentText()),
                filterRe)

            QApplication.processEvents()
            QApplication.processEvents()

            # retrieve the values
            reg = sub.regexpCheckBox.isChecked()
            wo = sub.wordCheckBox.isChecked()
            cs = sub.caseCheckBox.isChecked()
            ct = sub.findtextCombo.currentText()
            if reg:
                txt = ct
            else:
                txt = re.escape(ct)
            if wo:
                txt = "\\b{0}\\b".format(txt)
            if sys.version_info[0] == 2:
                flags = re.UNICODE | re.LOCALE
            else:
                flags = re.UNICODE
            if not cs:
                flags |= re.IGNORECASE
            try:
                search = re.compile(txt, flags)
            except re.error as why:
                E5MessageBox.critical(
                    self,
                    self.tr("Invalid search expression"),
                    self.tr("""<p>The search expression is not valid.</p>"""
                            """<p>Error: {0}</p>""").format(str(why)))
                self.stopButton.setEnabled(False)
                self.findButton.setEnabled(True)
                self.findButton.setDefault(True)
                return

            if self.__replaceMode:
                replTxt = sub.replacetextCombo.currentText()

            # ======================================================
            # set the button states
            self.stopButton.setEnabled(True)
            self.stopButton.setDefault(True)
            self.findButton.setEnabled(False)

            # now go through all the files
            self.__populating = True
            self.findList.setUpdatesEnabled(False)

            breakSearch = False

            fileOccurrences = 0

            for file in files:
                self.__lastFileItem = None
                found = False
                if self.__cancelSearch or breakSearch:
                    break

                self.findProgressLabel.setPath(file)

                fn = file

                # read the file and split it into textlines
                try:
                    text, encoding, hashStr = Utilities.readEncodedFileWithHash(fn)
                    lines = text.splitlines(True)
                except (UnicodeError, IOError):
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue

                # now perform the search and display the lines found
                count = 0
                for line in lines:
                    if self.__cancelSearch:
                        break

                    count += 1
                    contains = search.search(line)
                    if contains:
                        occurrences += 1
                        found = True
                        start = contains.start()
                        end = contains.end()
                        if self.__replaceMode:
                            rline = search.sub(replTxt, line)
                        else:
                            rline = ""
                        line = self.__stripEol(line)
                        if len(line) > 1024:
                            line = "{0} ...".format(line[:1024])
                        if self.__replaceMode:
                            if len(rline) > 1024:
                                rline = "{0} ...".format(line[:1024])
                            line = "- {0}\n+ {1}".format(
                                line, self.__stripEol(rline))
                        self.__createItem(file, count, line, start, end,
                                          rline, hashStr)

                    QApplication.processEvents()


                self.findList.setUpdatesEnabled(True)
                self.findList.sortItems(self.findList.sortColumn(),
                                        self.findList.header().sortIndicatorOrder())
                self.findList.resizeColumnToContents(1)
                count_ = self.findList.topLevelItemCount()

                if found:
                    fileOccurrences += 1
                    progress += 1
                    self.findProgress.setValue(progress)
            #
            if not files:
                self.findProgress.setMaximum(1)
                self.findProgress.setValue(1)
            #
            resultFormat = self.tr("{0} / {1}", "occurrences / files")
            self.findProgressLabel.setPath(resultFormat.format(
                self.tr("%n occurrence(s)", "", occurrences),
                self.tr("%n file(s)", "", count_)))

            if self.__replaceMode:
                self.findList.header().resizeSection(0, self.__section0Size + 30)
            self.findList.header().setStretchLastSection(True)
            self.__populating = False

            self.stopButton.setEnabled(False)
            self.findButton.setEnabled(True)
            self.findButton.setDefault(True)

            if breakSearch:
                self.close()
        count_ = self.findList.topLevelItemCount()
        # self.findProgressLabel.setPath("")
        # self.findProgress.setValue(count_)
        self.findProgress.setMaximum(count_)

    def __getFileList(self, path, filterRe):
        """
        Private method to get a list of files to search.
        
        @param path the root directory to search in (string)
        @param filterRe regular expression defining the filter
            criteria (regexp object)
        @return list of files to be processed (list of strings)
        """
        path = os.path.abspath(path)
        files = []
        for dirname, _, names in os.walk(path):
            files.extend([os.path.join(dirname, f)
                          for f in names
                          if re.match(filterRe, f)]
                         )
        return files

    def setOpenFiles(self):
        """
        Public slot to set the mode to search in open files.
        """
        self.openFilesButton.setChecked(True)

    @pyqtSlot()
    def on_replaceButton_clicked(self):
        """
        Private slot to perform the requested replace actions.
        替换开始
        """
        self.findProgress.setMaximum(self.findList.topLevelItemCount())
        self.findProgress.setValue(0)

        progress = 0
        for index in range(self.findList.topLevelItemCount()):
            itm = self.findList.topLevelItem(index)
            if itm.checkState(0) in [Qt.PartiallyChecked, Qt.Checked]:
                file = itm.text(0)
                origHash = itm.data(0, self.md5Role)

                self.findProgressLabel.setPath(file)

                fn = file

                # read the file and split it into textlines
                try:
                    text, encoding, hashStr = \
                        Utilities.readEncodedFileWithHash(fn)
                    lines = text.splitlines(True)
                except (UnicodeError, IOError) as err:
                    E5MessageBox.critical(
                        self,
                        self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not read the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""")
                            .format(fn, str(err))
                    )
                    progress += 1
                    self.findProgress.setValue(progress)
                    continue

                # Check the original and the current hash. Skip the file,
                # if hashes are different.

                # if origHash != hashStr:
                #     E5MessageBox.critical(
                #         self,
                #         self.tr("Replace in Files"),
                #         self.tr(
                #             """<p>The current and the original hash of the"""
                #             """ file <b>{0}</b> are different. Skipping it."""
                #             """</p><p>Hash 1: {1}</p><p>Hash 2: {2}</p>""")
                #             .format(fn, origHash, hashStr)
                #     )
                #     progress += 1
                #     self.findProgress.setValue(progress)
                #     continue

                # replace the lines authorized by the user
                for cindex in range(itm.childCount()):
                    citm = itm.child(cindex)
                    if citm.checkState(0) == Qt.Checked:
                        line = citm.data(0, self.lineRole)
                        rline = citm.data(0, self.replaceRole)
                        lines[line - 1] = rline

                # write the file
                # 写入
                txt = "".join(lines)
                try:
                    Utilities.writeEncodedFile(fn, txt, encoding)
                except (IOError, Utilities.CodingError, UnicodeError) as err:
                    E5MessageBox.critical(
                        self,
                        self.tr("Replace in Files"),
                        self.tr(
                            """<p>Could not save the file <b>{0}</b>."""
                            """ Skipping it.</p><p>Reason: {1}</p>""")
                            .format(fn, str(err))
                    )

            progress += 1
            self.findProgress.setValue(progress)

        self.findProgressLabel.setPath("")

        # 替换完成
        self.findList.clear()
        self.replaceButton.setEnabled(False)
        self.findButton.setEnabled(True)
        self.findButton.setDefault(True)

    def __contextMenuRequested(self, pos):
        """
        Private slot to handle the context menu request.
        
        @param pos position the context menu shall be shown (QPoint)
        """
        menu = QMenu(self)

        menu.addAction(self.tr("Copy Path to Clipboard"),
                       self.__copyToClipboard)

        menu.exec_(QCursor.pos())

    def __copyToClipboard(self):
        """
        Private method to copy the path of an entry to the clipboard.
        """
        itm = self.findList.selectedItems()[0]
        if itm.parent():
            fn = itm.parent().text(0)
        else:
            fn = itm.text(0)

        cb = QApplication.clipboard()
        cb.setText(fn)

    # =================================
    @pyqtSlot()
    def on_add_btn_clicked(self):
        """
        add form.
        """

        sub = subForm(self)
        self.mdiArea.addSubWindow(sub)
        sub.show()
        self.mdiArea.tileSubWindows()

    @pyqtSlot()
    def on_clear_btn_clicked(self):
        """
        Slot documentation goes here.
        """
        for i in self.mdiArea.subWindowList():
            self.mdiArea.removeSubWindow(i)

    # =================================
    def saveToFile(self, filename):
        try:
            with open(filename, "w") as file:
                file.write(json.dumps(self.serialize(), indent=4))
                print("saving to", filename, "was successfull.")

                self.has_been_modified = False
        except:

            QMessageBox.warning(self, "error", "save json fail", QMessageBox.Ok)

    def loadFromFile(self, filename):
        try:
            with open(filename, "r") as file:
                raw_data = file.read()
                data = json.loads(raw_data, encoding='utf-8')
                self.deserialize(data)
        except:
            QMessageBox.warning(self, "error", "open json fail", QMessageBox.Ok)

    def serialize(self):
        """ÐòÁл¯"""
        subs = []
        for sub in self.mdiArea.subWindowList():
            subs.append(sub.widget().serialize())

        return OrderedDict([
            ('subs', subs),
            ('path', self.dirPicker.path()),
        ])

    def deserialize(self, data, hashmap={}, restore_id=True):
        """·´ÐòÁл¯"""

        self.clear_btn.click()

        for sub_info in data['subs']:
            sub = subForm(self).deserialize(sub_info)
            self.mdiArea.addSubWindow(sub)
            sub.show()
        self.mdiArea.tileSubWindows()

        self.dirPicker.setPath(data['path'])

        self.enableFindButton(False, False)
        return True
Пример #31
0
 def addItem(branch, name, num, num2):
     item = QTreeWidgetItem(branch)
     item.setFlags(item.flags() | Qt.ItemIsEditable)
     item.setText(0, name)
     item.setText(1, str(num))
     item.setText(2, str(num2))
class Waterfall(QWidget, waterfall.Ui_Waterfall):
    
    general_settings_signal = QtCore.pyqtSignal(list) #send list of plotting params
    updated_rectangles_signal = QtCore.pyqtSignal(list) #send list of updated artists for redrawing

    def __init__(self, parent):
        super(Waterfall,self).__init__(parent)
        self.setupUi(self)
        
        self.test = {'a':1,'b':2,'c':3}
        #Button functions
        self.btn_apply_general_settings.clicked.connect(self.send_settings)
        self.patient_tree = self.create_patient_tree()
        self.data_viewer_container.addWidget(self.patient_tree)

    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        

    def on_generated_rectangles_signal(self,signal):
        self.rectangles_received = signal[0]
        self.add_items() #display in table
        #print(self.rectangles_received)


    def send_settings(self,signal):
        self.list_general_settings = [
                                        self.plot_title.text(),
                                        self.x_label.text(),
                                        self.y_label.text(),
                                        self.twenty_percent_line.isChecked(),
                                        self.thirty_percent_line.isChecked(),
                                        self.zero_percent_line.isChecked(),
                                        self.display_responses_as_text.isChecked()
                                    ]
        self.general_settings_signal.emit(self.list_general_settings)

    def create_patient_tree(self):
            '''
            Create QTreeWidget populated with a patient's data for the DataEntry dialog.
            Assumes that self.temp_patient is the patient of interest and that the variable belongs to the dialog.
            '''
            self.tree = QTreeWidget()
            self.root = self.tree.invisibleRootItem()
            self.headers = [
                            'Patient #',
                            'Best response %',
                            'Overall response',
                            'Cancer',
                            'Color coding key',
                            ]
            self.headers_item = QTreeWidgetItem(self.headers)
            self.tree.setColumnCount(len(self.headers))
            self.tree.setHeaderItem(self.headers_item)
            self.root.setExpanded(True)
            self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
            self.tree.header().setStretchLastSection(False)
            return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        self.tree.clear() #clear prior to entering items, prevent aggregation
        i=0
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            self.rect_item = QTreeWidgetItem(self.root)
            self.rect_params = [
                                self.waterfall_data['Patient number'][i], 
                                rect.get_height(),
                                self.waterfall_data['Overall response'][i],
                                self.waterfall_data['Cancer'][i]
                                ]
            for col in range(0,4):
                self.rect_item.setText(col,str(self.rect_params[col]))
                self.rect_item.setTextAlignment(col,4)
            self.tree.setItemWidget(self.rect_item, 4, CustomCombo(self,self.test))
            self.rect_item.setFlags(self.rect_item.flags() | QtCore.Qt.ItemIsEditable)
            i+=1
        
    def on_updated_tree_item(self):
        #update the rectangle which was edited
        pass
 def _add_code_pep8(self):
     item = QTreeWidgetItem()
     item.setFlags(item.flags() | Qt.ItemIsEditable)
     self._listIgnoreViolations.addTopLevelItem(item)
     self._listIgnoreViolations.setCurrentItem(item)
     self._listIgnoreViolations.editItem(item, 0)
Пример #34
0
 def new_cluster(self):
     item_0 = QTreeWidgetItem(self.treeWidget)
     item_0.setText(0,"Yeni Kolon")
     item_0.setFlags(item_0.flags() | Qt.ItemIsEditable)
Пример #35
0
    def __generateItem(self, changelist, status, propStatus, locked, history,
                       switched, lockinfo, uptodate, revision, change, author,
                       path):
        """
        Private method to generate a status item in the status list.
        
        @param changelist name of the changelist (string)
        @param status text status (pysvn.wc_status_kind)
        @param propStatus property status (pysvn.wc_status_kind)
        @param locked locked flag (boolean)
        @param history history flag (boolean)
        @param switched switched flag (boolean)
        @param lockinfo lock indicator (string)
        @param uptodate up to date flag (boolean)
        @param revision revision (integer)
        @param change revision of last change (integer)
        @param author author of the last change (string)
        @param path path of the file or directory (string)
        """
        statusText = self.tr(svnStatusMap[status])
        itm = QTreeWidgetItem(self.statusList)
        itm.setData(0, Qt.DisplayRole, "")
        itm.setData(1, Qt.DisplayRole, changelist)
        itm.setData(2, Qt.DisplayRole, statusText)
        itm.setData(3, Qt.DisplayRole, self.tr(svnStatusMap[propStatus]))
        itm.setData(4, Qt.DisplayRole, self.yesno[locked])
        itm.setData(5, Qt.DisplayRole, self.yesno[history])
        itm.setData(6, Qt.DisplayRole, self.yesno[switched])
        itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo])
        itm.setData(8, Qt.DisplayRole, self.yesno[uptodate])
        itm.setData(9, Qt.DisplayRole, revision)
        itm.setData(10, Qt.DisplayRole, change)
        itm.setData(11, Qt.DisplayRole, author)
        itm.setData(12, Qt.DisplayRole, path)

        itm.setTextAlignment(1, Qt.AlignLeft)
        itm.setTextAlignment(2, Qt.AlignHCenter)
        itm.setTextAlignment(3, Qt.AlignHCenter)
        itm.setTextAlignment(4, Qt.AlignHCenter)
        itm.setTextAlignment(5, Qt.AlignHCenter)
        itm.setTextAlignment(6, Qt.AlignHCenter)
        itm.setTextAlignment(7, Qt.AlignHCenter)
        itm.setTextAlignment(8, Qt.AlignHCenter)
        itm.setTextAlignment(9, Qt.AlignRight)
        itm.setTextAlignment(10, Qt.AlignRight)
        itm.setTextAlignment(11, Qt.AlignLeft)
        itm.setTextAlignment(12, Qt.AlignLeft)

        if status in [pysvn.wc_status_kind.added,
                      pysvn.wc_status_kind.deleted,
                      pysvn.wc_status_kind.modified] or \
           propStatus in [pysvn.wc_status_kind.added,
                          pysvn.wc_status_kind.deleted,
                          pysvn.wc_status_kind.modified]:
            itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
            itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
        else:
            itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable)

        if statusText not in self.__statusFilters:
            self.__statusFilters.append(statusText)
Пример #36
0
class myGUI(QMainWindow):
    signal_loginSuccess = QtCore.pyqtSignal()
    signal_startShowTree = QtCore.pyqtSignal()
    signal_setStartBackupBtn = QtCore.pyqtSignal(str, bool)
    signal_showUserOptionWindow = QtCore.pyqtSignal()
    signal_showDevOptionWindow = QtCore.pyqtSignal()
    signal_close = QtCore.pyqtSignal()
    signal_appendDownloadList = QtCore.pyqtSignal(dict)
    signal_processbar_value = QtCore.pyqtSignal(int)
    signal_startUpdate = QtCore.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.config = ConfigParser()
        self.pool = threadpool.ThreadPool(4)
        self.DownloadPool = threadpool.ThreadPool(1)
        self.readSetting()
        string.setLanguage(self.config['User']['language'])
        self.version = 1.21
        self.host = 'https://ilearn2.fcu.edu.tw'
        self.statusbar = self.statusBar()
        self.initUI()
        self.web = iLearnManager(self.host)
        self.init_iLearn()
        self.FileTree = {}
        self.success = 0
        self.failed = 0
        self.fileList = []
        self.retryList = []
        self.failedList = []
        self.retryTimes = 0
        self.nowLoad = 0
        self.retryAfter = 0
        self.initCheckUpdate = False
        self.retryTimer = QtCore.QTimer()
        self.retryTimer.timeout.connect(self.startRetry)
        self.signal_loginSuccess.connect(self.ShowResource)
        self.signal_appendDownloadList.connect(self.appendItemToDownloadList)
        self.signal_processbar_value.connect(self.setProcessBarValue)
        self.signal_startShowTree.connect(self.startShowTree)
        self.signal_setStartBackupBtn.connect(self.setStartBackupBtn)
        self.timer_checkUpdate = QtCore.QTimer()
        self.timer_checkUpdate.timeout.connect(self.checkUpdate)
        self.timer_checkUpdate.start(1000)
        if self.config['dev'].getboolean('autologin') == True:
            self.btn_login.click()

    def closeEvent(self, event):
        self.signal_close.emit()
        self.close()

    def setStatusBarText(self, str):
        self.statusbar.showMessage(str)

    def init_iLearn(self):
        self.web.signal_finishDownload.connect(self.startDownload)
        self.web.signal_setStatusProcessBar.connect(self.setStatusProcessBar)
        self.web.signal_Log.connect(self.print)
        self.web.signal_setStatusBarText.connect(self.setStatusBarText)
        t = Thread(target=self.TestiLearnConnection)
        t.run()

    def setStartBackupBtn(self, text, enabled):
        self.btn_StartBackup.setEnabled(enabled)
        self.btn_StartBackup.setText(text)

    def setStatusProcessBar(self, idx, value):
        if value == -1:
            ProcessBar = QProgressBar()
            self.StatusTable.setCellWidget(idx, 3, ProcessBar)
        elif value == -2:
            if self.retryTimes == 0:
                self.failed += 1
            self.failedList.append(idx)
            self.StatusTable.removeCellWidget(idx, 3)  # 移除進度條之控件
            ErrorIcon = QIcon(":img/DownloadFailed.png")  # 開啟下載失敗之圖案
            item = QTableWidgetItem(ErrorIcon,
                                    string._('Download Falied'))  # 新增顯示失敗的元件
            self.StatusTable.setItem(idx, 3, item)  # 將新元件設定到表格內
            if idx == len(self.fileList) - 1:
                self.signal_processbar_value.emit(idx + 1)
            self.finishDownloadCheck(idx)
        elif value == 101:
            if self.retryTimes != 0:
                self.failed -= 1
            self.success += 1
            self.print(string._('Download file %d finish!') % (idx + 1))
            self.StatusTable.removeCellWidget(idx, 3)
            OkIcon = QIcon(":img/FinishDownload.png")  # 開啟下載完成之圖案
            item = QTableWidgetItem(OkIcon, "OK")  # 新增顯示OK的元件
            self.StatusTable.setItem(idx, 3, item)  # 將新元件設定到表格內
            self.finishDownloadCheck(idx)
        else:
            ProcessBar = self.StatusTable.cellWidget(idx, 3)
            if ProcessBar == None:
                ProcessBar = QProgressBar()
                self.StatusTable.setCellWidget(idx, 3, ProcessBar)
            ProcessBar.setValue(value)

    def finishDownloadCheck(self, idx):
        def checkIsEndElement(idx):
            if self.retryTimes == 0:
                return idx == len(self.fileList) - 1
            else:
                return idx == self.retryList[-1]

        def backupFinish():
            self.signal_processbar_value.emit(self.statusProcessBar.maximum())
            self.signal_setStartBackupBtn.emit(string._('Start Backup'), True)
            QMessageBox.information(
                self, string._("Download finish!"),
                string._("Success:%d\nFailed:%d") %
                (self.success, self.failed))

        if checkIsEndElement(idx):
            if self.retryTimes == self.config['User'].getint('retrytimes'):
                backupFinish()
            else:
                self.signal_processbar_value.emit(
                    self.statusProcessBar.maximum())
                if self.failed == 0:
                    backupFinish()
                else:
                    self.retryAfter = self.config['User'].getint(
                        'secondbetweenretry')
                    self.retryTimer.start(1000)

    def checkUpdate(self):
        try:
            self.timer_checkUpdate.stop()
        except:
            pass
        with open('version.ini', mode='w') as f:
            f.write(str(self.version))
        s = requests.Session()
        versionFile = s.get(
            'https://raw.githubusercontent.com/fcu-d0441320/iLearnBackupTool/master/version.ini'
        )
        version = float(versionFile.text)
        if version > self.version:
            reply = QMessageBox.question(
                self, string._('Find New version'),
                string.
                _('Find New Version:%.1f\nNow Vsrsion:%.1f\nDo you want to update?'
                  ) % (version, self.version),
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.setVisible(False)
                self.signal_startUpdate.emit(self.config['User']['language'])
        else:
            if self.initCheckUpdate == False:
                self.initCheckUpdate = True
            else:
                QMessageBox.information(self,
                                        string._('This is the latest version'),
                                        string._('This is the latest version'))
                # QMessageBox().information(self,"有更新版本!","發現有新版本,請前往官網更新,或檢查是否與Updater_GUI.exe放置於相同資料夾!")

    def moveToCenter(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def initUI(self):
        self.resize(800, 600)
        self.setWindowIcon(QIcon(':img/Main_Icon.png'))
        self.moveToCenter()
        self.setWindowTitle(string._('iLearn Backup Tool'))
        self.statusbar.showMessage(string._('Starting Backup Tool...'))
        self.createMenu()
        self.statusProcessBar = QProgressBar()
        self.statusProcessBar.setValue(0)
        self.statusProcessBar.setFormat(string._("Ready..."))
        self.statusbar.addPermanentWidget(self.statusProcessBar)

        self.grid = QGridLayout()
        widget = QWidget()
        self.setCentralWidget(widget)
        widget.setLayout(self.grid)
        self.grid.addWidget(self.createLoginGroup(), 0, 0)
        self.grid.addWidget(self.createSaveGroup(), 1, 0)
        self.grid.addWidget(self.createCourseGroup(), 0, 1, 2, 1)
        self.grid.addWidget(self.createStatusView(), 2, 0, 1, 2)

        self.grid.setColumnStretch(0, 10)
        self.grid.setColumnStretch(1, 20)
        self.grid.setRowStretch(0, 6)
        self.grid.setRowStretch(1, 6)
        self.grid.setRowStretch(2, 10)
        self.web = iLearnManager()

        self.show()

    def createStatusTable(self):
        self.StatusTable = QTableWidget()
        self.StatusTable.setColumnCount(4)
        horizontal_header = [
            string._('File name'),
            string._('Path'),
            string._('iLearn mod'),
            string._('Download status')
        ]
        self.StatusTable.setHorizontalHeaderLabels(horizontal_header)
        self.StatusTable.setEditTriggers(QTableWidget.NoEditTriggers)
        self.StatusTable.setColumnWidth(0, 140)
        self.StatusTable.setColumnWidth(1, 120)
        self.StatusTable.setColumnWidth(2, 120)
        self.StatusTable.setColumnWidth(3, 380)
        return self.StatusTable

    def createLogSpace(self):
        self.LogSpace = QPlainTextEdit()
        self.LogSpace.setReadOnly(True)
        return self.LogSpace

    def print(self, msg):
        self.LogSpace.appendPlainText(
            time.strftime("[%H:%M:%S] ", time.localtime()) + msg)

    def createStatusView(self):
        tabs = QTabWidget()
        tabs.addTab(self.createStatusTable(), string._('Backup status'))
        tabs.addTab(self.createLogSpace(), string._('Log'))
        return tabs

    def createLoginGroup(self):
        groupBox = QGroupBox(string._('Step 1: Login'))
        form = QGridLayout()
        label_NID = QLabel(string._('NID:'))
        self.input_NID = QLineEdit()
        self.input_NID.setText(self.config['dev']['nid'])
        label_Pass = QLabel(string._('Password:'******'dev']['pass'])
        self.input_Pass.setEchoMode(QLineEdit.Password)
        form.addWidget(label_NID, 0, 0)
        form.addWidget(self.input_NID, 0, 1, 1, 2)
        form.addWidget(label_Pass, 1, 0)
        form.addWidget(self.input_Pass, 1, 1, 1, 2)

        self.btn_clean = QPushButton(string._('Clean'), self)
        self.btn_clean.clicked[bool].connect(self.cleanLogin)
        form.addWidget(self.btn_clean, 2, 1)

        self.btn_login = QPushButton(string._('Login'), self)
        self.btn_login.clicked[bool].connect(self.Login)
        form.addWidget(self.btn_login, 2, 2)

        label_iLearnStatus = QLabel(string._('iLearn status:'))
        form.addWidget(label_iLearnStatus, 3, 0)

        self.label_iLearn = QLabel()
        form.addWidget(self.label_iLearn, 3, 1, 1, 2)

        vbox = QVBoxLayout()
        vbox.addLayout(form)
        vbox.addStretch(1)
        groupBox.setLayout(vbox)

        return groupBox

    def cleanLogin(self):
        self.input_NID.setText("")
        self.input_Pass.setText("")

    def createSaveGroup(self):
        groupBox = QGroupBox(string._('Step 3:Select save option'))

        radio1 = QRadioButton(string._('Save as file'))
        radio1.setChecked(True)
        radio2 = QRadioButton(string._('Save as web page'))
        radio2.setEnabled(False)

        self.btn_StartBackup = QPushButton(string._('Start Backup'), self)
        self.btn_StartBackup.setEnabled(False)
        self.btn_StartBackup.clicked[bool].connect(self.StartBackup)
        self.btn_OpenFolder = QPushButton(string._('Open Folder'), self)
        self.btn_OpenFolder.clicked[bool].connect(self.OpenFolder)

        vbox = QVBoxLayout()
        vbox.addWidget(radio1)
        vbox.addWidget(radio2)
        vbox.addWidget(self.btn_StartBackup)
        vbox.addWidget(self.btn_OpenFolder)
        vbox.addStretch(1)
        groupBox.setLayout(vbox)

        if not exists('iLearn'):
            makedirs('iLearn')

        return groupBox

    def OpenFolder(self):
        subprocess.Popen(['explorer', "iLearn"])

    def createCourseGroup(self):
        groupBox = QGroupBox(
            string._('Step 2:Select sourse resource to backup'))

        self.CourseListBox = QVBoxLayout()
        self.CourseListBox.addStretch(1)

        self.CourseTreeList = QTreeWidget()
        self.CourseTreeList.setHeaderHidden(True)
        self.CourseTreeList.setEnabled(False)
        self.CourseTreeList.itemExpanded.connect(self.ExpandCourse)
        self.CourseTreeListRoot = QTreeWidgetItem(self.CourseTreeList)
        self.CourseTreeListRoot.setText(0, string._("All course"))
        self.CourseTreeListRoot.setFlags(self.CourseTreeListRoot.flags()
                                         | QtCore.Qt.ItemIsTristate
                                         | QtCore.Qt.ItemIsUserCheckable)
        self.CourseTreeListRoot.setCheckState(0, QtCore.Qt.Unchecked)

        HLayout = QHBoxLayout()
        HLayout.addWidget(self.CourseTreeList)

        groupBox.setLayout(HLayout)

        return groupBox

    def createMenu(self):
        menubar = self.menuBar()

        fileMenu = menubar.addMenu(string._('File'))
        closeAct = QAction(QIcon(':img/Close_Icon.png'), string._('Quit'),
                           self)
        closeAct.triggered.connect(qApp.quit)
        fileMenu.addAction(closeAct)

        optMenu = menubar.addMenu(string._('Option'))
        DevOptAct = QAction(QIcon(':img/Settings_Icon.png'),
                            string._('Developer options'), self)
        DevOptAct.triggered.connect(self.showDevOption)
        UserOptionAction = QAction(QIcon(':img/Settings_Icon.png'),
                                   string._('Preferences'), self)
        UserOptionAction.triggered.connect(self.showUserOption)
        optMenu.addAction(UserOptionAction)
        optMenu.addAction(DevOptAct)

        helpMenu = menubar.addMenu(string._('Help'))
        helpAct = QAction(QIcon(':img/Help_Icon.png'), string._('Help'), self)
        helpAct.triggered.connect(self.showHelp)
        aboutAct = QAction(QIcon(':img/About_Icon.png'), string._('About'),
                           self)
        aboutAct.triggered.connect(self.showInformation)
        checkUpdateAct = QAction(QIcon(':img/Update_Icon.png'),
                                 string._('Check update'), self)
        checkUpdateAct.triggered.connect(self.checkUpdate)
        helpMenu.addAction(helpAct)
        helpMenu.addAction(checkUpdateAct)
        helpMenu.addAction(aboutAct)

    def showHelp(self):
        subprocess.Popen(
            ["explorer", "http://github.com/fcu-d0441320/iLearnBackupTool"])

    def showUserOption(self):
        self.signal_showUserOptionWindow.emit()

    def showDevOption(self):
        self.signal_showDevOptionWindow.emit()

    def Login(self):
        t = Thread(target=self.__Login)
        t.run()

    def __Login(self):
        self.web.setUser(self.input_NID.text(), self.input_Pass.text())
        self.label_iLearn.setText(
            string._('User %s is signing in...') % self.input_NID.text())
        self.print(
            string._('User %s is signing in...') % self.input_NID.text())
        status, UserName = self.web.Login()
        if status:  # == True
            self.statusbar.showMessage(string._('Sign in success'))
            self.label_iLearn.setText(
                string._('%s sign in sucess') % (UserName))
            self.print(string._('%s sign in sucess') % (UserName))
            self.input_Pass.setEnabled(False)
            self.input_NID.setEnabled(False)
            self.btn_login.setEnabled(False)
            self.btn_clean.setEnabled(False)
            self.signal_loginSuccess.emit()
        else:
            self.statusbar.showMessage(string._('Sign in failed'))
            self.label_iLearn.setText(string._('Sign in failed'))
            self.print(UserName + string._('Sign in failed'))
        self.nowLoad = 0

    def ShowResource(self):
        self.CourseTreeList.setEnabled(True)
        self.courseList = self.web.getCourseList()

        for course in self.courseList:
            courseItem = QTreeWidgetItem(self.CourseTreeListRoot)
            self.CourseTreeListRoot.setExpanded(True)
            courseItem.setFlags(courseItem.flags() | QtCore.Qt.ItemIsTristate
                                | QtCore.Qt.ItemIsUserCheckable)
            courseItem.setText(0, course['title'])
            courseItem.setCheckState(0, QtCore.Qt.Unchecked)
            courseItem.setIcon(0, QIcon(':img/mod.course.jpg'))

            child = QTreeWidgetItem(courseItem)
            child.setFlags(courseItem.flags() | QtCore.Qt.ItemIsUserCheckable)
            child.setText(0, string._('Loading...'))
            child.setCheckState(0, QtCore.Qt.Unchecked)
        self.startBackgroundLoad()

    def ExpandCourse(self, courseItem):
        if courseItem.child(0).text(0) == string._('Loading...'):
            i = 0
            for ele in self.courseList:
                if ele['title'] == courseItem.text(0):
                    break
                else:
                    i += 1
            self.timer = QtCore.QTimer()  # 计时器
            self.timer.timeout.connect(
                partial(self.appedResourceToTree, i, courseItem))
            self.timer.start(10)

    def startBackgroundLoad(self):
        if self.nowLoad < len(self.courseList):
            self.statusProcessBar.setMaximum(len(self.courseList))
            self.statusProcessBar.setFormat(
                string._('Loding course resource') + '(%v/' + '%d)' %
                (len(self.courseList)))

            reqs = threadpool.makeRequests(self.loadFileTreeBackground,
                                           range(len(self.courseList)))
            for req in reqs:
                self.pool.putRequest(req)

    def setProcessBarValue(self, value):
        if value == self.statusProcessBar.maximum():
            self.statusProcessBar.setFormat(string._('Ready...'))
            self.statusProcessBar.setMaximum(100)
            self.statusProcessBar.setValue(0)
        else:
            self.statusProcessBar.setValue(value)

    def startShowTree(self):
        for i, courseItem in [
            (i, self.CourseTreeListRoot.child(i))
                for i in range(self.CourseTreeListRoot.childCount())
        ]:
            if courseItem.child(0).text(0) == string._('Loading...'):
                self.appedResourceToTree(i, courseItem)

    def loadFileTreeBackground(self, index):
        self.signal_processbar_value.emit(index)
        if self.courseList[index]['title'] not in self.FileTree:
            FileList = self.web.getCourseFileList(
                self.courseList[index],
                useRealFileName=self.config['User'].getboolean(
                    'userealfilename'),
                showTime=self.config['dev'].getboolean('showloadtime'))
            if self.courseList[index]['title'] not in self.FileTree:
                self.FileTree[self.courseList[index]['title']] = FileList
        if index == len(self.courseList) - 1:
            self.signal_processbar_value.emit(len(self.courseList))
            self.signal_setStartBackupBtn.emit(string._('Start Backup'), True)
            self.signal_startShowTree.emit()

    def appedResourceToTree(self, i, courseItem):
        course = self.courseList[i]
        try:
            self.timer.stop()
        except:
            pass
        tStart = time.time()
        if course['title'] not in self.FileTree:
            courseFileList = self.web.getCourseFileList(
                course,
                useRealFileName=self.config['User'].getboolean(
                    'userealfilename'),
                showTime=self.config['dev'].getboolean('showloadtime'))
            if course['title'] not in self.FileTree:
                self.FileTree[course['title']] = courseFileList
                self.nowLoad += 1
        else:
            courseFileList = self.FileTree[course['title']]
        checkStatus = courseItem.checkState(0)
        totalFiles = 0
        if len(courseFileList) == 0:
            sectionItem = QTreeWidgetItem(courseItem)
            sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate
                                 | QtCore.Qt.ItemIsUserCheckable)
            sectionItem.setText(0,
                                string._('There has no resource to download.'))
            sectionItem.setCheckState(0, checkStatus)
        for section in courseFileList:
            sectionItem = QTreeWidgetItem(courseItem)
            sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate
                                 | QtCore.Qt.ItemIsUserCheckable)
            sectionItem.setText(0, section['section'])
            sectionItem.setCheckState(0, checkStatus)
            sectionItem.setIcon(0, QIcon(":img/mod.folder.svg"))
            for recource in section['mods']:
                if recource['mod'] == 'forum':
                    forumItem = QTreeWidgetItem(sectionItem)
                    forumItem.setFlags(forumItem.flags()
                                       | QtCore.Qt.ItemIsTristate
                                       | QtCore.Qt.ItemIsUserCheckable)
                    forumItem.setText(0, recource['name'])
                    forumItem.setCheckState(0, checkStatus)
                    forumItem.setIcon(0, QIcon(":img/mod.discuss.svg"))
                    for topic in recource['data']:
                        topicItem = QTreeWidgetItem(forumItem)
                        topicItem.setFlags(topicItem.flags()
                                           | QtCore.Qt.ItemIsTristate
                                           | QtCore.Qt.ItemIsUserCheckable)
                        topicItem.setText(0, topic['name'])
                        topicItem.setCheckState(0, checkStatus)
                        topicItem.setIcon(0, QIcon(":img/mod.discuss.svg"))
                        totalFiles += 1
                elif recource['mod'] in [
                        'url', 'resource', 'assign', 'page', 'videos'
                ]:
                    recourceItem = QTreeWidgetItem(sectionItem)
                    recourceItem.setFlags(recourceItem.flags()
                                          | QtCore.Qt.ItemIsTristate
                                          | QtCore.Qt.ItemIsUserCheckable)
                    recourceItem.setText(0, recource['name'])
                    recourceItem.setCheckState(0, checkStatus)
                    recourceItem.setIcon(
                        0, QIcon(":img/mod." + recource['mod'] + ".svg"))
                    totalFiles += 1
                elif recource['mod'] == 'folder':
                    folderItem = QTreeWidgetItem(sectionItem)
                    folderItem.setFlags(folderItem.flags()
                                        | QtCore.Qt.ItemIsTristate
                                        | QtCore.Qt.ItemIsUserCheckable)
                    folderItem.setText(0, recource['name'])
                    folderItem.setCheckState(0, checkStatus)
                    folderItem.setIcon(0, QIcon(":img/mod.folder.svg"))
                    for file in recource['data']:
                        fileItem = QTreeWidgetItem(folderItem)
                        fileItem.setFlags(fileItem.flags()
                                          | QtCore.Qt.ItemIsTristate
                                          | QtCore.Qt.ItemIsUserCheckable)
                        fileItem.setText(0, file['name'])
                        fileItem.setCheckState(0, checkStatus)
                        fileItem.setIcon(0, QIcon(":img/mod.resource.svg"))
                        totalFiles += 1
        courseItem.removeChild(courseItem.child(0))
        tStop = time.time()
        if self.config['dev'].getboolean('showloadtime'):
            self.print(
                string._(
                    'Load course %s in %.3f sec, total has %d resource(s)') %
                (courseItem.text(0), tStop - tStart, totalFiles))

    def showFileList(self):
        self.btn_StartBackup.setEnabled(False)
        courseIndex = 0
        for courseItem in [
                self.CourseTreeListRoot.child(i)
                for i in range(self.CourseTreeListRoot.childCount())
        ]:
            courseIndex += 1
            self.signal_processbar_value.emit(courseIndex)
            courseData = self.FileTree[courseItem.text(0)]
            if courseItem.checkState(0) != QtCore.Qt.Unchecked:
                for sectionItem in [
                        courseItem.child(i)
                        for i in range(courseItem.childCount())
                ]:
                    sectionItemName = sectionItem.text(0)
                    if sectionItemName == string._(
                            'There has no resource to download.'):
                        continue
                    sectionData = \
                    [courseData[i] for i in range(len(courseData)) if courseData[i]['section'] == sectionItemName][0]
                    if sectionItem.checkState(0) != QtCore.Qt.Unchecked:
                        for modItem in [
                                sectionItem.child(i)
                                for i in range(sectionItem.childCount())
                        ]:
                            modItemName = modItem.text(0)
                            modData = [
                                sectionData['mods'][i]
                                for i in range(len(sectionData['mods'])) if
                                sectionData['mods'][i]['name'] == modItemName
                            ][0]
                            if modItem.checkState(0) != QtCore.Qt.Unchecked:
                                if modData['mod'] == 'forum':
                                    for topicItem in [
                                            modItem.child(i) for i in range(
                                                modItem.childCount())
                                    ]:
                                        if topicItem.checkState(
                                                0) == QtCore.Qt.Checked:
                                            topicName = topicItem.text(0)
                                            resource = [
                                                modData['data'][i]
                                                for i in range(
                                                    len(modData['data']))
                                                if modData['data'][i]['name']
                                                == topicName
                                            ][0]
                                            self.signal_appendDownloadList.emit(
                                                resource)
                                elif modData['mod'] in [
                                        'resource', 'url', 'assign', 'page',
                                        'videos'
                                ]:
                                    if modItem.checkState(
                                            0) == QtCore.Qt.Checked:
                                        self.signal_appendDownloadList.emit(
                                            modData)
                                elif modData['mod'] == 'folder':
                                    for fileItem in [
                                            modItem.child(i) for i in range(
                                                modItem.childCount())
                                    ]:
                                        if fileItem.checkState(
                                                0) == QtCore.Qt.Checked:
                                            fileName = fileItem.text(0)
                                            resource = [
                                                modData['data'][i]
                                                for i in range(
                                                    len(modData['data']))
                                                if modData['data'][i]['name']
                                                == fileName
                                            ][0]
                                            self.signal_appendDownloadList.emit(
                                                resource)
        self.retryTimes = 0
        self.failedList = []
        self.retryList = []
        self.success = 0
        self.failed = 0
        time.sleep(0.5)
        reqs = threadpool.makeRequests(self.startDownload,
                                       range(len(self.fileList)))
        for req in reqs:
            self.DownloadPool.putRequest(req)
        if len(self.fileList) == 0:
            self.btn_StartBackup.setEnabled(True)
        else:
            self.statusProcessBar.setFormat(
                string._('Downloading...') + "(%v/" +
                "%d)" % len(self.fileList))
            self.statusProcessBar.setMaximum(len(self.fileList))

    def startRetry(self):
        if self.retryAfter == 0:
            self.retryTimes += 1
            self.retryTimer.stop()
            self.retryList = self.failedList
            self.failedList = []
            reqs = threadpool.makeRequests(self.startDownload, self.retryList)
            for req in reqs:
                self.DownloadPool.putRequest(req)
            self.statusProcessBar.setFormat(
                string._('Downloading...') + "(%v/" +
                "%d)" % len(self.retryList))
            self.statusProcessBar.setMaximum(len(self.retryList))
        else:
            self.retryAfter -= 1
            self.signal_setStartBackupBtn.emit(
                string._('Download will retry after %d sec.') %
                self.retryAfter, False)

    def appendItemToDownloadList(self, Item):
        self.fileList.append(Item)
        mod = Item['mod']
        if '/' in mod:
            mod = mod.split('/')[1]
        row_count = self.StatusTable.rowCount()
        self.StatusTable.insertRow(row_count)
        self.StatusTable.setItem(row_count, 0, QTableWidgetItem(Item['name']))
        self.StatusTable.setItem(row_count, 1, QTableWidgetItem(Item['path']))
        self.StatusTable.setItem(
            row_count, 2,
            QTableWidgetItem(QIcon(':img/mod.%s.svg' % mod), Item['mod']))
        self.StatusTable.setItem(row_count, 3, QTableWidgetItem('等待中...'))

    def startDownload(self, idx):
        if idx < len(self.fileList):
            self.btn_StartBackup.setText(
                string._('Downloading...(%d/%d)') % (idx, len(self.fileList)))
            if self.retryTimes != 0:
                indexInRetryList = 0
                for ele in self.retryList:
                    indexInRetryList += 1
                    if ele == idx:
                        break
                self.btn_StartBackup.setText(
                    string._('Downloading...(%d/%d)') %
                    (indexInRetryList, len(self.retryList)))
            self.signal_processbar_value.emit(idx)
            self.print(string._('Start to download %dth file') % (idx + 1))
            self.web.DownloadFile(idx, self.fileList[idx])
            time.sleep(0.5)

    def StartBackup(self):
        self.fileList = []
        self.StatusTable.setRowCount(0)
        self.statusProcessBar.setFormat(
            string._('Loading file list') + "(%v" +
            "/%d)" % self.CourseTreeListRoot.childCount())
        self.statusProcessBar.setMaximum(self.CourseTreeListRoot.childCount())
        self.showFileList()

    def showInformation(self):
        QMessageBox.about(self, string._('About'),
                          string._('tool Information') % self.version)

    def TestiLearnConnection(self):
        self.statusbar.showMessage(
            string._('Testing connection with iLearn2...'))
        self.label_iLearn.setText(string._('Connecting...'))
        if self.web.TestConnection():  # ==Ture
            self.statusbar.showMessage(string._('Connect to iLearn2 success!'))
            self.label_iLearn.setText(string._('Connect success!'))
        else:
            self.statusbar.showMessage(string._('Can not connect to iLearn2!'))
            self.label_iLearn.setText(string._('Connect failed!'))

    def readSetting(self):
        try:
            self.config.read('setting.ini', encoding='utf-8')
            OPTION = self.config.get('User', 'userealfilename')
            OPTION = self.config.get('User', 'language')
            OPTION = self.config.get('User', 'retrytimes')
            OPTION = self.config.get('User', 'secondbetweenretry')
            OPTION = self.config.get('dev', 'nid')
            OPTION = self.config.get('dev', 'pass')
            OPTION = self.config.get('dev', 'showloadtime')
        except:
            self.config['User'] = {}
            self.config['User']['userealfilename'] = 'False'
            self.config['User']['language'] = '繁體中文'
            self.config['dev'] = {}
            self.config['dev']['nid'] = ''
            self.config['dev']['pass'] = ''
            self.config['dev']['autologin'] = '******'
            self.config['dev']['showloadtime'] = 'False'
            self.config['User']['retrytimes'] = '3'
            self.config['User']['secondbetweenretry'] = '5'
            with open('setting.ini', 'w', encoding='utf-8') as configfile:
                self.config.write(configfile)

    def restart(self):
        subprocess.Popen("iLearnBackupTool")
        self.close()
Пример #37
0
    def create_complex_node(self, key, value, root=None):
        # 0: key, 1:value, 2:type 3:file/image path
        sub_node = None
        if isinstance(value, (int, float)):
            if root is None:
                sub_node = QTreeWidgetItem(self.__right_tree)
                sub_node.setText(0, key)
                sub_node.setText(1, str(value))
                sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable)
            else:
                sub_node = create_tree_item(key=key, value=value, edit=True)
                root.addChild(sub_node)
                root.setExpanded(True)

        elif isinstance(value, str):
            if root is None:
                sub_node = QTreeWidgetItem(self.__right_tree)
                sub_node.setText(0, key)
                sub_node.setText(1, str(value))
                if key not in DISABLE_EDIT_KEYS:
                    sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable)

            else:
                enable_edit = False
                if key in [
                        ITEM_TYPE_ELEMENT_NAME, ITEM_CONDITION_NAME,
                        ITEM_CONDITIONS_NAME
                ]:
                    enable_edit = True
                sub_node = create_tree_item(key=key,
                                            value=value,
                                            edit=enable_edit)
                root.addChild(sub_node)

            if key == 'algorithm':
                self._create_algorithm_node(key=key,
                                            value=value,
                                            node=sub_node)
            elif key == 'type':
                self._set_type_node(key, value, sub_node)

        elif isinstance(value, dict):
            if root is None:
                sub_node = QTreeWidgetItem(self.__right_tree)
                sub_node.setText(0, key)
            else:
                sub_node = create_tree_item(key=key)
                root.addChild(sub_node)

            if key == 'refer':
                sub_node.setText(2, ITEM_TYPE_REFER_TASK)

            for sub_key, sub_value in value.items():
                self.create_complex_node(key=sub_key,
                                         value=sub_value,
                                         root=sub_node)

            sub_node.setExpanded(True)

        elif isinstance(value, list):
            if key == 'elements':
                sub_node = QTreeWidgetItem(self.__right_tree)
                sub_node.setText(0, key)
                sub_node.setText(2, ITEM_TYPE_ELEMENTS)
                sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable)
            else:
                sub_node = root

            for sub_value in value:
                rename_key = key[:-1]
                sub_type = ITEM_TYPE_ELEMENT
                if rename_key == 'template':
                    sub_type = ITEM_TYPE_TEMPLATE
                enable_edit = False
                ss_node = create_tree_item(key=rename_key,
                                           node_type=sub_type,
                                           edit=enable_edit)
                sub_node.addChild(ss_node)
                for ss_key, ss_value in sub_value.items():
                    self.create_complex_node(key=ss_key,
                                             value=ss_value,
                                             root=ss_node)
                ss_node.setExpanded(True)
            sub_node.setExpanded(True)

        if sub_node is None:
            return

        if key in SCENE_HIDDEN_KEYS:
            sub_node.setHidden(True)
Пример #38
0
 def appedResourceToTree(self, i, courseItem):
     course = self.courseList[i]
     try:
         self.timer.stop()
     except:
         pass
     tStart = time.time()
     if course['title'] not in self.FileTree:
         courseFileList = self.web.getCourseFileList(
             course,
             useRealFileName=self.config['User'].getboolean(
                 'userealfilename'),
             showTime=self.config['dev'].getboolean('showloadtime'))
         if course['title'] not in self.FileTree:
             self.FileTree[course['title']] = courseFileList
             self.nowLoad += 1
     else:
         courseFileList = self.FileTree[course['title']]
     checkStatus = courseItem.checkState(0)
     totalFiles = 0
     if len(courseFileList) == 0:
         sectionItem = QTreeWidgetItem(courseItem)
         sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate
                              | QtCore.Qt.ItemIsUserCheckable)
         sectionItem.setText(0,
                             string._('There has no resource to download.'))
         sectionItem.setCheckState(0, checkStatus)
     for section in courseFileList:
         sectionItem = QTreeWidgetItem(courseItem)
         sectionItem.setFlags(sectionItem.flags() | QtCore.Qt.ItemIsTristate
                              | QtCore.Qt.ItemIsUserCheckable)
         sectionItem.setText(0, section['section'])
         sectionItem.setCheckState(0, checkStatus)
         sectionItem.setIcon(0, QIcon(":img/mod.folder.svg"))
         for recource in section['mods']:
             if recource['mod'] == 'forum':
                 forumItem = QTreeWidgetItem(sectionItem)
                 forumItem.setFlags(forumItem.flags()
                                    | QtCore.Qt.ItemIsTristate
                                    | QtCore.Qt.ItemIsUserCheckable)
                 forumItem.setText(0, recource['name'])
                 forumItem.setCheckState(0, checkStatus)
                 forumItem.setIcon(0, QIcon(":img/mod.discuss.svg"))
                 for topic in recource['data']:
                     topicItem = QTreeWidgetItem(forumItem)
                     topicItem.setFlags(topicItem.flags()
                                        | QtCore.Qt.ItemIsTristate
                                        | QtCore.Qt.ItemIsUserCheckable)
                     topicItem.setText(0, topic['name'])
                     topicItem.setCheckState(0, checkStatus)
                     topicItem.setIcon(0, QIcon(":img/mod.discuss.svg"))
                     totalFiles += 1
             elif recource['mod'] in [
                     'url', 'resource', 'assign', 'page', 'videos'
             ]:
                 recourceItem = QTreeWidgetItem(sectionItem)
                 recourceItem.setFlags(recourceItem.flags()
                                       | QtCore.Qt.ItemIsTristate
                                       | QtCore.Qt.ItemIsUserCheckable)
                 recourceItem.setText(0, recource['name'])
                 recourceItem.setCheckState(0, checkStatus)
                 recourceItem.setIcon(
                     0, QIcon(":img/mod." + recource['mod'] + ".svg"))
                 totalFiles += 1
             elif recource['mod'] == 'folder':
                 folderItem = QTreeWidgetItem(sectionItem)
                 folderItem.setFlags(folderItem.flags()
                                     | QtCore.Qt.ItemIsTristate
                                     | QtCore.Qt.ItemIsUserCheckable)
                 folderItem.setText(0, recource['name'])
                 folderItem.setCheckState(0, checkStatus)
                 folderItem.setIcon(0, QIcon(":img/mod.folder.svg"))
                 for file in recource['data']:
                     fileItem = QTreeWidgetItem(folderItem)
                     fileItem.setFlags(fileItem.flags()
                                       | QtCore.Qt.ItemIsTristate
                                       | QtCore.Qt.ItemIsUserCheckable)
                     fileItem.setText(0, file['name'])
                     fileItem.setCheckState(0, checkStatus)
                     fileItem.setIcon(0, QIcon(":img/mod.resource.svg"))
                     totalFiles += 1
     courseItem.removeChild(courseItem.child(0))
     tStop = time.time()
     if self.config['dev'].getboolean('showloadtime'):
         self.print(
             string._(
                 'Load course %s in %.3f sec, total has %d resource(s)') %
             (courseItem.text(0), tStop - tStart, totalFiles))
Пример #39
0
 def TreeItem(self, parent, name, tooltip, icon):
     child = QTreeWidgetItem(parent)
     child.setText(0, name)
     child.setToolTip(0, tooltip)
     child.setIcon(0, QIcon(icon))
     child.setFlags(child.flags())
Пример #40
0
 def __generateItem(self, status, propStatus, locked, history, switched,
                    lockinfo, uptodate, revision, change, author, path):
     """
     Private method to generate a status item in the status list.
     
     @param status status indicator (string)
     @param propStatus property status indicator (string)
     @param locked locked indicator (string)
     @param history history indicator (string)
     @param switched switched indicator (string)
     @param lockinfo lock indicator (string)
     @param uptodate up to date indicator (string)
     @param revision revision string (string)
     @param change revision of last change (string)
     @param author author of the last change (string)
     @param path path of the file or directory (string)
     """
     if self.__nonverbose and \
        status == " " and \
        propStatus == " " and \
        locked == " " and \
        history == " " and \
        switched == " " and \
        lockinfo == " " and \
        uptodate == " " and \
        self.currentChangelist == "":
         return
     
     if revision == "":
         rev = ""
     else:
         try:
             rev = int(revision)
         except ValueError:
             rev = revision
     if change == "":
         chg = ""
     else:
         try:
             chg = int(change)
         except ValueError:
             chg = change
     statusText = self.status[status]
     
     itm = QTreeWidgetItem(self.statusList)
     itm.setData(0, Qt.DisplayRole, "")
     itm.setData(1, Qt.DisplayRole, self.currentChangelist)
     itm.setData(2, Qt.DisplayRole, statusText)
     itm.setData(3, Qt.DisplayRole, self.propStatus[propStatus])
     itm.setData(4, Qt.DisplayRole, self.locked[locked])
     itm.setData(5, Qt.DisplayRole, self.history[history])
     itm.setData(6, Qt.DisplayRole, self.switched[switched])
     itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo])
     itm.setData(8, Qt.DisplayRole, self.uptodate[uptodate])
     itm.setData(9, Qt.DisplayRole, rev)
     itm.setData(10, Qt.DisplayRole, chg)
     itm.setData(11, Qt.DisplayRole, author)
     itm.setData(12, Qt.DisplayRole, path)
     
     itm.setTextAlignment(1, Qt.AlignLeft)
     itm.setTextAlignment(2, Qt.AlignHCenter)
     itm.setTextAlignment(3, Qt.AlignHCenter)
     itm.setTextAlignment(4, Qt.AlignHCenter)
     itm.setTextAlignment(5, Qt.AlignHCenter)
     itm.setTextAlignment(6, Qt.AlignHCenter)
     itm.setTextAlignment(7, Qt.AlignHCenter)
     itm.setTextAlignment(8, Qt.AlignHCenter)
     itm.setTextAlignment(9, Qt.AlignRight)
     itm.setTextAlignment(10, Qt.AlignRight)
     itm.setTextAlignment(11, Qt.AlignLeft)
     itm.setTextAlignment(12, Qt.AlignLeft)
     
     if status in "ADM" or propStatus in "M":
         itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
         itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
     else:
         itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable)
     
     self.hidePropertyStatusColumn = self.hidePropertyStatusColumn and \
         propStatus == " "
     self.hideLockColumns = self.hideLockColumns and \
         locked == " " and lockinfo == " "
     self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " "
     self.hideHistoryColumn = self.hideHistoryColumn and history == " "
     self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " "
     
     if statusText not in self.__statusFilters:
         self.__statusFilters.append(statusText)
Пример #41
0
 def FolderItem(self, parent, name, icon):
     table_folder = QTreeWidgetItem(parent)
     table_folder.setText(0, name)
     table_folder.setIcon(0, QIcon(icon))
     table_folder.setFlags(table_folder.flags())
     return table_folder
Пример #42
0
 def __generateItem(self, changelist, status, propStatus, locked, history,
                    switched, lockinfo, uptodate, revision, change, author,
                    path):
     """
     Private method to generate a status item in the status list.
     
     @param changelist name of the changelist (string)
     @param status text status (pysvn.wc_status_kind)
     @param propStatus property status (pysvn.wc_status_kind)
     @param locked locked flag (boolean)
     @param history history flag (boolean)
     @param switched switched flag (boolean)
     @param lockinfo lock indicator (string)
     @param uptodate up to date flag (boolean)
     @param revision revision (integer)
     @param change revision of last change (integer)
     @param author author of the last change (string)
     @param path path of the file or directory (string)
     """
     statusText = self.tr(svnStatusMap[status])
     itm = QTreeWidgetItem(self.statusList)
     itm.setData(0, Qt.DisplayRole, "")
     itm.setData(1, Qt.DisplayRole, changelist)
     itm.setData(2, Qt.DisplayRole, statusText)
     itm.setData(3, Qt.DisplayRole, self.tr(svnStatusMap[propStatus]))
     itm.setData(4, Qt.DisplayRole, self.yesno[locked])
     itm.setData(5, Qt.DisplayRole, self.yesno[history])
     itm.setData(6, Qt.DisplayRole, self.yesno[switched])
     itm.setData(7, Qt.DisplayRole, self.lockinfo[lockinfo])
     itm.setData(8, Qt.DisplayRole, self.yesno[uptodate])
     itm.setData(9, Qt.DisplayRole, revision)
     itm.setData(10, Qt.DisplayRole, change)
     itm.setData(11, Qt.DisplayRole, author)
     itm.setData(12, Qt.DisplayRole, path)
     
     itm.setTextAlignment(1, Qt.AlignLeft)
     itm.setTextAlignment(2, Qt.AlignHCenter)
     itm.setTextAlignment(3, Qt.AlignHCenter)
     itm.setTextAlignment(4, Qt.AlignHCenter)
     itm.setTextAlignment(5, Qt.AlignHCenter)
     itm.setTextAlignment(6, Qt.AlignHCenter)
     itm.setTextAlignment(7, Qt.AlignHCenter)
     itm.setTextAlignment(8, Qt.AlignHCenter)
     itm.setTextAlignment(9, Qt.AlignRight)
     itm.setTextAlignment(10, Qt.AlignRight)
     itm.setTextAlignment(11, Qt.AlignLeft)
     itm.setTextAlignment(12, Qt.AlignLeft)
     
     if status in [pysvn.wc_status_kind.added,
                   pysvn.wc_status_kind.deleted,
                   pysvn.wc_status_kind.modified] or \
        propStatus in [pysvn.wc_status_kind.added,
                       pysvn.wc_status_kind.deleted,
                       pysvn.wc_status_kind.modified]:
         itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
         itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
     else:
         itm.setFlags(itm.flags() & ~Qt.ItemIsUserCheckable)
     
     if statusText not in self.__statusFilters:
         self.__statusFilters.append(statusText)
class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)



        self.plot_title = 'f(R),f(R,Q),GR comparison for Mass and Radius'
        self.xlabel = "$R[km]$"
        self.ylabel = r'$M[M_\odot]$'
        self.xlim = (8.0, 20.0)

        tree = QTreeWidget()
        headerItem = QTreeWidgetItem()
        item = QTreeWidgetItem()

        tree_fRQ = QTreeWidget()
        headerItem_fRQ = QTreeWidgetItem()
        item_fRQ = QTreeWidgetItem()

        tree_GR = QTreeWidget()
        headerItem_GR = QTreeWidgetItem()
        item_GR = QTreeWidgetItem()

        tree_quantities = QTreeWidget()
        headerItem_quantities = QTreeWidgetItem()
        item_quantities = QTreeWidgetItem()

        self.quant_branch = QTreeWidgetItem(tree_quantities)
        self.quant_branch.setText(0, "Quantities")
        self.quant_branch.setFlags(self.quant_branch.flags() )
        # self.GR_branch.setCheckState(0, Qt.Unchecked)

        child = QTreeWidgetItem(self.quant_branch)
        child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
        child.setText(0, 'R-M')
        child.setCheckState(0, Qt.Checked)
        child.emitDataChanged()  # .connect(self.plot)

        child = QTreeWidgetItem(self.quant_branch)
        child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
        child.setText(0, 'rho-M')
        child.setCheckState(0, Qt.Unchecked)
        child.emitDataChanged()

        self.GR_branch = QTreeWidgetItem(tree_GR)
        self.GR_branch.setText(0, "GR")
        self.GR_branch.setFlags(self.GR_branch.flags() | Qt.ItemIsTristate  | Qt.ItemIsUserCheckable)
        #self.GR_branch.setCheckState(0, Qt.Unchecked)

        for x in range(len(glob.glob('Results/TOV_output_GR_*'))):
            child = QTreeWidgetItem(self.GR_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext =  GR_Modellist[x].EOS_type
            child.setText(0,checktext)
            child.setCheckState(0, Qt.Unchecked)
            child.emitDataChanged()# .connect(self.plot)

        self.fR_branch = QTreeWidgetItem(tree)
        self.fR_branch.setText(0,"fR")
        self.fR_branch.setFlags(self.fR_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

        for x in range(len(glob.glob('Results/TOV_output_fR_*'))):
            child = QTreeWidgetItem(self.fR_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext = fR_Modellist[x].ID + fR_Modellist[x].EOS_type
            child.setText(0,checktext)
            child.setCheckState(0, Qt.Unchecked)
            child.emitDataChanged()# .connect(self.plot)

        #if(fRQ_branch.child(1).isSelected==1){print("hey hey")}

        self.fRQ_branch = QTreeWidgetItem(tree_fRQ)
        self.fRQ_branch.setText(0, "fRQ")
        self.fRQ_branch.setFlags(self.fRQ_branch.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

        for x in range(len(glob.glob('Results/TOV_output_fRQ_*'))):
            child = QTreeWidgetItem(self.fRQ_branch)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            checktext = fRQ_Modellist[x].ID + fRQ_Modellist[x].EOS_type
            child.setText(0, checktext)
            child.setCheckState(0, Qt.Unchecked)
        print("checked?", self.fR_branch.child(0).isSelected())
        tree.itemChanged.connect(self.plot)
        tree_fRQ.itemChanged.connect(self.plot)
        tree_GR.itemChanged.connect(self.plot)
        tree_quantities.itemChanged.connect(self.quant_change)
        tree_quantities.itemChanged.connect(self.plot)



        #tree.show()

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        #self.button = QPushButton('Plot')
        #self.button.clicked.connect(self.plot)

        # set the layout
        self.layout = QVBoxLayout()

        self.sublayout1 = QVBoxLayout()
        self.sublayout2 = QHBoxLayout()
        plotBox = QHBoxLayout()
        plotBox.addLayout(self.sublayout1, 1)
        plotBox.addLayout(self.sublayout2, 4)
        bottomlayout = QHBoxLayout()
        #self.layout.addLayout()


        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas,1)
        #self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        #layout = QHBoxLayout()
        self.btn_rhoM = QCheckBox("rho-M")
        self.btn_RM = QCheckBox("R-M")
        self.btn_GR = QCheckBox("GR")
        self.btn_fR =  QCheckBox("fR")
        self.btn_fRQ = QCheckBox("fRQ")

        self.btn_fRs = []

        self.btn_rhoM.setChecked(False)
        self.btn_RM.setChecked(True)
        self.btn_GR.setChecked(False)
        self.btn_fR.setChecked(False)
        self.btn_fRQ.setChecked(False)

        #self.b1.stateChanged.connect(lambda: self.btnstate(self.b1))
        #self.btn_rhoM.stateChanged.connect(self.quant_change)
        #self.btn_RM.stateChanged.connect(self.quant_change)

        self.btn_rhoM.stateChanged.connect(self.plot)
        self.btn_RM.stateChanged.connect(self.plot)
        self.btn_GR.stateChanged.connect(self.plot)
        self.btn_fR.stateChanged.connect(self.plot)
        self.btn_fRQ.stateChanged.connect(self.plot)

        #self.layout.addWidget(self.btn_GR)
        #self.layout.addWidget(self.btn_fR)
        #self.layout.addWidget(self.btn_fRQ)
        self.sublayout2.addWidget(tree_quantities)
        self.sublayout2.addWidget(tree_GR)
        self.sublayout2.addWidget(tree)
        self.sublayout2.addWidget(tree_fRQ)
        self.layout.addLayout(plotBox)

    def quant_change(self):
        if(self.quant_branch.child(0).checkState(0)):
            self.plot_title = 'f(R),f(R,Q),GR comparison for Radius and Mass of NS'
            self.xlabel = "R[km]"
            self.ylabel = r'M[$M_\odot$]'
            self.xlim = (8.0, 20.0)


        if (self.quant_branch.child(1).checkState(0)):
            self.plot_title = 'f(R),f(R,Q),GR comparison for Central Density and Mass of NS'
            self.xlabel = r'$\log\rho_c[\frac{g}{cm^3}]$'
            self.ylabel = r'M[$M_\odot$]'
            self.xlim = (13.5, 17.0)


    def plot(self):
        fR_label = 'f(R)\n  $(R_p=$' + r'$%s$' % fR_Rp + r'$)$'
        fRQ_label = 'f(R,Q) \n  $(R_p=$' + r'$%s$' % fRQ_Rp + '$)$\n  ' + r'$(R_q=$' + r'$%s$' % fRQ_Rq + '$)$'

        if self.btn_fR.isChecked() == True:
            #self.btn_fRs.append(QCheckBox("yep"))
            print("self.fR_branch.child(i).isSelected()", self.fR_branch.child(i).isSelected())
            self.layout.addWidget(self.btn_fRs[0])
            plt.plot(x, y,  label=r'${}$'.format(fR_label), color='blue')
            plt.title('fR/GR comparison for Mass and Radius for $R_p=2.1*10^{80}$')
            plt.legend(fontsize=20)

            #plt.show()


        ''' plot some random stuff '''
        # random data
        #data = [random.random() for i in range(10)]

        # instead of ax.hold(False)
        self.figure.clear()

        # create an axis
        ax = self.figure.add_subplot(111)

        # discards the old graph
        # ax.hold(False) # deprecated, see above

        # plot data

        for i in range(len(glob.glob('Results/TOV_output_GR_*'))):
            if self.GR_branch.child(i).checkState(0):
                labelly = 'GR ' + GR_Modellist[i].EOS_type
                if (self.quant_branch.child(0).checkState(0)):
                    ax.plot(GR_Modellist[i].rad, GR_Modellist[i].mass, label=labelly) #, next(linecycler)
                if (self.quant_branch.child(1).checkState(0)):
                    ax.plot(GR_Modellist[i].rho, GR_Modellist[i].mass, label=labelly) #, next(linecycler)



        for i in range(len(glob.glob('Results/TOV_output_fR_*'))):
            if self.fR_branch.child(i).checkState(0):
                labelly = 'f(R) ' + fR_Modellist[i].EOS_type + ": R_p= " + fR_Modellist[i].ID
                if (self.quant_branch.child(0).checkState(0)):
                    ax.plot(fR_Modellist[i].rad,fR_Modellist[i].mass,next(linecycler),label=r'${}$'.format(labelly))
                if (self.quant_branch.child(1).checkState(0)):
                    ax.plot(fR_Modellist[i].rho, fR_Modellist[i].mass,next(linecycler), label=r'${}$'.format(labelly))
                #print(self.fR_branch.child(i).isSelected())
                #ax.plot(x5, y5, label='GR', color='black')


        for i in range(len(glob.glob('Results/TOV_output_fRQ_*'))):
            if self.fRQ_branch.child(i).checkState(0):
                labelly = 'f(R,Q) ' + fRQ_Modellist[i].EOS_type + ": R_p= " + fRQ_Modellist[i].ID
                if (self.quant_branch.child(0).checkState(0)):
                    ax.plot(fRQ_Modellist[i].rad,fRQ_Modellist[i].mass,next(linecycler),label=r'${}$'.format(labelly))
                if (self.quant_branch.child(1).checkState(0)):
                    ax.plot(fRQ_Modellist[i].rho, fRQ_Modellist[i].mass, next(linecycler), label=r'${}$'.format(labelly))

                    #ax.plot(x5, y5, label='GR', color='black')
                #print(fRQ_Modellist[i].rad, " ", fRQ_Modellist[i].mass)


        ax.legend(fontsize=15)
        if self.btn_fRQ.isChecked() == True:
            ax.plot(x2, y2, label=fRQ_label, color='blue')
            ax.legend(fontsize=20)



        #ax.set_title(self.plot_title)
        ax.set_xlim(self.xlim)
        ax.set_xlabel(self.xlabel,fontsize=20)
        ax.set_ylabel(self.ylabel,fontsize=20)
        # refresh canvas
        self.canvas.draw()




    def btnstate(self, b):
        if b.text() == "fR":
            if b.isChecked() == True:
                self.plot(b)