Esempio n. 1
1
    def __init__(self):
        super(PugdebugExpressionViewer, self).__init__()

        # Action for adding a new expression
        self.add_action = QAction(QIcon.fromTheme('list-add'), "&Add", self)
        self.add_action.triggered.connect(self.handle_add_action)

        # Action for deleting selected expressions
        self.delete_action = QAction(
            QIcon.fromTheme('list-remove'),
            "&Delete", self
        )
        self.delete_action.setShortcut(QKeySequence("Del"))
        self.delete_action.triggered.connect(self.handle_delete_action)

        self.toolbar = QToolBar()
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.addAction(self.add_action)
        self.toolbar.addAction(self.delete_action)

        self.tree = QTreeWidget()
        self.tree.setColumnCount(3)
        self.tree.setHeaderLabels(['Expression', 'Type', 'Value'])
        self.tree.setSelectionMode(QAbstractItemView.ContiguousSelection)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.show_context_menu)

        layout = QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.tree)
        self.setLayout(layout)

        self.restore_state()

        self.tree.itemChanged.connect(self.handle_item_changed)
Esempio n. 2
0
    def create_mid_group(self):
        self.ddi_tree = QTreeWidget()
        self.ddi_tree.itemSelectionChanged.connect(self.show_ddi_details)

        ddi_details = QGroupBox()
        ddi_details_layout = QGridLayout()
        ddi_details_layout.setContentsMargins(0,0,0,0)
        ddi_details_layout.addWidget(self.create_common_ddi_details(), 0, 0, 1, 1)
        ddi_details_layout.addWidget(self.create_specific_ddi_details(), 1, 0, 3, 1)
        ddi_details.setLayout(ddi_details_layout)

        self.step_tree = QTreeWidget()
        self.step_tree.itemSelectionChanged.connect(self.show_step_details)
        step_details = QGroupBox()
        step_details_layout = QGridLayout()
        step_details_layout.setContentsMargins(0,0,0,0)
        step_details_layout.addWidget(self.create_common_step_details(), 0, 0, 1, 1)
        # step_details_layout.addWidget(self.create_specific_step_details(), 1, 0, 3, 1)
        step_details.setLayout(step_details_layout)

        splitter = QSplitter(self)
        splitter.addWidget(self.ddi_tree)
        splitter.addWidget(ddi_details)
        splitter.addWidget(self.step_tree)
        splitter.addWidget(step_details)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(0,0,0,0)
        # self.__mix_to_layout(hbox, self.ddi_tree, ddi_details, self.step_tree, step_details)
        hbox.addWidget(splitter)
        # group_box.setLayout(hbox)
        return hbox
Esempio n. 3
0
 def keyPressEvent(self, e):
     if e.key() == Qt.Key_Enter or e.key() == Qt.Key_Return:
         item = self.currentItem()
         col  = self.currentColumn()
         self.editItem(item, col)
         
     elif e.key() == Qt.Key_Left or e.key() == Qt.Key_Right:
             curr_idx = self.currentIndex()
             if e.key() == Qt.Key_Left:
                 if curr_idx.column() > 0:
                     next_idx = curr_idx.sibling(curr_idx.row(), curr_idx.column()-1)
                     self.setCurrentIndex(next_idx)
             else: 
                 if curr_idx.column() < self.colSELOPT:
                     next_idx = curr_idx.sibling(curr_idx.row(), curr_idx.column()+1)
                     self.setCurrentIndex(next_idx)
                     
     elif (e.key() == Qt.Key_Up or e.key() == Qt.Key_Down) and e.modifiers() == Qt.ControlModifier:
         item = self.currentItem()
         idx  = self.currentIndex()
         if e.key() == Qt.Key_Up:
             if item.childCount():
                 self.collapseItem(item)
             else:
                 if item.parent():
                     self.collapseItem( item.parent() )
                     p_idx = idx.parent()
                     self.setCurrentIndex( p_idx.sibling( p_idx.row(), idx.column() ) )
         else:
             if item.childCount():
                 self.expandItem(item)
     else:
         QTreeWidget.keyPressEvent(self, e)
Esempio n. 4
0
 def __init__(self, parent, items):
     QTreeWidget.__init__( self )
     self.setColumnCount( 2 )
     header = QTreeWidgetItem( SubtleTreeWidget.ITEM_ROLE )
     header.setText(0, 'File')
     header.setText(1, 'Status')
     self.setHeaderItem( header )
     self.addTopLevelItems( items )
Esempio n. 5
0
 def keyPressEvent(self, event: QKeyEvent):
     if self.window().is_dirty() \
             and (event.matches(QKeySequence.MoveToNextLine) or event.matches(QKeySequence.MoveToPreviousLine)):
         veto = self.window().central_widget.promptToSave()
         if not veto:
             QTreeWidget.keyPressEvent(self, event)
         else:
             event.ignore()
     else:
         QTreeWidget.keyPressEvent(self, event)
Esempio n. 6
0
 def __init__(self, parent=None):
     QTreeWidget.__init__(self, parent)
     
     self.singleOverlaySelection = True
     
     self.header().close()
     self.setSortingEnabled(True)
     self.installEventFilter(self)
     self.spacePressed.connect(self.spacePressedTreewidget)
     self.itemChanged.connect(self.treeItemChanged)
Esempio n. 7
0
    def __init__(self):
        QTreeWidget.__init__(self)
        self.setAnimated(True)
        self.setHeaderLabel(self.tr("Folders"))
        self.header().setStretchLastSection(False)
        self.header().setHidden(True)
        self.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)

        self.itemClicked.connect(self._open_file)

        Amaru.load_component("tree_project", self)
Esempio n. 8
0
    def __init__(self, jack_client, parent=None, **kwargs):
        super().__init__(parent)

        self.resize(600, 400)

        self.setLayout(QGridLayout())
        # self.layout().setContentsMargins(0, 0, 0, 0)

        self.output_widget = QTreeWidget(self)
        self.output_widget.setHeaderLabels(['Output ports'])

        self.input_widget = QTreeWidget(self)
        self.input_widget.setHeaderLabels(['Input ports'])

        self.connections_widget = ConnectionsWidget(self.output_widget,
                                                    self.input_widget,
                                                    parent=self)
        self.output_widget.itemExpanded.connect(self.connections_widget.update)
        self.output_widget.itemCollapsed.connect(self.connections_widget.update)
        self.input_widget.itemExpanded.connect(self.connections_widget.update)
        self.input_widget.itemCollapsed.connect(self.connections_widget.update)

        self.input_widget.itemSelectionChanged.connect(
            self.__input_selection_changed)
        self.output_widget.itemSelectionChanged.connect(
            self.__output_selection_changed)

        self.layout().addWidget(self.output_widget, 0, 0)
        self.layout().addWidget(self.connections_widget, 0, 1)
        self.layout().addWidget(self.input_widget, 0, 2)

        self.layout().setColumnStretch(0, 2)
        self.layout().setColumnStretch(1, 1)
        self.layout().setColumnStretch(2, 2)

        self.connectButton = QPushButton('Connect', self)
        self.connectButton.clicked.connect(self.__disconnect_selected)
        self.connectButton.setEnabled(False)
        self.layout().addWidget(self.connectButton, 1, 1)

        self.dialogButtons = QDialogButtonBox(
            QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.dialogButtons.accepted.connect(self.accept)
        self.dialogButtons.rejected.connect(self.reject)
        self.layout().addWidget(self.dialogButtons, 2, 0, 1, 3)

        self.__jack_client = jack_client
        self.__selected_in = None
        self.__selected_out = None

        self.connections = []
        self.update_graph()
Esempio n. 9
0
 def _load_ui(self):
     main_layout = QVBoxLayout(self)
     main_layout.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY))
     main_hbox = QHBoxLayout()
     # Session list
     session_layout = QVBoxLayout()
     self._session_list = QTreeWidget()
     self._session_list.setHeaderLabels(["Session", "Last Modified"])
     session_layout.addWidget(self._session_list)
     # Content frame
     content_frame = QFrame()
     content_frame.hide()
     frame_layout = QVBoxLayout(content_frame)
     content_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
     session_layout.addWidget(content_frame)
     frame_layout.setContentsMargins(0, 0, 0, 0)
     self._content_list = QTreeWidget()
     self._content_list.setHeaderHidden(True)
     frame_layout.addWidget(self._content_list)
     # Separator line
     line_frame = QFrame()
     line_frame.setFrameStyle(QFrame.VLine | QFrame.Sunken)
     # Buttons
     btn_layout = QVBoxLayout()
     btn_create = QPushButton(translations.TR_SESSIONS_BTN_CREATE)
     btn_activate = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE)
     btn_update = QPushButton(translations.TR_SESSIONS_BTN_UPDATE)
     btn_delete = QPushButton(translations.TR_SESSIONS_BTN_DELETE)
     btn_details = QPushButton(translations.TR_SESSIONS_BTN_DETAILS)
     btn_details.setCheckable(True)
     # Add buttons to layout
     btn_layout.addWidget(btn_create)
     btn_layout.addWidget(btn_activate)
     btn_layout.addWidget(btn_update)
     btn_layout.addWidget(btn_delete)
     btn_layout.addStretch()
     btn_layout.addWidget(btn_details)
     # Add widgets and layouts to the main layout
     main_layout.addLayout(main_hbox)
     main_hbox.addLayout(session_layout)
     main_hbox.addWidget(line_frame)
     main_hbox.addLayout(btn_layout)
     main_hbox.setSizeConstraint(QLayout.SetFixedSize)
     btn_details.toggled[bool].connect(content_frame.setVisible)
     # Connections
     self._session_list.itemSelectionChanged.connect(
         self.load_session_content)
     btn_activate.clicked.connect(self.open_session)
     btn_update.clicked.connect(self.save_session)
     btn_create.clicked.connect(self.create_session)
     btn_delete.clicked.connect(self.delete_session)
Esempio n. 10
0
    def fillTreeWidget(self, widget : QTreeWidget, tree : Tree):
        def helper(t : Tree, parent):
            item = QTreeWidgetItem()
            item.setText(0, t.name)
            item.setIcon(0, QIcon('data/gfx/folder.png'))
            if type(parent) == QTreeWidget:
                parent.insertTopLevelItem(0, item)
            else:
                parent.addChild(item)
            for ch in t.children:
                helper(ch, item)

        widget.setColumnCount(1)
        helper(tree, widget)
Esempio n. 11
0
    def __init__(self, parent=None):
        QTreeWidget.__init__(self, parent)
        self._model = None
        self._catRow = [-1, -1, -1]
        self._filter = ""
        self._lastID = -1
        self._updating = False
        self._showSubPlot = False
        self.setRootIsDecorated(False)
        self.setIndentation(10)

        self.setColumnCount(1)
        self._rootItem = QTreeWidgetItem()
        self.insertTopLevelItem(0, self._rootItem)
Esempio n. 12
0
    def __init__(self, parent=None):
        QTreeWidget.__init__(self, parent)
        self._model = None
        self._catRow = [-1, -1, -1]
        self._filter = ""
        self._lastID = -1
        self._updating = False
        self.setRootIsDecorated(False)
        self.setIndentation(10)
        self.setHeaderHidden(True)
        self.setIconSize(QSize(24, 24))

        self.setColumnCount(1)
        self._rootItem = QTreeWidgetItem()
        self.insertTopLevelItem(0, self._rootItem)
Esempio n. 13
0
    def __init__(self, show_root=False, scan="Scan", scan_whats_this='', whats_this=''):
        """ Initialise the editor. """

        super().__init__()

        self.package = None
        self.project = None

        self._show_root = show_root

        self._package_edit = QTreeWidget(whatsThis=whats_this)
        self._package_edit.header().hide()
        self._package_edit.itemChanged.connect(self._package_changed)
        self.addWidget(self._package_edit, 0, 0, 3, 1)

        self._scan_button = QPushButton(scan, whatsThis=scan_whats_this,
                clicked=self._scan, enabled=False)
        self.addWidget(self._scan_button, 0, 1)

        self._remove_button = QPushButton("Remove all",
                whatsThis="Remove all of the scanned directories and files.",
                clicked=self._remove_all, enabled=False)
        self.addWidget(self._remove_button, 0, 2)

        self._include_button = QPushButton("Include all",
                whatsThis="Select all of the scanned directories and files.",
                clicked=self._include_all, enabled=False)
        self.addWidget(self._include_button, 1, 1)

        self._exclude_button = QPushButton("Exclude all",
                whatsThis="Deselect all of the scanned directories and files.",
                clicked=self._exclude_all, enabled=False)
        self.addWidget(self._exclude_button, 1, 2)

        self._exclusions_edit = QTreeWidget(
                whatsThis="Any directory or file that matches any of the "
                        "these patterns will be automatically ignored when "
                        "scanning. Double-click on a pattern to edit or remove "
                        "it. Double-click below the last pattern in order to "
                        "add a new one.")
        self._exclusions_edit.setHeaderLabel("Exclusions")
        self._exclusions_edit.setEditTriggers(
                QTreeWidget.DoubleClicked|QTreeWidget.SelectedClicked|
                        QTreeWidget.EditKeyPressed)
        self._exclusions_edit.setRootIsDecorated(False)
        self._exclusions_edit.itemChanged.connect(self._exclusion_changed)

        self.addWidget(self._exclusions_edit, 2, 1, 1, 2)
Esempio n. 14
0
    def __init__(self, cues=None, properties=('index', 'name'), **kwargs):
        super().__init__(**kwargs)

        self.setMinimumSize(600, 400)

        self._properties = list(properties)
        self._cues = {}

        self.list = QTreeWidget(self)
        self.list.setSelectionMode(QTreeWidget.SingleSelection)
        self.list.setSelectionBehavior(QTreeWidget.SelectRows)
        self.list.setAlternatingRowColors(True)
        self.list.setIndentation(0)
        self.list.setHeaderLabels([prop.title() for prop in properties])
        self.list.header().setSectionResizeMode(QHeaderView.Fixed)
        self.list.header().setSectionResizeMode(1, QHeaderView.Stretch)
        self.list.header().setStretchLastSection(False)
        self.list.sortByColumn(0, Qt.AscendingOrder)
        self.list.setSortingEnabled(True)

        if cues is not None:
            self.add_cues(cues)

        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.list)

        self.buttons = QDialogButtonBox(self)
        self.buttons.addButton(QDialogButtonBox.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.layout().addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
Esempio n. 15
0
    def createDockWindows(self):
        dock = QDockWidget("Available Garments Types", self)
        #dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.availableItems = QListWidget(dock)
        self.availableItems.setMinimumWidth(350)
        self.availableItems.setMaximumWidth(350)
        #self.availableItems.addItems(("stuff"))
        self.availableItems.itemClicked.connect(self.itemClicked_Click)
        dock.setWidget(self.availableItems)
        self.addDockWidget(Qt.RightDockWidgetArea, dock)
        self.viewMenu.addAction(dock.toggleViewAction())
        dock.hide()

        self.dock = QDockWidget("Available Garment Sizes", self)
        self.orderItem = QTreeWidget(dock)
        #self.orderItem.setMinimumWidth(350)
        #self.orderItem.setMaximumWidth(350)
        #self.orderItem.insertText(("more stuff"))
        self.dock.setWidget(self.orderItem)
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock)
        self.viewMenu.addAction(self.dock.toggleViewAction())
        self.dock.hide()
        
        #Create a tree widget for use when the t-shirt is clicked.
        self.treeDock = QDockWidget("Order Items", self)
        self.garmentTree = QTreeWidget(self.treeDock)
        self.garmentTree.setObjectName('garmentTree')
        self.garmentTree.itemClicked.connect(CSRWidgets.sumQuantity)
        self.garmentTree.itemClicked.connect(lambda: CSRWidgets.updateNameDesign(self))
            
        self.garmentTree.setMaximumWidth(480)
        self.garmentTree.setMinimumWidth(480)
   
        self.treeDock.hide()
Esempio n. 16
0
 def mouseReleaseEvent(self, event):
     done = False
     if (
             QApplication.mouseButtons() & Qt.LeftButton and 
             self.receivers(self.l_clicked_anywhere) > 0):
         done = True
     if (
             QApplication.mouseButtons() & Qt.MidButton and 
             self.receivers(self.m_clicked_anywhere) > 0):
         done = True
     if (
             QApplication.mouseButtons() & Qt.RightButton and 
             self.receivers(self.r_clicked_anywhere) > 0):
         done = True
     if not done:
         QTreeWidget.mouseReleaseEvent(self, event)
Esempio n. 17
0
    def __init__(self):
        super(MainWindow, self).__init__()
        self.dbm_obj = Dbm()
        self.curFile = ''
        self.textEdit = QTextEdit()
        self.sectionTreeWidget = QTreeWidget()

        self.notesListWidget = QListWidget()
        self.createHorizontalGroupBox()
        self.setCentralWidget(self.horizontalGroupBox)

        self.createActions()
        self.createMenus()
        # self.createToolBars()
        self.createStatusBar()
        self.readSettings()

        [self.hierarchy_dict, self.notebook_dict, self.section_dict, self.page_dict] = [{}, {}, {}, {}]

        self.setCurrentFile('')

        # For binding slots and signals
        self.fetchPageThread = FetchPage()
        self.fetchPageThread.setObjectName('fetchPageThread')
        self.syncAllThread = SyncAllThread()
        self.syncAllThread.setObjectName('syncAllThread')
        self.textEdit.document().contentsChanged.connect(self.documentWasModified)
        self.sectionTreeWidget.setObjectName("sectionTreeWidget")
        self.notesListWidget.setObjectName("notesListWidget")
        QMetaObject.connectSlotsByName(self)
        self.readDB()
    def __init__(self, parent, topLevelOperatorView):
        super(BookmarksWindow, self).__init__(parent)
        self.setWindowTitle("Bookmarks")
        self.topLevelOperatorView = topLevelOperatorView
        self.bookmark_tree = QTreeWidget(self)
        self.bookmark_tree.setHeaderLabels( ["Location", "Notes"] )
        self.bookmark_tree.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred )
        self.bookmark_tree.setColumnWidth(0, 200)
        self.bookmark_tree.setColumnWidth(1, 300)

        self.note_edit = QLineEdit(self)
        self.add_bookmark_button = QPushButton("Add Bookmark", self, clicked=self.add_bookmark)

        geometry = self.geometry()
        geometry.setSize( QSize(520, 520) )
        self.setGeometry(geometry)
        
        layout = QVBoxLayout()
        layout.addWidget(self.bookmark_tree)
        layout.addWidget(self.note_edit)
        layout.addWidget(self.add_bookmark_button)
        self.setLayout(layout)

        self._load_bookmarks()
        
        self.bookmark_tree.setContextMenuPolicy( Qt.CustomContextMenu )
        self.bookmark_tree.customContextMenuRequested.connect( self.showContextMenu )
        
        self.bookmark_tree.itemDoubleClicked.connect(self._handle_doubleclick)
Esempio n. 19
0
    def dropEvent(self, event: QDropEvent):
        """custom drop event to prevent reparenting
        """
        # data = event.mimeData()
        # if data.hasFormat('application/x-qabstractitemmodeldatalist'):
        #     the_bytearray = data.data('application/x-qabstractitemmodeldatalist')
        #     data_item = self.decodeMimeData(the_bytearray)
        #     print("got a drop event", data_item)

        # item Drop above
        pos = event.pos()
        dest_item = self.itemAt(pos)
        if dest_item is None:
            return
        dest_parent = dest_item.parent()
        selected_items = self.selectedItems()
        for x in selected_items:
            if x.parent() != dest_parent:
                return

        res = QTreeWidget.dropEvent(self, event)
        if isinstance(dest_item, OutlineVirtualHelixItem):
            part = dest_item.part()
            vhi_list = [dest_parent.child(i) for i in range(dest_parent.childCount())]
            part.setImportedVHelixOrder([vhi.idNum() for vhi in vhi_list], check_batch=False)
Esempio n. 20
0
 def setup_ui(self):
     self._layout = QVBoxLayout()
     self.setLayout(self._layout)
     # create layout for top line of buttons
     self._layout_topbuttons = QHBoxLayout()
     self._layout.addLayout(self._layout_topbuttons)
     # create reload button
     self._btn_reload = QPushButton(self.tr('Refresh imperium'), self)
     self._btn_reload.setIcon(QIcon(':i/reload.png'))
     self._btn_reload.clicked.connect(self.on_btn_refresh_imperium)
     self._layout_topbuttons.addWidget(self._btn_reload)
     # finalize top buttons layout
     self._layout_topbuttons.addStretch()
     # create tree
     self._tree = QTreeWidget(self)
     self._tree.setAnimated(False)
     self._tree.setExpandsOnDoubleClick(True)
     self._tree.setHeaderHidden(False)
     self._tree.setItemsExpandable(True)
     self._tree.setRootIsDecorated(True)
     self._tree.setSortingEnabled(False)
     self._tree.setColumnCount(1)
     self._tree.setHeaderLabels(['None'])
     self._layout.addWidget(self._tree)
     self._tree.show()
Esempio n. 21
0
    def __init__(self, parent=None, update=True):
        QDialog.__init__(self, parent=parent)
        layout = QVBoxLayout()
        self.tree = QTreeWidget()
        layout.addWidget(self.tree)
        self.setLayout(layout)

        self._mgr = CacheMemoryManager()

        self._tracked_caches = {}

        # tree setup code
        self.tree.setHeaderLabels(
            ["cache", "memory", "roi", "dtype", "type", "info", "id"])
        self._idIndex = self.tree.columnCount() - 1
        self.tree.setColumnHidden(self._idIndex, True)
        self.tree.setSortingEnabled(True)
        self.tree.clear()

        self._root = TreeNode()

        # refresh every x seconds (see showEvent())
        self.timer = QTimer(self)
        if update:
            self.timer.timeout.connect(self._updateReport)
Esempio n. 22
0
    def __init__(self, pathProjects, parent=None):
        #pathProjects must be a list
        super(AddToProject, self).__init__(parent)
        self.setWindowTitle(_translate("AddToProject", "Add File to Project"))
        self.pathSelected = ''
        vbox = QVBoxLayout(self)

        self._tree = QTreeWidget()
        self._tree.header().setHidden(True)
        self._tree.setSelectionMode(QTreeWidget.SingleSelection)
        self._tree.setAnimated(True)
        vbox.addWidget(self._tree)
        hbox = QHBoxLayout()
        btnAdd = QPushButton(_translate("AddToProject", "Add here!"))
        btnCancel = QPushButton(_translate("AddToProject", "Cancel"))
        hbox.addWidget(btnCancel)
        hbox.addWidget(btnAdd)
        vbox.addLayout(hbox)
        #load folders
        self._root = None
        self._loading_items = {}
        self.loading_projects(pathProjects)
        self._thread_execution = ThreadExecution(
            self._thread_load_projects, args=[pathProjects])
        self._thread_execution.finished.connect(self._callback_load_project)
        self._thread_execution.start()

        btnCancel.clicked['bool'].connect(self.close)
        btnAdd.clicked['bool'].connect(self._select_path)
Esempio n. 23
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.name = self.tr("Misc")

        self.markColorLabel = QLabel(self.tr("Default flag colors:"), self)
        # TODO: enforce duplicate names avoidance
        self.markColorWidget = QTreeWidget(self)
        self.markColorWidget.setHeaderLabels(
            (self.tr("Color"), self.tr("Name")))
        self.markColorWidget.setRootIsDecorated(False)
        self.markColorWidget.setSelectionBehavior(
            QAbstractItemView.SelectRows)
        # TODO: make this work correctly, top-level items only
        # self.markColorWidget.setDragDropMode(QAbstractItemView.InternalMove)
        self.addItemButton = QPushButton("+", self)
        self.addItemButton.clicked.connect(self.addItem)
        self.removeItemButton = QPushButton("−", self)
        self.removeItemButton.clicked.connect(self.removeItem)

        self.loadRecentFileBox = QCheckBox(
            self.tr("Load most recent file on start"), self)

        layout = QGridLayout(self)
        l = 0
        layout.addWidget(self.markColorLabel, l, 0, 1, 3)
        l += 1
        layout.addWidget(self.markColorWidget, l, 0, 1, 3)
        l += 1
        layout.addWidget(self.addItemButton, l, 0)
        layout.addWidget(self.removeItemButton, l, 1)
        l += 1
        layout.addWidget(self.loadRecentFileBox, l, 0, 1, 3)
        self.setLayout(layout)

        self.readSettings()
Esempio n. 24
0
    def __init__(self, parent, info, title):
        super().__init__(parent)

        self.setWindowTitle('Media Info - ' + title)
        self.setWindowModality(QtCore.Qt.ApplicationModal)
        self.setMinimumSize(500, 250)
        self.resize(500, 250)

        self.vLayout = QVBoxLayout(self)

        self.infoTree = QTreeWidget(self)
        self.infoTree.setColumnCount(2)
        self.infoTree.setHeaderLabels(['Scope', 'Value'])
        self.infoTree.setAlternatingRowColors(True)
        self.infoTree.setSelectionMode(QAbstractItemView.NoSelection)
        self.infoTree.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.vLayout.addWidget(self.infoTree)

        self.__generate_widgets(info)
        self.infoTree.setColumnWidth(0, 150)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
        self.vLayout.addWidget(self.buttonBox)

        self.buttonBox.rejected.connect(self.close)
Esempio n. 25
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.setMinimumSize(400, 300)

        self._cues = []

        self.list = QTreeWidget(self)
        self.list.setSelectionMode(self.list.SingleSelection)
        self.list.setSelectionBehavior(self.list.SelectRows)
        self.list.setAlternatingRowColors(True)
        self.list.setIndentation(0)
        self.list.setHeaderLabels(['Index', 'Name'])
        self.list.header().setSectionResizeMode(QHeaderView.Fixed)
        self.list.header().setSectionResizeMode(1, QHeaderView.Stretch)
        self.list.header().setStretchLastSection(False)

        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.list)

        self.buttons = QDialogButtonBox(self)
        self.buttons.addButton(QDialogButtonBox.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.layout().addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
Esempio n. 26
0
    def __init__(self, plugins):
        QTreeWidget.__init__(self)

        self.setHeaderHidden(True)
        self.itemExpanded.connect(self.handleExpanded)
        self.itemClicked.connect(self.handleClicked)

        self.context = pyblish.api.Context()

        for plugin in plugins:
            p = plugin()
            item = QTreeWidgetItem(self)
            item.setText(0, p.__class__.__name__)
            item.plugin = p
            instance = pyblish.api.Instance(p.__class__.__name__, self.context)
            item.instance = instance
            self.addItems(item)
Esempio n. 27
0
class MemUsageDialog(QDialog):
    def __init__(self, parent=None, update=True):
        QDialog.__init__(self, parent=parent)
        layout = QVBoxLayout()
        self.tree = QTreeWidget()
        layout.addWidget(self.tree)
        self.setLayout(layout)

        self._mgr = CacheMemoryManager()

        self._tracked_caches = {}

        # tree setup code
        self.tree.setHeaderLabels(
            ["cache", "memory", "roi", "dtype", "type", "info", "id"])
        self._idIndex = self.tree.columnCount() - 1
        self.tree.setColumnHidden(self._idIndex, True)
        self.tree.setSortingEnabled(True)
        self.tree.clear()

        self._root = TreeNode()

        # refresh every x seconds (see showEvent())
        self.timer = QTimer(self)
        if update:
            self.timer.timeout.connect(self._updateReport)

    def _updateReport(self):
        # we keep track of dirty reports so we just have to update the tree
        # instead of reconstructing it
        reports = []
        for c in self._mgr.getFirstClassCaches():
            r = MemInfoNode()
            c.generateReport(r)
            reports.append(r)
        self._root.handleChildrenReports(
            reports, root=self.tree.invisibleRootItem())

    def hideEvent(self, event):
        self.timer.stop()

    def showEvent(self, show):
        # update once so we don't have to wait for initial report
        self._updateReport()
        # update every 5 sec.
        self.timer.start(5*1000)
Esempio n. 28
0
    def get_variable_table(self, context):
        context_key = context.replace(' ', '-').lower()

        if context_key in self.variable_tables:
            table = self.variable_tables[context_key]
        else:
            table = QTreeWidget()
            table.setColumnCount(3)
            table.setHeaderLabels(['Name', 'Type', 'Value'])
            table.setColumnWidth(0, 250)
            table.setColumnWidth(1, 150)

            self.variable_tables[context_key] = table

            if context == 'Locals':
                self.insertTab(0, table, context)
            else:
                self.addTab(table, context)

            table.itemDoubleClicked.connect(
                self.handle_variable_double_clicked
            )

            self.setCurrentIndex(0)

        return table
Esempio n. 29
0
 def __init__(self, parent=None):
     super().__init__(parent)
     IDE.register_service("errors_tree", self)
     box = QVBoxLayout(self)
     box.setContentsMargins(0, 0, 0, 0)
     self._tree = QTreeWidget()
     self._tree.header().setHidden(True)
     self._tree.setAnimated(True)
     box.addWidget(self._tree)
Esempio n. 30
0
 def initialize_lexicon_tree(self):
     self.lexicon_tree = QTreeWidget()
     self.lexicon_tree.setEnabled(True)
     self.lexicon_tree.setMinimumWidth(TREEWIDGET_WIDTH_MIN)
     self.lexicon_tree.setMaximumWidth(TREEWIDGET_WIDTH_MAX)
     self.lexicon_tree.setMinimumHeight(TREEWIDGET_HEIGHT_MIN)
     self.lexicon_tree.setHeaderLabel('')
     self.lexicon_tree.setItemsExpandable(True)
     # noinspection PyUnresolvedReferences
     self.lexicon_tree.itemClicked.connect(self.tree_item_clicked)
Esempio n. 31
0
class FileReaderPanel(ToolInstance):
    SESSION_ENDURING = False
    SESSION_SAVE = False
    help = "https://github.com/QChASM/SEQCROW/wiki/Model-Manager-Tool"

    NAME_COL = 0
    ID_COL = 1
    COORDSETS_COL = 2
    NRG_COL = 3
    FREQ_COL = 4

    def __init__(self, session, name):
        super().__init__(session, name)

        self.display_name = "SEQCROW Models"

        self.tool_window = MainToolWindow(self)

        self._build_ui()
        self.fill_tree()

        self._fr_change = self.session.filereader_manager.triggers.add_handler(
            FILEREADER_CHANGE, lambda *args: self.fill_tree(*args))
        self._add_models = self.session.triggers.add_handler(
            ADD_MODELS, lambda *args: self.fill_tree(*args))
        self._molid_change = self.session.triggers.add_handler(
            MODEL_ID_CHANGED, lambda *args: self.fill_tree(*args))
        self._molname_change = self.session.triggers.add_handler(
            MODEL_NAME_CHANGED, lambda *args: self.fill_tree(*args))

    def _build_ui(self):
        layout = QGridLayout()

        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        #TODO: make buttons disabled/enabled if items are selected that don't have the info
        self.tree = QTreeWidget()
        self.tree.setSelectionMode(QTreeWidget.ExtendedSelection)
        self.tree.setHeaderLabels(
            ["Name", "ID", "movie", "energy", "frequencies"])
        self.tree.setUniformRowHeights(True)

        self.tree.setColumnWidth(self.NAME_COL, 200)
        layout.addWidget(self.tree, 0, 0, 3, 1)

        restore_button = QPushButton("restore")
        restore_button.clicked.connect(self.restore_selected)
        layout.addWidget(restore_button, 0, 1)

        nrg_plot_button = QPushButton("energy plot")
        nrg_plot_button.clicked.connect(self.open_nrg_plot)
        layout.addWidget(nrg_plot_button, 1, 1)

        coordset_slider_button = QPushButton("movie slider")
        coordset_slider_button.clicked.connect(self.open_movie_slider)
        layout.addWidget(coordset_slider_button, 2, 1)

        self.tool_window.ui_area.setLayout(layout)

        self.tool_window.manage(placement="side")

    def fill_tree(self, *args):
        item_stack = [self.tree.invisibleRootItem()]

        self.tree.clear()
        self._items = []

        fr_dict = self.session.filereader_manager.filereader_dict

        for model in fr_dict.keys():
            id = model.id
            if id is None:
                continue

            name = model.name
            parent = item_stack[0]
            item = QTreeWidgetItem(parent)
            item._model = model
            item_stack.append(item)
            self._items.append(item)

            item.setData(self.NAME_COL, Qt.DisplayRole, model)
            item.setText(self.NAME_COL, name)
            item.setText(self.ID_COL, ".".join([str(x) for x in id]))

            if any(x.all_geom is not None and len(x.all_geom) > 1
                   for x in fr_dict[model]):
                item.setText(self.COORDSETS_COL, "yes")
            else:
                item.setText(self.COORDSETS_COL, "no")

            if any("energy" in x.other for x in fr_dict[model]):
                item.setText(self.NRG_COL, "yes")
            else:
                item.setText(self.NRG_COL, "no")

            if any("frequency" in x.other for x in fr_dict[model]):
                item.setText(self.FREQ_COL, "yes")
            else:
                item.setText(self.FREQ_COL, "no")

            for fr in fr_dict[model]:
                child = QTreeWidgetItem(item)
                child.setData(self.NAME_COL, Qt.DisplayRole, fr)
                child.setText(self.NAME_COL, fr.name)
                if fr.all_geom is not None and len(fr.all_geom) > 1:
                    child.setText(self.COORDSETS_COL, "yes")
                else:
                    child.setText(self.COORDSETS_COL, "no")

                if "energy" in fr.other:
                    child.setText(self.NRG_COL, "%.6f" % fr.other["energy"])
                else:
                    child.setText(self.NRG_COL, "")

                if "frequency" in fr.other:
                    child.setText(self.FREQ_COL, "yes")
                else:
                    child.setText(self.FREQ_COL, "no")

            #self.tree.expandItem(item)

        for i in [
                self.ID_COL, self.COORDSETS_COL, self.NRG_COL, self.FREQ_COL
        ]:
            self.tree.resizeColumnToContents(i)

    def restore_selected(self):
        items = [item for item in self.tree.selectedItems()]
        model_dict = self.session.filereader_manager.filereader_dict
        models = list(model_dict.keys())
        for item in items:
            parent = item.parent()
            mdl = models[self.tree.indexOfTopLevelItem(parent)]
            if parent is None:
                fr = model_dict[mdl][-1]
            else:
                fr = model_dict[mdl][parent.indexOfChild(item)]

            fr_rescol = ResidueCollection(fr)
            fr_rescol.update_chix(mdl)
            if fr.all_geom is not None and len(fr.all_geom) > 1:
                coordsets = fr_rescol.all_geom_coordsets(fr)

                mdl.remove_coordsets()
                mdl.add_coordsets(coordsets)

                for i, coordset in enumerate(coordsets):
                    mdl.active_coordset_id = i + 1

                    for atom, coord in zip(mdl.atoms, coordset):
                        atom.coord = coord

                mdl.active_coordset_id = 1

    def open_nrg_plot(self):
        items = [item for item in self.tree.selectedItems()]
        model_dict = self.session.filereader_manager.filereader_dict
        models = list(model_dict.keys())
        for item in items:
            parent = item.parent()
            mdl = models[self.tree.indexOfTopLevelItem(parent)]
            if parent is None:
                fr = model_dict[mdl][-1]
            else:
                fr = model_dict[mdl][parent.indexOfChild(item)]

            EnergyPlot(self.session, mdl, fr)

    def open_movie_slider(self):
        items = [item for item in self.tree.selectedItems()]
        model_dict = self.session.filereader_manager.filereader_dict
        models = list(model_dict.keys())
        for item in items:
            parent = item.parent()
            mdl = models[self.tree.indexOfTopLevelItem(parent)]
            #coordset doesn't start out with the current coordset id
            #it looks like it should, but it doesn't
            #it starts at 1 instead
            slider = CoordinateSetSlider(self.session, mdl)
            slider.set_slider(mdl.active_coordset_id)
            #run(self.session, "coordset slider %s" % mdl.atomspec)

    def display_help(self):
        """Show the help for this tool in the help viewer."""
        from chimerax.core.commands import run
        run(self.session,
            'open %s' % self.help if self.help is not None else "")

    def delete(self):
        """overload delete"""
        self.session.filereader_manager.triggers.remove_handler(
            self._fr_change)
        self.session.triggers.remove_handler(self._add_models)
        self.session.triggers.remove_handler(self._molid_change)
        self.session.triggers.remove_handler(self._molname_change)
        super().delete()

    def close(self):
        """overload close"""
        self.session.filereader_manager.triggers.remove_handler(
            self._fr_change)
        self.session.triggers.remove_handler(self._add_models)
        self.session.triggers.remove_handler(self._molid_change)
        self.session.triggers.remove_handler(self._molname_change)
        super().close()
Esempio n. 32
0
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)
        
        #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 type'
                            ]
            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.tree.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
            #self.tree.header().setStretchLastSection(False)
            return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        i=0
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            self.rect_item = QTreeWidgetItem(self.root)

            for col in range(0,4):
            self.rect_params = [self.waterfall_data['Patient number'][i], rect.get_height()]

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
 def keyPressEvent(self, event):
     if event.key() in [Qt.Key_F2, Qt.Key_Return]:
         self.on_activated(self.currentItem(), self.currentColumn())
     else:
         QTreeWidget.keyPressEvent(self, event)
    def __init__(self, theParent, theProject):
        QWidget.__init__(self, theParent)

        self.mainConf = nw.CONFIG
        self.theParent = theParent
        self.theProject = theProject
        self.theTheme = theParent.theTheme
        self.theIndex = theParent.theIndex
        self.optState = theProject.optState

        # Internal
        self._theToC = []

        iPx = self.theTheme.baseIconSize
        hPx = self.mainConf.pxInt(12)
        vPx = self.mainConf.pxInt(4)

        # Contents Tree
        # =============

        self.tocTree = QTreeWidget()
        self.tocTree.setIconSize(QSize(iPx, iPx))
        self.tocTree.setIndentation(0)
        self.tocTree.setColumnCount(6)
        self.tocTree.setSelectionMode(QAbstractItemView.NoSelection)
        self.tocTree.setHeaderLabels(
            ["Title", "Words", "Pages", "Page", "Progress", ""])

        treeHeadItem = self.tocTree.headerItem()
        treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignRight)

        treeHeader = self.tocTree.header()
        treeHeader.setStretchLastSection(True)
        treeHeader.setMinimumSectionSize(hPx)

        wCol0 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol0", 200))
        wCol1 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol1", 60))
        wCol2 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol2", 60))
        wCol3 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol3", 60))
        wCol4 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol4", 90))

        self.tocTree.setColumnWidth(0, wCol0)
        self.tocTree.setColumnWidth(1, wCol1)
        self.tocTree.setColumnWidth(2, wCol2)
        self.tocTree.setColumnWidth(3, wCol3)
        self.tocTree.setColumnWidth(4, wCol4)
        self.tocTree.setColumnWidth(5, hPx)

        # Options
        # =======

        wordsPerPage = self.optState.getInt("GuiProjectDetails",
                                            "wordsPerPage", 350)
        countFrom = self.optState.getInt("GuiProjectDetails", "countFrom", 1)
        clearDouble = self.optState.getInt("GuiProjectDetails", "clearDouble",
                                           True)

        wordsHelp = (
            "Typical word count for a 5 by 8 inch book page with 11 pt font is 350."
        )
        offsetHelp = ("Start counting page numbers from this page.")
        dblHelp = (
            "Assume a new chapter or partition always start on an odd numbered page."
        )

        self.wpLabel = QLabel("Words per page")
        self.wpLabel.setToolTip(wordsHelp)

        self.wpValue = QSpinBox()
        self.wpValue.setMinimum(10)
        self.wpValue.setMaximum(1000)
        self.wpValue.setSingleStep(10)
        self.wpValue.setValue(wordsPerPage)
        self.wpValue.setToolTip(wordsHelp)
        self.wpValue.valueChanged.connect(self._populateTree)

        self.poLabel = QLabel("Count pages from")
        self.poLabel.setToolTip(offsetHelp)

        self.poValue = QSpinBox()
        self.poValue.setMinimum(1)
        self.poValue.setMaximum(9999)
        self.poValue.setSingleStep(1)
        self.poValue.setValue(countFrom)
        self.poValue.setToolTip(offsetHelp)
        self.poValue.valueChanged.connect(self._populateTree)

        self.dblLabel = QLabel("Clear double pages")
        self.dblLabel.setToolTip(dblHelp)

        self.dblValue = QSwitch(self, 2 * iPx, iPx)
        self.dblValue.setChecked(clearDouble)
        self.dblValue.setToolTip(dblHelp)
        self.dblValue.clicked.connect(self._populateTree)

        self.optionsBox = QGridLayout()
        self.optionsBox.addWidget(self.wpLabel, 0, 0)
        self.optionsBox.addWidget(self.wpValue, 0, 1)
        self.optionsBox.addWidget(self.dblLabel, 0, 3)
        self.optionsBox.addWidget(self.dblValue, 0, 4)
        self.optionsBox.addWidget(self.poLabel, 1, 0)
        self.optionsBox.addWidget(self.poValue, 1, 1)
        self.optionsBox.setHorizontalSpacing(hPx)
        self.optionsBox.setVerticalSpacing(vPx)
        self.optionsBox.setColumnStretch(2, 1)

        # Assemble
        # ========

        self.outerBox = QVBoxLayout()
        self.outerBox.addWidget(QLabel("<b>Table of Contents</b>"))
        self.outerBox.addWidget(self.tocTree)
        self.outerBox.addLayout(self.optionsBox)

        self.setLayout(self.outerBox)

        self._prepareData()
        self._populateTree()

        return
class GuiProjectDetailsContents(QWidget):

    C_TITLE = 0
    C_WORDS = 1
    C_PAGES = 2
    C_PAGE = 3
    C_PROG = 4

    def __init__(self, theParent, theProject):
        QWidget.__init__(self, theParent)

        self.mainConf = nw.CONFIG
        self.theParent = theParent
        self.theProject = theProject
        self.theTheme = theParent.theTheme
        self.theIndex = theParent.theIndex
        self.optState = theProject.optState

        # Internal
        self._theToC = []

        iPx = self.theTheme.baseIconSize
        hPx = self.mainConf.pxInt(12)
        vPx = self.mainConf.pxInt(4)

        # Contents Tree
        # =============

        self.tocTree = QTreeWidget()
        self.tocTree.setIconSize(QSize(iPx, iPx))
        self.tocTree.setIndentation(0)
        self.tocTree.setColumnCount(6)
        self.tocTree.setSelectionMode(QAbstractItemView.NoSelection)
        self.tocTree.setHeaderLabels(
            ["Title", "Words", "Pages", "Page", "Progress", ""])

        treeHeadItem = self.tocTree.headerItem()
        treeHeadItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
        treeHeadItem.setTextAlignment(self.C_PROG, Qt.AlignRight)

        treeHeader = self.tocTree.header()
        treeHeader.setStretchLastSection(True)
        treeHeader.setMinimumSectionSize(hPx)

        wCol0 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol0", 200))
        wCol1 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol1", 60))
        wCol2 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol2", 60))
        wCol3 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol3", 60))
        wCol4 = self.mainConf.pxInt(
            self.optState.getInt("GuiProjectDetails", "widthCol4", 90))

        self.tocTree.setColumnWidth(0, wCol0)
        self.tocTree.setColumnWidth(1, wCol1)
        self.tocTree.setColumnWidth(2, wCol2)
        self.tocTree.setColumnWidth(3, wCol3)
        self.tocTree.setColumnWidth(4, wCol4)
        self.tocTree.setColumnWidth(5, hPx)

        # Options
        # =======

        wordsPerPage = self.optState.getInt("GuiProjectDetails",
                                            "wordsPerPage", 350)
        countFrom = self.optState.getInt("GuiProjectDetails", "countFrom", 1)
        clearDouble = self.optState.getInt("GuiProjectDetails", "clearDouble",
                                           True)

        wordsHelp = (
            "Typical word count for a 5 by 8 inch book page with 11 pt font is 350."
        )
        offsetHelp = ("Start counting page numbers from this page.")
        dblHelp = (
            "Assume a new chapter or partition always start on an odd numbered page."
        )

        self.wpLabel = QLabel("Words per page")
        self.wpLabel.setToolTip(wordsHelp)

        self.wpValue = QSpinBox()
        self.wpValue.setMinimum(10)
        self.wpValue.setMaximum(1000)
        self.wpValue.setSingleStep(10)
        self.wpValue.setValue(wordsPerPage)
        self.wpValue.setToolTip(wordsHelp)
        self.wpValue.valueChanged.connect(self._populateTree)

        self.poLabel = QLabel("Count pages from")
        self.poLabel.setToolTip(offsetHelp)

        self.poValue = QSpinBox()
        self.poValue.setMinimum(1)
        self.poValue.setMaximum(9999)
        self.poValue.setSingleStep(1)
        self.poValue.setValue(countFrom)
        self.poValue.setToolTip(offsetHelp)
        self.poValue.valueChanged.connect(self._populateTree)

        self.dblLabel = QLabel("Clear double pages")
        self.dblLabel.setToolTip(dblHelp)

        self.dblValue = QSwitch(self, 2 * iPx, iPx)
        self.dblValue.setChecked(clearDouble)
        self.dblValue.setToolTip(dblHelp)
        self.dblValue.clicked.connect(self._populateTree)

        self.optionsBox = QGridLayout()
        self.optionsBox.addWidget(self.wpLabel, 0, 0)
        self.optionsBox.addWidget(self.wpValue, 0, 1)
        self.optionsBox.addWidget(self.dblLabel, 0, 3)
        self.optionsBox.addWidget(self.dblValue, 0, 4)
        self.optionsBox.addWidget(self.poLabel, 1, 0)
        self.optionsBox.addWidget(self.poValue, 1, 1)
        self.optionsBox.setHorizontalSpacing(hPx)
        self.optionsBox.setVerticalSpacing(vPx)
        self.optionsBox.setColumnStretch(2, 1)

        # Assemble
        # ========

        self.outerBox = QVBoxLayout()
        self.outerBox.addWidget(QLabel("<b>Table of Contents</b>"))
        self.outerBox.addWidget(self.tocTree)
        self.outerBox.addLayout(self.optionsBox)

        self.setLayout(self.outerBox)

        self._prepareData()
        self._populateTree()

        return

    def getColumnSizes(self):
        """Return the column widths for the tree columns.
        """
        retVals = [
            self.tocTree.columnWidth(0),
            self.tocTree.columnWidth(1),
            self.tocTree.columnWidth(2),
            self.tocTree.columnWidth(3),
            self.tocTree.columnWidth(4),
        ]
        return retVals

    ##
    #  Internal Functions
    ##

    def _prepareData(self):
        """Extract the data for the tree.
        """
        self._theToC = []
        self._theToC = self.theIndex.getTableOfContents(2)
        self._theToC.append(("", 0, "END", 0))
        return

    ##
    #  Slots
    ##

    def _populateTree(self):
        """Set the content of the chapter/page tree.
        """
        dblPages = self.dblValue.isChecked()
        wpPage = self.wpValue.value()
        fstPage = self.poValue.value() - 1

        pTotal = 0
        tPages = 1

        theList = []
        for _, tLevel, tTitle, wCount in self._theToC:
            pCount = math.ceil(wCount / wpPage)
            if dblPages:
                pCount += pCount % 2

            pTotal += pCount
            theList.append((tLevel, tTitle, wCount, pCount))

        pMax = pTotal - fstPage

        self.tocTree.clear()
        for tLevel, tTitle, wCount, pCount in theList:
            newItem = QTreeWidgetItem()

            if tPages <= fstPage:
                progPage = numberToRoman(tPages, True)
                progText = ""
            else:
                cPage = tPages - fstPage
                pgProg = 100.0 * (cPage - 1) / pMax if pMax > 0 else 0.0
                progPage = f"{cPage:n}"
                progText = f"{pgProg:.1f}{nwUnicode.U_THSP}%"

            newItem.setIcon(self.C_TITLE,
                            self.theTheme.getIcon("doc_h%d" % tLevel))
            newItem.setText(self.C_TITLE, tTitle)
            newItem.setText(self.C_WORDS, f"{wCount:n}")
            newItem.setText(self.C_PAGES, f"{pCount:n}")
            newItem.setText(self.C_PAGE, progPage)
            newItem.setText(self.C_PROG, progText)

            newItem.setTextAlignment(self.C_WORDS, Qt.AlignRight)
            newItem.setTextAlignment(self.C_PAGES, Qt.AlignRight)
            newItem.setTextAlignment(self.C_PAGE, Qt.AlignRight)
            newItem.setTextAlignment(self.C_PROG, Qt.AlignRight)

            # Make pages and titles/partitions stand out
            if tLevel < 2:
                bFont = newItem.font(self.C_TITLE)
                if tLevel == 0:
                    bFont.setItalic(True)
                else:
                    bFont.setBold(True)
                    bFont.setUnderline(True)
                newItem.setFont(self.C_TITLE, bFont)

            tPages += pCount

            self.tocTree.addTopLevelItem(newItem)

        return
Esempio n. 36
0
class SimpleWindow(OpenGLWindow):
    def __init__(self, format=DEFAULT_FORMAT, size=(700, 700)):
        super(SimpleWindow, self).__init__()

        self.setFormat(format)
        self.resize(*size)

        self.m_program = None
        self.m_frame = 0
        self.buffer = None
        # self.scene = scene
        # scene.window = self
        self.layers = []

        # background color
        self.clearcolor = (1, 1, 1, 1)

        # model paramenters
        self.m_translation = np.zeros(3, dtype=np.float32)

        # view parameters
        self.v_scale = 0.1
        self.v_cam_distance = 2
        self.v_translation = np.zeros(3, dtype=np.float32)
        self.v_rotation = q.quaternion()

        # projection parameters
        self.p_nclip = 0.1
        self.p_fclip = 100
        self.p_fov = 60
        self.p_ratio = 4.0 / 3.0

        self.last_mouse_pos = None

        # self.disableCentering = False

        self.layerWidget = QTreeWidget()
        self.layerWidget.headerItem().setHidden(True)
        self.layerWidget.setSelectionMode(QAbstractItemView.MultiSelection)
        self.layerWidget.itemClicked.connect(self.updateLayerVisibility)

        # self.layerDockWidget.show()

    def updateLayerVisibility(self, item, col):
        selected_names = [
            item.text(0) for item in self.layerWidget.selectedItems()
        ]
        for layer in self.layers:
            layer.is_visible = layer.name() in selected_names
            for painter in layer.painters:
                painter.is_visible = painter.name() in selected_names
        self.renderLater()

    def setBBox(self, bbox):
        self.bbox = bbox

    def setLayer(self, layer):
        assert (type(layer) is Layer)

        if layer in self.layers:
            self.unsetLayer(layer)

        self.layers.append(layer)
        item = QTreeWidgetItem([layer.name()], 0)
        layer.tree_item = item
        self.layerWidget.addTopLevelItem(item)
        item.setSelected(layer.is_visible)
        for painter in layer.painters:
            child_item = QTreeWidgetItem([painter.name()], 0)
            item.addChild(child_item)
            child_item.setSelected(painter.is_visible)
        self.layerWidget.expandItem(item)

    def unsetLayer(self, layer):
        self.layerWidget.blockSignals(True)
        index = self.layerWidget.indexOfTopLevelItem(layer.tree_item)
        self.layerWidget.takeTopLevelItem(index)
        self.layerWidget.blockSignals(False)
        try:
            self.layers.remove(layer)
        except KeyError:
            print('attemped to delete crap that doesnt exist')
            pass

    # def clearLayers(self):
    #     self.layerWidget.clear()

    def initialise(self):
        self.crosshair_painter = crosshairPainter()
        gl.glClearColor(*self.clearcolor)
        gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
        gl.glDepthMask(gl.GL_TRUE)
        gl.glEnable(gl.GL_DEPTH_TEST)
        gl.glDepthFunc(gl.GL_LESS)
        # gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        # gl.glEnable(gl.GL_BLEND)
        print(gl.glGetIntegerv(gl.GL_MAX_VIEWPORT_DIMS))
        self.center()
        self.renderLater()

    def center(self, bbox=None):
        # if not self.disableCentering:
        if bbox is None:
            self.v_scale = 0.1
            self.v_translation = np.zeros(3)
        elif bbox.is_empty:
            self.v_scale = 0.1
            self.v_translation = np.zeros(3)
        else:
            w, h = self.width(), self.height()
            mi = min(w, h)
            self.v_scale = .8 * 2 * min((w / mi) / bbox.width[0],
                                        (h / mi) / bbox.width[1])
            self.v_translation = -bbox.center

    def setClearColor(self, color):
        self.clearcolor = color

    def render(self):
        # if self.scene.is_changed:
        #     self.center(self.scene.bbox)
        #     self.scene.is_changed = False

        gl.glViewport(0, 0, self.width(), self.height())

        gl.glClearColor(*self.clearcolor)

        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        bits = 0
        bits |= gl.GL_COLOR_BUFFER_BIT
        bits |= gl.GL_DEPTH_BUFFER_BIT
        bits |= gl.GL_STENCIL_BUFFER_BIT
        gl.glClear(bits)

        for layer in self.layers:
            if layer.is_visible:
                for painter in layer.painters:
                    if painter.is_visible:
                        painter.render(view=self)
        if self.crosshair_painter.is_visible:
            self.crosshair_painter.render()

        self.m_frame += 1

    def screen2view(self, x, y):
        w, h = self.width(), self.height()
        r = 2 * self.radius
        return (x - w / 2.) / r, ((h - y) - h / 2.) / r

    @property
    def radius(self):
        return 0.5 * min(self.width(), self.height())

    @property
    def mat_view(self):
        mat = np.eye(4, dtype=np.float32)
        translate(mat, *self.v_translation)
        scale(mat, self.v_scale, self.v_scale, self.v_scale)
        mat = mat.dot(np.array(q.matrix(self.v_rotation), dtype=np.float32))
        translate(mat, 0, 0, -self.v_cam_distance)
        return mat

    @property
    def mat_model(self):
        return translate(np.eye(4, dtype=np.float32), *self.m_translation)

    @property
    def mat_projection(self):
        return perspective(self.p_fov, self.p_ratio, self.p_nclip,
                           self.p_fclip)

    def computeMVPMatrix(self):
        mvp_matrix = np.eye(4, dtype=np.float32)
        # model
        translate(mvp_matrix, *self.m_translation)
        # view
        mvp_matrix = mvp_matrix.dot(self.mat_view)
        # projection
        projection = perspective(self.p_fov, self.p_ratio, self.p_nclip,
                                 self.p_fclip)
        return mvp_matrix.dot(projection)

    def resizeEvent(self, event):
        size = event.size()
        self.p_ratio = size.width() / size.height()
        self.renderNow()

    def wheelEvent(self, event):
        modifiers = event.modifiers()
        ticks = float(event.angleDelta().y() + event.angleDelta().x()) / 50
        if modifiers == Qt.ShiftModifier:
            # if self.projection_mode == 'perspective':
            old_fov = self.p_fov
            # do `dolly zooming` so that world appears at same size after canging fov
            self.p_fov = max(5., self.p_fov + ticks)
            self.p_fov = min(120., self.p_fov)
            self.v_cam_distance = self.v_cam_distance * (math.tan(
                math.radians(old_fov) / 2.)) / (math.tan(
                    math.radians(self.p_fov) / 2.))
        else:
            self.v_scale *= (ticks / 30 + 1.)
            self.v_scale = max(1E-3, self.v_scale)
            self.v_scale = min(1E3, self.v_scale)
        self.renderNow()

    def mouseMoveEvent(self, event):
        modifiers = event.modifiers()
        buttons = event.buttons()
        pos_x, pos_y = event.x(), event.y()

        if self.last_mouse_pos is None:
            self.last_mouse_pos = pos_x, pos_y

        if Qt.ShiftModifier == modifiers:
            x0, y0 = self.last_mouse_pos
            x1, y1 = pos_x, pos_y
            dx, dy = (x1 - x0), (y1 - y0)
            #scale to zero plane in projection frustrum
            scale = self.v_cam_distance * math.tan(
                math.radians(self.p_fov / 2.))
            dx, dy = scale * dx, scale * dy
            r = self.radius
            #multiply with inverse view matrix and apply translation in world coordinates
            self.v_translation += np.array([dx / r, -dy / r, 0., 0.]).dot(
                np.linalg.inv(self.mat_view))[:3]
            self.crosshair_painter.is_visible = True
        elif Qt.LeftButton == buttons:
            x0, y0 = self.screen2view(*self.last_mouse_pos)
            x1, y1 = self.screen2view(pos_x, pos_y)

            v0 = q.arcball(x0, y0)
            v1 = q.arcball(x1, y1)

            self.v_rotation = q.product(v1, v0, self.v_rotation)
            self.crosshair_painter.is_visible = True
        else:
            self.crosshair_painter.is_visible = False

        self.last_mouse_pos = pos_x, pos_y
        self.renderNow()

    def keyPressEvent(self, event):
        key = event.key()
        repeat = event.isAutoRepeat()
        if key == Qt.Key_T:
            self.v_rotation = q.quaternion()
        elif key == Qt.Key_U:
            if hasattr(self, 'bbox'):
                self.center(self.bbox)
        self.renderNow()
class CollapsibleDialog(QDialog):
    #
    #A Dialog to which collapsible sections can be added;
    #
    def __init__(self):
        super().__init__()
        self.tree=QTreeWidget()
        self.tree.setHeaderHidden(True)
        layout=QVBoxLayout()
        layout.addWidget(self.tree)
        self.setLayout(layout)
        self.tree.setIndentation(0)
        self.infoWidth=self.tree.size().width()
        self.sections=[]
        self.define_sections()
        self.add_sections()

    def add_sections(self):
        #adds a collapsible sections for every 
        #(title, widget) tuple in self.sections
        #
        for (title, widget) in self.sections:
            button1 = self.add_button(title)
            section1 = self.add_widget(button1, widget)
            #section1.setFlags(section1.flags() & ~Qt.ItemIsSelectable)#deactivate label being selectable
            #section1.setFlags(section1.flags() & ~Qt.ItemIsEnabled)
            #section1.setFlags(section1.flags() & Qt.NoFocus)
            #section1.setFlags(section1 & QAbstractItemView.NoFocus)
            section1.setSelected(False)
            section1.setSelected(True)
            section1.setSelected(False)
            button1.addChild(section1)

    def define_sections(self):
        #reimplement this to define all your sections
        #and add them as (title, widget) tuples to self.sections
        #
        style =QLabel().setStyleSheet("font: 15pt Tw Cen MT")
        
        #    self.labelText = QLabel(self)
        widget = QFrame(self.tree)
        layout = QVBoxLayout(widget)
        
        infoD=QLabel(self)
        
        infoD.setStyleSheet("font: 15pt Tw Cen MT")
        infoD.setText("Data can be manually entered into a table or uploaded from a CSV File.\n"
                                "[MANUAL INPUT]\n"
                                "Format for table.")
        #                       "The first row will be for Headers\n"
        #                       "The first column will be for Headers\n"
        #                       "It should be numerical input only.\n"
        #                       "The rest of the capabilities will be dependent upon \nthe type of data you entered\n"
        #                       "(ordinal, interval, or frequency).\n\n")
        infoD2=QLabel(self)
        infoD2.setStyleSheet("font: 15pt Tw Cen MT")
        infoD2.setText(        "[Data]"
                               "\nChoice to Submit Everything\n"
                                "Specify certain rows and columns to perform analyses on.\n"
                                "NOTE: First ROW & COLUMN of Numercial DATA are ROW 1 & COL 1 before Submit\n"
                               "NOTE: ONE column for Statistical Test | TWO columns for Regression Test\n"
                               "\n[Type]\n"
                               "Please specify if Data is Interval, Ordinal, or Frequency.\n\n"
                               "[Buttons]\n"
                               "Import CSV: Use a CSV file that already exist.\n"
                               "Clear Table: Remove the data completely from table.\n"
                               "Submit Data: Pass the data you plan to use for analysis.")
        # titleD=QLabel(self)
        # titleD.setStyleSheet("font 20pt Tw Cen MT")
        # titleD.setText("DataTab")
        
        self.pixmap=QPixmap(os.path.join(Path(os.path.dirname(os.path.abspath(__file__)),"ManualInputFormat.png")))
        self.pixmap2=self.pixmap.scaled(self.infoWidth*.70,self.infoWidth*.50)
        pic=QLabel(self)
        pic.setPixmap(self.pixmap2)

        layout.addWidget(infoD)
        layout.addWidget(pic)
        layout.addWidget(infoD2)
        title = "DataTab"
        self.sections.append((title, widget))


        widget = QFrame(self.tree)
        layout = QVBoxLayout(widget)
        infoG=QLabel(self)
        infoG.setStyleSheet("font: 15pt Tw Cen MT")
        infoG.setText("The graph will be selectable by the user for display.\n\n"
                               "[Selection]\n"
                               "Vertical Bar\n"
                               "Horizontal Bar\n"
                               "Pie Chart\n"
                                "Normal Distribution Curve\n"
                                "Scatter Plot\n\n"
                                "[Buttons]\n"
                                "Graph: Proceeds to graph data based on graph selection\n"
                                "Save as PNG: To save the graph generated as PNG")

        layout.addWidget(infoG)
        title = "GraphTab"
        self.sections.append((title, widget))

        #"[Interval Data Test]\n"
        #"Mean, Median, Mode, Standard Deviation, Least Square Line, X^2 (Chi Square),\n"
        #"Correlation Coefficient, Sign Test, Rank Sum Test, and Spearman Rank Correlation.\n\n"
        #"[Ordinal Data Test]\n"
        #"Mean, Median, Mode, Standard Deviation, Least Square Line, X^2 (Chi Square),\n"
        #"Correlation Coefficient, Sign Test, Rank Sum Test, and Spearman Rank Correlation.\n\n"
        #"[Frequency Data Test]\n"
        #"Mean, Median, Mode, Standard Deviation, Least Square Line, X^2 (Chi Square),\n"
        #"Correlation Coefficient, Sign Test, Rank Sum Test, and Spearman Rank Correlation.\n\n"    
                               
        widget = QFrame(self.tree)
        layout = QVBoxLayout(widget)
        infoA=QLabel(self)
        infoA.setStyleSheet("font: 15pt Tw Cen MT")
        infoA.setText("Apply Statistical Analysis if it is meaningful for the type of data.\n"
                                "May select more than one statistical test for any specified set of data.\n"
                                "The following statistical analyses on your data:\n\n"
                                "Reminder:\n"
                                "[Statisical Test] ONE Column-\n" 
                                "Max, Min, Range, Mean, Median, Mode, Variance, STD Deviation, Coefficient of Variance,\nZScore\n"  
                                "[Regression Test] TWO Column-\n"
                                "Pearson Regression, Linear, Normal Distribution, Sign Test, Spearman Rank Correlation\nCoefficient\n")

       
        infoA2 = QLabel(self)
        infoA2.setStyleSheet("font: 15pt Tw Cen MT")
        infoA2.setText("\n[Analyze]\n"
                                "Proceed to apply the Statistical Analysis that would be applied.")
       #picture of a table with test that apply for the type of data
        
        # self.pixmap=QPixmap(os.path.join(Path(os.path.dirname(os.path.abspath(__file__)),"TableTest.JPG")))
        # self.pixmap2=self.pixmap.scaled(self.infoWidth*.70,self.infoWidth*.50)
        # pic=QLabel(self)
        # pic.setPixmap(self.pixmap2)
        
        
        layout.addWidget(infoA)
        # layout.addWidget(pic)
        layout.addWidget(infoA2)
        
        title = "AnalysisTab"
        self.sections.append((title, widget))
        
        widget = QFrame(self.tree)
        layout = QVBoxLayout(widget)
        infoS=QLabel(self)
        infoS.setStyleSheet("font: 15pt Tw Cen MT")
        infoS.setText("See a summary of all the results of all \nStatistical Analysis you did to your data.\n\n"
                        "[Options]\n"
                        "Save CSV File: User to save the Summary Report as CSV file.\n"   
                        "Save Text File: User to save the Summary Report as text file.\n"
                        "Clear: User to clear the Summary Report Log.")
        layout.addWidget(infoS)
        title = "SummaryTab"
        self.sections.append((title, widget))

    def add_button(self, title):
        #creates a QTreeWidgetItem containing a button 
        #to expand or collapse its section
        #
        item = QTreeWidgetItem()
        self.tree.addTopLevelItem(item)
        self.tree.setItemWidget(item, 0, LabelExpandButton(item, text = title))
        return item

    def add_widget(self, button, widget):
        #creates a QWidgetItem containing the widget,
        #as child of the button-QWidgetItem
        #
        section = QTreeWidgetItem(button)
        section.setDisabled(False)
        #section.setFlags(section.flags() & ~Qt.ItemIsSelectable)
        #section.setFlags(section.flags() & ~Qt.ItemIsEnabled)
        #section.setFlags(section.flags() & Qt.NoFocus)
        section.setSelected(False)
        section.setSelected(True)
        section.setSelected(False)
        self.tree.setItemWidget(section, 0, widget)
        return section
Esempio n. 38
0
    def initCenterWidget(self):
        centerWidget = QWidget()

        self.centerBox = QVBoxLayout()
        self.centerBox.setAlignment(Qt.AlignTop)
        self.initQuickLink()

        localWidget = QWidget()
        serverWidget = QWidget()

        localWidgetLayout = QVBoxLayout()
        serverWidgetLayout = QVBoxLayout()

        localLabelLayout = QHBoxLayout()
        serverLabelLayout = QHBoxLayout()

        self.localPathLineEdit = QLineEdit()
        self.serverPathLineEdit = QLineEdit()

        self.localPathLineEdit.setFocusPolicy(Qt.NoFocus)
        self.serverPathLineEdit.setFocusPolicy(Qt.NoFocus)

        self.initLocalFileBox()
        self.initServerFileBox()

        localLabelLayout.addWidget(QLabel('本地文件:'))
        localLabelLayout.addWidget(self.localPathLineEdit)

        serverLabelLayout.addWidget(QLabel('服务器文件:'))
        serverLabelLayout.addWidget(self.serverPathLineEdit)

        localWidgetLayout.addLayout(localLabelLayout)
        localWidgetLayout.addWidget(self.localFileTreeView)
        localWidgetLayout.setContentsMargins(0, 0, 0, 0)

        serverWidgetLayout.addLayout(serverLabelLayout)
        serverWidgetLayout.addWidget(self.serverFileTree)
        serverWidgetLayout.setContentsMargins(0, 0, 0, 0)

        localWidget.setLayout(localWidgetLayout)
        localWidget.setContentsMargins(0, 0, 0, 0)
        serverWidget.setLayout(serverWidgetLayout)
        serverWidget.setContentsMargins(0, 0, 0, 0)

        self.taskQueueTreeWidget = QTreeWidget()
        self.taskQueueTreeWidget.setColumnCount(6)
        self.taskQueueTreeWidget.setHeaderLabels(
            ['文件名', '本地文件夹', '传输方向', ' 远程文件夹', '文件大小', '当前状态'])
        self.taskQueueTreeWidget.setItemDelegate(MyDelegate())

        taskQueueWidget = QWidget()
        taskQueueLayout = QVBoxLayout()
        taskQueueLayout.addWidget(QLabel('任务队列:'))
        taskQueueLayout.addWidget(self.taskQueueTreeWidget)
        taskQueueLayout.setContentsMargins(0, 0, 0, 0)
        taskQueueWidget.setLayout(taskQueueLayout)
        taskQueueWidget.setContentsMargins(0, 0, 0, 0)

        splitter1 = QSplitter(Qt.Horizontal)
        splitter2 = QSplitter(Qt.Vertical)
        splitter3 = QSplitter(Qt.Vertical)
        splitter4 = QSplitter(Qt.Vertical)

        splitter2.addWidget(localWidget)
        splitter2.addWidget(self.localFileTreeWidget)
        splitter3.addWidget(serverWidget)
        splitter3.addWidget(self.serverFileTable)
        splitter1.addWidget(splitter2)
        splitter1.addWidget(splitter3)
        splitter4.addWidget(splitter1)
        splitter4.addWidget(taskQueueWidget)

        self.centerBox.addWidget(splitter4)

        centerWidget.setLayout(self.centerBox)
        self.setCentralWidget(centerWidget)

        self.refreshTableButton.clicked.connect(self.tableRefresh)
Esempio n. 39
0
class BolumlemePencere(QWidget):
    def __init__(self, ebeveyn=None):
        super(BolumlemePencere, self).__init__(ebeveyn)
        self.ebeveyn = ebeveyn

        self.sistemDiski = ["", ""]
        self.takasDiski = ["", ""]
        self.seciliDisk = None
        self.diskler = parted.getAllDevices()
        disklerWidget = QWidget()
        disklerLayout = QHBoxLayout()
        self.disklerAcilirKutu = QComboBox()
        self.yenileButon = QPushButton(self.tr("Yenile"))
        self.yenileButon.pressed.connect(self.diskYenile)

        self.bolumListeKutu = QTreeWidget()
        self.bolumListeKutu.setColumnCount(4)
        self.bolumListeKutu.headerItem().setText(0, self.tr("bölüm"))
        self.bolumListeKutu.headerItem().setText(1, self.tr("kullanım"))
        self.bolumListeKutu.headerItem().setText(2, self.tr("boyut"))
        self.bolumListeKutu.headerItem().setText(3, self.tr("format"))
        # self.bolumListeKutu.headerItem().setText(4, self.tr("bayraklar"))
        self.bolumListeKutu.headerItem().setText(4, self.tr("bölüm numarası"))

        self.disklerAcilirKutu.currentIndexChanged.connect(self.diskDegisti)

        disklerLayout.addWidget(self.disklerAcilirKutu)
        disklerLayout.addWidget(self.yenileButon)
        disklerWidget.setLayout(disklerLayout)
        layout = QVBoxLayout()
        layout.addWidget(disklerWidget)
        layout.addWidget(self.bolumListeKutu)
        lejant = QLabel()
        lejant.setPixmap(QPixmap(":/gorseller/lejant.png"))
        lejant.setAlignment(Qt.AlignCenter)
        layout.addWidget(lejant)
        self.bolumListeKutu.itemClicked.connect(self.bolumSecildiFonk)
        self.bolumListeKutu.itemDoubleClicked.connect(self.bolumFormatSecFonk)

        opWidget = QWidget()
        opButonlar = QHBoxLayout()
        self.yeniBolumBtn = QPushButton(self.tr("Yeni Bölüm Ekle"))
        self.yeniBolumBtn.pressed.connect(self.bolumEkleFonk)
        self.bolumSilBtn = QPushButton(self.tr("Bölümü Sil"))
        self.bolumSilBtn.pressed.connect(self.bolumSilFonk)
        opButonlar.addWidget(self.yeniBolumBtn)
        opButonlar.addWidget(self.bolumSilBtn)
        opWidget.setLayout(opButonlar)
        layout.addWidget(opWidget)

        self.bolumSilBtn.setEnabled(False)
        self.setLayout(layout)
        self.diskYenile()

    def diskYenile(self):
        self.disklerAcilirKutu.clear()
        self.diskler = parted.getAllDevices()
        for disk in self.diskler:
            try:
                if parted.Disk(disk).type == "msdos":
                    self.disklerAcilirKutu.addItem("{} {} GB ({})".format(
                        disk.model, format(disk.getSize(unit="GB"), '.2f'),
                        disk.path),
                                                   userData=disk.path)
            except parted.DiskLabelException:
                disk = parted.freshDisk(disk, "msdos")
                # CDROM Aygıtları için
                try:
                    disk.commit()
                except parted.IOException:
                    pass
                else:
                    disk = disk.device
                    self.disklerAcilirKutu.addItem("{} {} GB ({})".format(
                        disk.model, format(disk.getSize(unit="GB"), '.2f'),
                        disk.path),
                                                   userData=disk.path)

    def diskDegisti(self):
        if self.disklerAcilirKutu.currentData():
            self.aygit = parted.getDevice(self.disklerAcilirKutu.currentData())
            self.ebeveyn.disk = parted.Disk(self.aygit)
            self.bolumListeYenile()

    def bolumListeYenile(self):
        self.extended = None
        self.bolumListeKutu.clear()
        for bolum in self.ebeveyn.disk.partitions:
            _bolum = self.bolumBilgi(bolum, "GB")
            if self.sistemDiski and bolum.path == self.sistemDiski[0]:
                if self.sistemDiski[1] == "evet":
                    item = self.treeWidgetItemOlustur(_bolum["yol"],
                                                      self.tr("Sistem Diski"),
                                                      _bolum["boyut"] + " GB",
                                                      "ext4",
                                                      _bolum["bayraklar"],
                                                      _bolum["no"])
                else:
                    item = self.treeWidgetItemOlustur(_bolum["yol"],
                                                      self.tr("Sistem Diski"),
                                                      _bolum["boyut"],
                                                      _bolum["dosyaSis"],
                                                      _bolum["bayraklar"],
                                                      _bolum["no"])
            elif self.takasDiski and bolum.path == self.takasDiski[0]:
                item = self.treeWidgetItemOlustur(_bolum["yol"],
                                                  self.tr("Takas Alanı"),
                                                  _bolum["boyut"],
                                                  self.tr("takas"),
                                                  _bolum["bayraklar"],
                                                  _bolum["no"])
            else:
                item = self.treeWidgetItemOlustur(_bolum["yol"], "",
                                                  _bolum["boyut"],
                                                  _bolum["dosyaSis"],
                                                  _bolum["bayraklar"],
                                                  _bolum["no"])

            if _bolum["tur"] == parted.PARTITION_NORMAL:
                item.setIcon(0, QIcon("gorseller/primary.xpm"))
            elif _bolum["tur"] == parted.PARTITION_EXTENDED:
                item.setIcon(0, QIcon("gorseller/extended.xpm"))
                self.extended = item
            elif _bolum["tur"] == parted.PARTITION_LOGICAL:
                item.setIcon(0, QIcon("gorseller/logical.xpm"))
                self.extended.addChild(item)
                self.extended.setExpanded(True)
            self.bolumListeKutu.addTopLevelItem(item)

        for bosBolum in self.ebeveyn.disk.getFreeSpacePartitions():
            _toplam = 0
            _bolum = self.bolumBilgi(bosBolum, "GB")
            if float(_bolum["boyut"]) > 1:
                if _bolum["tur"] == 5:
                    uzatilmisKalan = self.treeWidgetItemOlustur(
                        "", self.tr("Uzatılmış Bölüm Kalan"), _bolum["boyut"],
                        "", "", "ayrilmamis")
                    uzatilmisKalan.setIcon(0, QIcon(":/gorseller/blank.xpm"))
                    self.extended.addChild(uzatilmisKalan)
                    self.extended.setExpanded(True)
                if _bolum["tur"] == parted.PARTITION_FREESPACE:
                    _toplam = _toplam + float(_bolum["boyut"])
                ayrilmamis = self.treeWidgetItemOlustur(
                    "", self.tr("Ayrılmamış Bölüm"), _toplam, "", "",
                    "ayrilmamis")
                ayrilmamis.setIcon(0, QIcon(":/gorseller/blank.xpm"))
                self.bolumListeKutu.addTopLevelItem(ayrilmamis)
        self.bolumListeKutu.resizeColumnToContents(0)
        self.bolumListeKutu.resizeColumnToContents(1)
        self.bolumListeKutu.resizeColumnToContents(2)
        self.bolumListeKutu.resizeColumnToContents(3)

    def treeWidgetItemOlustur(self, bolum, kullanim, boyut, format, islev,
                              bolumno):
        item = QTreeWidgetItem()
        item.setText(0, str(bolum))
        item.setText(1, str(kullanim))
        item.setText(2, str(boyut) + " GB ")
        item.setText(3, str(format))
        # item.setText(4, str(islev))
        item.setText(4, str(bolumno))
        return item

    def bolumSecildiFonk(self, tiklanan):
        if tiklanan.text(4) != "ayrilmamis":
            self.bolumSilBtn.setEnabled(True)
        else:
            self.bolumSilBtn.setEnabled(False)

    def bolumFormatSecFonk(self, tiklanan):
        if tiklanan.text(4) != "ayrilmamis":
            self.seciliDisk = tiklanan
            diskOzellikPencere = diskOzellikleriSinif(self)
            diskOzellikPencere.exec_()
            if self.sistemDiski[0] != "":
                self.ebeveyn.kurparam["disk"]["bolum"] = self.sistemDiski[0]
                self.ebeveyn.kurparam["disk"]["format"] = self.sistemDiski[1]
            if self.takasDiski[0] != "":
                self.ebeveyn.kurparam["disk"]["takasbolum"] = self.takasDiski[
                    0]
            else:
                self.ebeveyn.kurparam["disk"]["takasbolum"] = ""

            if self.sistemDiski[0] == "":
                pass
            elif self.sistemDiski[0] != "" and self.takasDiski[0] == "":
                QMessageBox.information(
                    self, self.tr("Bilgi"),
                    self.
                    tr("Takas Alanı Belirtmediniz\nTakas alanı ram miktarınızın düşük olduğu durumlarda\nram yerine disk kullanarak işlemlerin devam etmesini sağlar."
                       ))
                self.ebeveyn.ileriDugme.setDisabled(False)
                self.bolumListeYenile()
            elif self.sistemDiski[0] != "" and self.takasDiski[0] != "":
                if self.sistemDiski[0] == self.takasDiski[0]:
                    QMessageBox.warning(
                        self, self.tr("Hata"), self.takasDiski[0] + self.
                        tr(" diskini hem sistem hem takas için seçtiniz\nAynı diski hem sistem hem takas olarak kullanmazsınız"
                           ))
                    self.ebeveyn.ileriDugme.setDisabled(True)
                else:
                    self.ebeveyn.ileriDugme.setDisabled(False)
                    self.bolumListeYenile()

    def bolumEkleFonk(self):
        if self._en_buyuk_bos_alan():
            alan = self._en_buyuk_bos_alan()
            birincilSayi = len(self.ebeveyn.disk.getPrimaryPartitions())
            uzatilmisSayi = ext_count = 1 if self.ebeveyn.disk.getExtendedPartition(
            ) else 0
            parts_avail = self.ebeveyn.disk.maxPrimaryPartitionCount - (
                birincilSayi + uzatilmisSayi)
            if not parts_avail and not ext_count:
                QMessageBox.warning(
                    self, self.tr("Uyarı"),
                    self.
                    tr("""Eğer dörtten fazla disk bölümü oluşturmak istiyorsanız birincil bölümlerden birini silip uzatılmış bölüm oluşturun. 
                                    Bu durumda oluşturduğunuz uzatılmış bölümleri işletim sistemi kurmak için kullanamayacağınızı aklınızda bulundurun."""
                       ))
            else:
                if parts_avail:
                    if not uzatilmisSayi and parts_avail > 1:
                        self.bolumOlustur(alan, parted.PARTITION_NORMAL)
                        self.bolumListeYenile()
                    elif parts_avail == 1:
                        self.bolumOlustur(alan, parted.PARTITION_EXTENDED)
                        self.bolumListeYenile()
                if uzatilmisSayi:
                    ext_part = self.ebeveyn.disk.getExtendedPartition()
                    try:
                        alan = ext_part.geometry.intersect(alan)
                    except ArithmeticError:
                        QMessageBox.critical(
                            self, self.tr("Hata"),
                            self.
                            tr("Yeni disk bölümü oluşturmak için yeterli alan yok ! Uzatılmış bölümün boyutunu arttırmayı deneyiniz."
                               ))
                    else:
                        self.bolumOlustur(alan, parted.PARTITION_LOGICAL)
                        self.bolumListeYenile()

    def bolumSilFonk(self):
        if self.bolumListeKutu.currentItem().text(4) != "ayrilmamis":
            bolumNo = int(self.bolumListeKutu.currentItem().text(4))
            for bolum in self.ebeveyn.disk.partitions:
                if bolum.number == bolumNo:
                    try:
                        self.ebeveyn.disk.deletePartition(bolum)
                        self.bolumListeYenile()
                    except parted.PartitionException:
                        QMessageBox.warning(
                            self, self.tr("Uyarı"),
                            self.
                            tr("Lütfen uzatılmış bölümleri silmeden önce mantıksal bölümleri siliniz."
                               ))
            self.bolumSilBtn.setDisabled(True)

    def bolumBilgi(self, bolum, birim):
        _bolum = {}
        _bolum["yol"] = bolum.path
        if birim == "GB":
            _bolum["boyut"] = format(bolum.getSize(unit=birim), '.2f')
        else:
            _bolum["boyut"] = bolum.getSize(unit=birim)
        _bolum["dosyaSis"] = "Bilinmeyen"

        if bolum.fileSystem:
            if bolum.fileSystem.type.startswith('linux-swap'):
                _bolum["dosyaSis"] = "takas"
            else:
                _bolum["dosyaSis"] = bolum.fileSystem.type
        try:
            _bolum["bayraklar"] = bolum.getFlagsAsString()
        except:
            pass
        _bolum["no"] = bolum.number
        _bolum["tur"] = bolum.type
        return _bolum

    def _en_buyuk_bos_alan(self):
        maks_boyut = -1
        alan = None
        alignment = self.aygit.optimumAlignment

        for _alan in self.ebeveyn.disk.getFreeSpaceRegions():
            if _alan.length > maks_boyut and _alan.length > alignment.grainSize:
                alan = _alan
                maks_boyut = _alan.length
        return alan

    def bolumOlustur(self, alan, bolumTur):
        if bolumTur == parted.PARTITION_NORMAL or bolumTur == parted.PARTITION_EXTENDED:
            for bosBolum in self.ebeveyn.disk.getFreeSpacePartitions():
                _bolum = self.bolumBilgi(bosBolum, "GB")
                if _bolum["tur"] == parted.PARTITION_FREESPACE:
                    maksBoyut = float(_bolum["boyut"])
        elif bolumTur == bolumTur == parted.PARTITION_LOGICAL:
            for bosBolum in self.ebeveyn.disk.getFreeSpacePartitions():
                _bolum = self.bolumBilgi(bosBolum, "GB")
                if _bolum["tur"] == 5:
                    maksBoyut = float(_bolum["boyut"])

        alignment = self.aygit.optimalAlignedConstraint
        constraint = self.aygit.getConstraint()
        data = {
            'start': constraint.startAlign.alignUp(alan, alan.start),
            'end': constraint.endAlign.alignDown(alan, alan.end),
        }

        boyut, ok = QInputDialog().getDouble(self,
                                             self.tr('Bölüm oluştur'),
                                             self.tr('GB cinsinden boyut:'),
                                             min=0.001,
                                             value=1,
                                             max=maksBoyut,
                                             decimals=3)

        if ok:
            data["end"] = int(data["start"]) + int(
                parted.sizeToSectors(float(boyut), "GiB",
                                     self.aygit.sectorSize))
            try:
                geometry = parted.Geometry(device=self.aygit,
                                           start=int(data["start"]),
                                           end=int(data["end"]))
                partition = parted.Partition(
                    disk=self.ebeveyn.disk,
                    type=bolumTur,
                    geometry=geometry,
                )

                self.ebeveyn.disk.addPartition(partition=partition,
                                               constraint=constraint)
            except (parted.PartitionException, parted.GeometryException,
                    parted.CreateException) as e:
                # GeometryException accounts for incorrect start/end values (e.g. start < end),
                # CreateException is raised e.g. when the partition doesn't fit on the disk.
                # PartedException is a generic error (e.g. start/end values out of range)
                raise RuntimeError(e.message)
Esempio n. 40
0
class client(QMainWindow):
    def __init__(self):
        super().__init__()
        # self.localPath = os.environ['HOME']
        self.localPath = '/'
        self.serverPath = '/'
        self.linkData = []
        self.serverFileInfo = []
        self.waitingTaskQueue = []
        self.finishedTaskQueue = []
        self.createServerDirQueue = []
        self.downloadingTask = []
        self.connectionNow = {
            'hostname': '',
            'username': '',
            'passwd': '',
            'port': 21
        }
        self.FTP = None
        self.clearFlag = 0
        self.t1 = None
        self.timer = QTimer(self)
        self.lock = threading.Lock()
        self.Mutex = threading.Semaphore(1)
        self.initUI()

    def initUI(self):
        self.setGeometry(100, 100, 1100, 600)
        self.setMinimumWidth(650)
        self.setWindowTitle('ftpClient')
        self.initMenuBar()
        self.initCenterWidget()
        self.show()

    def initMenuBar(self):
        linkManage = QAction('管理连接(&L)', self)
        linkManage.setShortcut('Ctrl+M')
        linkManage.setStatusTip('管理所有连接')
        linkManage.triggered.connect(self.startLinkManageDialog)

        exitAct = QAction('退出(&E)', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('退出程序')
        exitAct.triggered.connect(qApp.quit)

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('文件(&F)')
        fileMenu.addAction(linkManage)
        fileMenu.addAction(exitAct)

    def initCenterWidget(self):
        centerWidget = QWidget()

        self.centerBox = QVBoxLayout()
        self.centerBox.setAlignment(Qt.AlignTop)
        self.initQuickLink()

        localWidget = QWidget()
        serverWidget = QWidget()

        localWidgetLayout = QVBoxLayout()
        serverWidgetLayout = QVBoxLayout()

        localLabelLayout = QHBoxLayout()
        serverLabelLayout = QHBoxLayout()

        self.localPathLineEdit = QLineEdit()
        self.serverPathLineEdit = QLineEdit()

        self.localPathLineEdit.setFocusPolicy(Qt.NoFocus)
        self.serverPathLineEdit.setFocusPolicy(Qt.NoFocus)

        self.initLocalFileBox()
        self.initServerFileBox()

        localLabelLayout.addWidget(QLabel('本地文件:'))
        localLabelLayout.addWidget(self.localPathLineEdit)

        serverLabelLayout.addWidget(QLabel('服务器文件:'))
        serverLabelLayout.addWidget(self.serverPathLineEdit)

        localWidgetLayout.addLayout(localLabelLayout)
        localWidgetLayout.addWidget(self.localFileTreeView)
        localWidgetLayout.setContentsMargins(0, 0, 0, 0)

        serverWidgetLayout.addLayout(serverLabelLayout)
        serverWidgetLayout.addWidget(self.serverFileTree)
        serverWidgetLayout.setContentsMargins(0, 0, 0, 0)

        localWidget.setLayout(localWidgetLayout)
        localWidget.setContentsMargins(0, 0, 0, 0)
        serverWidget.setLayout(serverWidgetLayout)
        serverWidget.setContentsMargins(0, 0, 0, 0)

        self.taskQueueTreeWidget = QTreeWidget()
        self.taskQueueTreeWidget.setColumnCount(6)
        self.taskQueueTreeWidget.setHeaderLabels(
            ['文件名', '本地文件夹', '传输方向', ' 远程文件夹', '文件大小', '当前状态'])
        self.taskQueueTreeWidget.setItemDelegate(MyDelegate())

        taskQueueWidget = QWidget()
        taskQueueLayout = QVBoxLayout()
        taskQueueLayout.addWidget(QLabel('任务队列:'))
        taskQueueLayout.addWidget(self.taskQueueTreeWidget)
        taskQueueLayout.setContentsMargins(0, 0, 0, 0)
        taskQueueWidget.setLayout(taskQueueLayout)
        taskQueueWidget.setContentsMargins(0, 0, 0, 0)

        splitter1 = QSplitter(Qt.Horizontal)
        splitter2 = QSplitter(Qt.Vertical)
        splitter3 = QSplitter(Qt.Vertical)
        splitter4 = QSplitter(Qt.Vertical)

        splitter2.addWidget(localWidget)
        splitter2.addWidget(self.localFileTreeWidget)
        splitter3.addWidget(serverWidget)
        splitter3.addWidget(self.serverFileTable)
        splitter1.addWidget(splitter2)
        splitter1.addWidget(splitter3)
        splitter4.addWidget(splitter1)
        splitter4.addWidget(taskQueueWidget)

        self.centerBox.addWidget(splitter4)

        centerWidget.setLayout(self.centerBox)
        self.setCentralWidget(centerWidget)

        self.refreshTableButton.clicked.connect(self.tableRefresh)

    def initQuickLink(self):
        self.hostInput = QLineEdit(self)
        self.userNameInput = QLineEdit(self)
        self.passwdInput = QLineEdit(self)
        self.portInput = QLineEdit('21', self)
        self.quickLoginButton = QPushButton('快速连接', self)
        self.anonymousLoginCheckBox = QCheckBox('匿名连接')
        self.refreshTableButton = QPushButton('刷新文件列表')

        self.passwdInput.setEchoMode(QLineEdit.Password)
        self.portInput.setValidator(QIntValidator(0, 65535))
        self.portInput.setMaximumWidth(40)

        quickLinkBox = QHBoxLayout()
        quickLinkBox.addWidget(QLabel('  主机:', self))
        quickLinkBox.addWidget(self.hostInput)
        quickLinkBox.addWidget(QLabel(' 用户名:', self))
        quickLinkBox.addWidget(self.userNameInput)
        quickLinkBox.addWidget(QLabel(' 密码:', self))
        quickLinkBox.addWidget(self.passwdInput)
        quickLinkBox.addWidget(QLabel(' 端口:', self))
        quickLinkBox.addWidget(self.portInput)
        quickLinkBox.addWidget(self.quickLoginButton)
        quickLinkBox.addWidget(self.anonymousLoginCheckBox)
        quickLinkBox.addWidget(self.refreshTableButton)
        quickLinkBox.addStretch(1)
        self.centerBox.addLayout(quickLinkBox)

        self.quickLoginButton.clicked.connect(self.connectFromQuickLink)
        self.anonymousLoginCheckBox.stateChanged.connect(
            self.quickLinkCheckBoxChanged)

    def initLocalFileBox(self):
        self.localFileTreeView = QTreeView()
        self.localFileTreeWidget = QTreeWidget()

        self.localDirModel = ChangedQDirModel()
        self.localFileTreeView.setModel(self.localDirModel)
        self.localFileTreeView.setColumnWidth(0, 240)
        self.localFileTreeView.setColumnWidth(2, 60)

        self.localFileTreeView.clicked.connect(self.localTreeClicked)

        self.localFileTreeWidget.setColumnCount(4)
        self.localFileTreeWidget.setHeaderLabels(
            ['文件名', '文件大小', '文件类型', '修改时间'])
        self.localFileTreeWidget.setColumnWidth(0, 240)
        self.localFileTreeWidget.setColumnWidth(2, 60)
        self.localFileTreeWidget.setItemDelegate(MyDelegate())

        self.localFileTable = []

        self.localFileRefesh()

        self.localFileTreeWidget.doubleClicked.connect(
            self.localTableDoubleClicked)
        self.localFileTreeWidget.itemPressed.connect(
            self.localTableRightClicked)

    def initServerFileBox(self):
        self.serverFileTree = QTreeWidget()
        self.serverFileTable = QTreeWidget()

        self.serverFileTree.setHeaderLabels(['目录结构'])
        self.serverFileTree.setItemDelegate(MyDelegate())

        self.serverFileTable.setColumnCount(5)
        self.serverFileTable.setHeaderLabels(
            ['文件名', '文件类型', '文件大小', '权限', '修改时间'])
        self.serverFileTable.setColumnWidth(0, 240)
        self.serverFileTable.setColumnWidth(1, 60)
        self.serverFileTable.setColumnWidth(2, 60)
        self.serverFileTable.setColumnWidth(3, 70)
        self.serverFileTable.setItemDelegate(MyDelegate())

        self.serverFileTree.itemExpanded.connect(self.serverFileTreeRefresh)
        self.serverFileTree.itemClicked.connect(self.serverFileTreeClicked)

        self.serverFileTable.doubleClicked.connect(
            self.serverTableDoubleClicked)
        self.serverFileTable.itemPressed.connect(self.serverTableRightClicked)

    def connectFromQuickLink(self):
        hostName = self.hostInput.text()
        userName = self.userNameInput.text()
        passwd = self.passwdInput.text()
        port = int(self.portInput.text())
        with open('linkdata.json', 'r') as f:
            self.linkData = json.load(f)
        data = {
            'hostname': hostName,
            'username': userName,
            'passwd': passwd,
            'port': port,
            'remark': '来自快速连接'
        }
        self.linkData[userName + '@' + hostName + ':' + str(port) + ' ' +
                      '来自快速连接'] = data
        with open('linkdata.json', 'w') as f:
            json.dump(self.linkData, f)

        try:
            self.aNewConnection(hostName, userName, passwd, port)
        except socket.gaierror:
            QMessageBox.information(self, '主机名错误', '主机名错误,请输入正确的主机名',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return
        except ConnectionRefusedError:
            QMessageBox.information(self, '连接出错', '连接失败,请检查是否输入了正确的主机名或端口',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return
        except ftplib.error_perm:
            QMessageBox.information(self, '登陆出错', '登陆失败,请检查是否输入了正确的用户名或密码',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return

    def localFileRefesh(self):
        self.localFileTable.clear()
        self.localFileTreeWidget.clear()

        if self.localPath != '/':
            node = QTreeWidgetItem(self.localFileTreeWidget)
            node.setText(0, '..')
            self.localFileTable.append(node)

        for i in os.listdir(self.localPath):
            node = QTreeWidgetItem(self.localFileTreeWidget)
            node.setText(0, i)
            tempPath = os.path.join(self.localPath, i)
            if os.path.isfile(tempPath):
                node.setText(1, str(os.path.getsize(tempPath)))
                node.setText(2, 'File')
            elif os.path.isdir(tempPath):
                node.setText(1, '')
                node.setText(2, 'Folder')
            elif os.path.islink(tempPath):
                node.setText(1, '')
                node.setText(2, 'Shortcut')
            elif os.path.ismount(tempPath):
                node.setText(1, '')
                node.setText(2, 'Mount')
            try:
                node.setText(3, TimeStampToTime(os.path.getmtime(tempPath)))
            except FileNotFoundError:
                pass
            except PermissionError:
                pass
            self.localFileTable.append(node)

        self.localPathLineEdit.setText(self.localPath)

        for i in self.localFileTable:
            self.localFileTreeWidget.addTopLevelItem(i)

    def serverFileTableRefresh(self):
        self.Mutex.acquire()
        try:
            fileinfo = self.FTP.getdirinfo(self.serverPath)
        except ftplib.error_temp:
            self.reconnect()
            fileinfo = self.FTP.getdirinfo(self.serverPath)
        self.Mutex.release()

        for i in fileinfo:
            node = QTreeWidgetItem(self.serverFileTable)
            node.setText(0, i[0])
            node.setText(1, i[1])
            node.setText(2, i[2])
            node.setText(3, i[3])
            node.setText(4, i[4])
            self.serverFileInfo.append(node)

        self.serverPathLineEdit.setText(self.serverPath)

        for i in self.serverFileInfo:
            self.serverFileTable.addTopLevelItem(i)

    def serverFileTreeRefresh(self, item):
        if self.clearFlag == 0:
            self.clearFlag = 1
            return

        path = item.text(0)
        fatherNode = item
        while fatherNode != self.serverFileTreeRoot:
            fatherNode = fatherNode.parent()
            path = fatherNode.text(0) + '/' + path

        path = path[1:] + '/'

        childrenItemList = item.takeChildren()
        for i in childrenItemList:
            item.removeChild(i)
        self.Mutex.acquire()
        fileinfo = self.FTP.getdirinfo(path)

        for i in fileinfo:
            if i[1] == 'Folder':
                node = QTreeWidgetItem(item)
                node.setText(0, i[0])
                tempinfo = self.FTP.getdirinfo(path + i[0])
                for j in tempinfo:
                    if j[1] == 'Folder':
                        tempnode = QTreeWidgetItem(node)
                        tempnode.setText(0, j[0])
                        node.addChild(tempnode)
                item.addChild(node)
        self.Mutex.release()

    def serverFileTreeClicked(self, item, int_p):
        path = item.text(0)
        fatherNode = item
        while fatherNode != self.serverFileTreeRoot:
            fatherNode = fatherNode.parent()
            path = fatherNode.text(0) + '/' + path
        if path != '/':
            self.serverPath = path[1:]
        else:
            self.serverPath = path

        self.serverFileTable.clear()
        self.serverFileInfo.clear()

        if self.serverPath != '/':
            node = QTreeWidgetItem(self.serverFileTable)
            node.setText(0, '..')
            self.serverFileInfo.append(node)

        self.serverFileTableRefresh()

    def serverTableDoubleClicked(self, index):
        if qApp.mouseButtons() == Qt.RightButton:
            return

        if self.serverFileInfo[index.row()].text(1) == 'File':
            return

        if index.row() == 0:
            if self.serverPath == '/':
                self.localPath = self.serverPath + self.serverFileInfo[0].text(
                    0)
            else:
                tempPath = self.serverPath.split('/')[:-1]
                self.serverPath = ''
                for i in tempPath:
                    self.serverPath = self.serverPath + '/' + i
                if self.serverPath != '/':
                    self.serverPath = self.serverPath[1:]
        else:
            self.serverPath = os.path.join(
                self.serverPath, self.serverFileInfo[index.row()].text(0))

        self.serverFileTable.clear()
        self.serverFileInfo.clear()

        if self.serverPath != '/':
            node = QTreeWidgetItem(self.serverFileTable)
            node.setText(0, '..')
            self.serverFileInfo.append(node)

        self.serverFileTableRefresh()

    def serverTableRightClicked(self, item, int_p):
        if item.text(0) == '..':
            return
        if qApp.mouseButtons() == Qt.RightButton:
            serverMenu = QMenu()
            downLoadFile = QAction('download')
            downLoadFolder = QAction('downloadfolder')
            downLoadFile.triggered.connect(self.downloadFile)
            downLoadFolder.triggered.connect(self.downloadFolder)
            if item.text(1) == 'Folder':
                serverMenu.addAction(downLoadFolder)
            else:
                serverMenu.addAction(downLoadFile)

            serverMenu.exec_(QCursor.pos())

    def downloadFile(self):
        filename = self.serverFileTable.selectedItems()[0].text(0)
        self.lock.acquire()
        try:
            self.waitingTaskQueue.append({
                'filename':
                filename,
                'localpath':
                self.localPath,
                'direction':
                '<--',
                'serverpath':
                self.serverPath,
                'filesize':
                self.serverFileTable.selectedItems()[0].text(2)
            })

        finally:
            self.lock.release()
        self.taskQueueRefresh()
        if len(self.downloadingTask) == 0:
            if self.t1 == None:
                self.t1 = threading.Thread(target=self.taskQueueOpertion)
                self.t1.start()
            else:
                if self.t1.is_alive():
                    pass
                else:
                    self.t1 = threading.Thread(target=self.taskQueueOpertion)
                    self.t1.start()

    def downloadFolder(self):
        folderpath = os.path.join(
            self.serverPath,
            self.serverFileTable.selectedItems()[0].text(0))
        if self.localPath == '/':
            os.mkdir('/' + self.serverFileTable.selectedItems()[0].text(0))
        else:
            os.mkdir(self.localPath + '/' +
                     self.serverFileTable.selectedItems()[0].text(0))
        self.Mutex.acquire()
        self.lock.acquire()
        try:
            self.traversalServerDir(folderpath, self.localPath,
                                    self.serverPath)
        except ftplib.error_temp:
            self.reconnect()
            self.traversalServerDir(folderpath, self.localPath,
                                    self.serverPath)
        finally:
            self.lock.release()
        self.Mutex.release()
        self.taskQueueRefresh()
        if len(self.downloadingTask) == 0:
            if self.t1 == None:
                self.t1 = threading.Thread(target=self.taskQueueOpertion)
                self.t1.start()
            else:
                if self.t1.is_alive():
                    pass
                else:
                    self.t1 = threading.Thread(target=self.taskQueueOpertion)
                    self.t1.start()

    def localTreeClicked(self, index):
        if self.localDirModel.fileInfo(index).isDir():
            self.localPath = self.localDirModel.filePath(index)
        else:
            self.localPath = self.localDirModel.filePath(index)
            tempPath = self.localPath.split('/')[:-1]
            self.localPath = ''
            for i in tempPath:
                self.localPath = self.localPath + '/' + i
            if self.localPath != '/':
                self.localPath = self.localPath[1:]

        self.localFileRefesh()

    def localTableDoubleClicked(self, index):
        if qApp.mouseButtons() == Qt.RightButton:
            return

        if os.path.isdir(
                os.path.join(
                    self.localPath,
                    self.localFileTable[index.row()].text(0))) == False:
            return

        if index.row() == 0:
            if self.localPath == '/':
                self.localPath = self.localPath + self.localFileTable[0].text(
                    0)
            else:
                tempPath = self.localPath.split('/')[:-1]
                self.localPath = ''
                for i in tempPath:
                    self.localPath = self.localPath + '/' + i
                if self.localPath != '/':
                    self.localPath = self.localPath[1:]
        else:
            self.localPath = os.path.join(
                self.localPath, self.localFileTable[index.row()].text(0))

        self.localFileRefesh()

    def localTableRightClicked(self, item, int_p):
        if item.text(0) == '..':
            return
        if qApp.mouseButtons() == Qt.RightButton:
            localMenu = QMenu()
            upLoadFile = QAction('upload')
            upLoadFolder = QAction('uploadfolder')
            upLoadFile.triggered.connect(self.uploadFile)
            upLoadFolder.triggered.connect(self.uploadFolder)
            if item.text(2) == 'Folder':
                localMenu.addAction(upLoadFolder)
            else:
                localMenu.addAction(upLoadFile)

            localMenu.exec_(QCursor.pos())

    def uploadFile(self):
        filename = self.localFileTreeWidget.selectedItems()[0].text(0)
        self.lock.acquire()
        try:
            self.waitingTaskQueue.append({
                'filename':
                filename,
                'localpath':
                self.localPath,
                'direction':
                '-->',
                'serverpath':
                self.serverPath,
                'filesize':
                self.localFileTreeWidget.selectedItems()[0].text(1)
            })

        finally:
            self.lock.release()
        self.taskQueueRefresh()
        if len(self.downloadingTask) == 0:
            if self.t1 == None:
                self.t1 = threading.Thread(target=self.taskQueueOpertion)
                self.t1.start()
            else:
                if self.t1.is_alive():
                    pass
                else:
                    self.t1 = threading.Thread(target=self.taskQueueOpertion)
                    self.t1.start()

    def uploadFolder(self):
        folderpath = os.path.join(
            self.localPath,
            self.localFileTreeWidget.selectedItems()[0].text(0))
        self.lock.acquire()
        try:
            self.traversalLocalDir(folderpath, self.localPath, self.serverPath)
        except ftplib.error_temp:
            self.reconnect()
            self.traversalLocalDir(folderpath, self.localPath, self.serverPath)
        finally:
            self.lock.release()
        self.taskQueueRefresh()

        if len(self.downloadingTask) == 0:
            if self.t1 == None:
                self.t1 = threading.Thread(target=self.taskQueueOpertion)
                self.t1.start()
            else:
                if self.t1.is_alive():
                    pass
                else:
                    self.t1 = threading.Thread(target=self.taskQueueOpertion)
                    self.t1.start()

    def taskQueueOpertion(self):

        while len(self.createServerDirQueue) != 0:
            self.FTP.mkd(self.createServerDirQueue[0])
            self.createServerDirQueue.pop(0)

        while len(self.waitingTaskQueue) != 0:
            self.lock.acquire()
            try:
                self.downloadingTask.append(self.waitingTaskQueue[0])
                print('taskadded' + str(self.waitingTaskQueue[0]))
                self.waitingTaskQueue.pop(0)
                print('self.waitingTaskQueue.pop(0)')
            finally:
                self.lock.release()
            print('before self.taskQueueRefresh()')
            self.Mutex.acquire()
            if self.downloadingTask[0]['direction'] == '<--':
                if ' ' in self.downloadingTask[0]['filename']:
                    localName = self.downloadingTask[0]['filename'].replace(
                        ' ', '_')
                else:
                    localName = self.downloadingTask[0]['filename']
                with open(
                        self.downloadingTask[0]['localpath'] + '/' + localName,
                        'wb') as fp:
                    if self.downloadingTask[0]['serverpath'] == '/':
                        tempserverpath = '/' + self.downloadingTask[0][
                            'filename']
                    else:
                        tempserverpath = self.downloadingTask[0][
                            'serverpath'] + '/' + self.downloadingTask[0][
                                'filename']
                    try:
                        self.FTP.retrbinary('RETR ' + tempserverpath, fp.write,
                                            10240)
                    except ftplib.error_temp:
                        self.reconnect()
                        self.FTP.retrbinary('RETR ' + tempserverpath, fp.write,
                                            10240)
                    self.FTP.set_debuglevel(0)
            elif self.downloadingTask[0]['direction'] == '-->':
                if self.downloadingTask[0]['serverpath'] == '/':
                    tempserverpath = '/' + self.downloadingTask[0]['filename']
                else:
                    tempserverpath = self.downloadingTask[0][
                        'serverpath'] + '/' + self.downloadingTask[0][
                            'filename']
                with open(
                        self.downloadingTask[0]['localpath'] + '/' +
                        self.downloadingTask[0]['filename'], 'rb') as fp:
                    try:
                        self.FTP.storbinary('STOR ' + tempserverpath, fp,
                                            10240)
                    except ftplib.error_temp:
                        self.reconnect()
                        self.FTP.storbinary('STOR ' + tempserverpath, fp,
                                            10240)
                    self.FTP.set_debuglevel(0)
            self.Mutex.release()
            self.lock.acquire()
            try:
                self.finishedTaskQueue.insert(0, self.downloadingTask[0])
                print('finish' + str(self.downloadingTask[0]))
                self.downloadingTask.clear()
                print('downloadingTask.clear()')
            finally:
                self.lock.release()

            print('after self.taskQueueRefresh()')

    def startLinkManageDialog(self):
        with open('linkdata.json', 'r') as f:
            self.linkData = json.load(f)
        self.linkManageDialog = QDialog()
        self.linkManageDialog.setModal(True)
        linkManageLayout = QVBoxLayout()
        self.linkManageDialog.setLayout(linkManageLayout)
        self.linkManageDialog.setWindowTitle('连接管理')

        linkDisplayLayout = QHBoxLayout()
        bottomButtomGroupLayout = QHBoxLayout()

        connectButtom = QPushButton('连接')
        confirmButtom = QPushButton('确定')
        cancleButtom = QPushButton('取消')

        bottomButtomGroupLayout.addStretch(1)
        bottomButtomGroupLayout.addWidget(connectButtom)
        bottomButtomGroupLayout.addWidget(confirmButtom)
        bottomButtomGroupLayout.addWidget(cancleButtom)

        linkManageLayout.addLayout(linkDisplayLayout)
        linkManageLayout.addLayout(bottomButtomGroupLayout)

        linkListLayout = QVBoxLayout()
        linkEditLayout = QVBoxLayout()

        linkDisplayLayout.addLayout(linkListLayout)
        linkDisplayLayout.addLayout(linkEditLayout)

        self.linkList = QListWidget()
        addLinkButton = QPushButton('新建')
        removeLinkButton = QPushButton('删除')
        linkManageButtonGroupLayout = QHBoxLayout()
        linkManageButtonGroupLayout.addWidget(addLinkButton)
        linkManageButtonGroupLayout.addWidget(removeLinkButton)

        linkListLayout.addWidget(QLabel('连接列表:'), 0, Qt.AlignTop)
        linkListLayout.addWidget(self.linkList)
        linkListLayout.addLayout(linkManageButtonGroupLayout)

        hBox1 = QHBoxLayout()
        hBox2 = QHBoxLayout()
        hBox3 = QHBoxLayout()
        hBox4 = QHBoxLayout()
        hBox5 = QHBoxLayout()
        hBox6 = QHBoxLayout()

        self.host = QLineEdit()
        self.userName = QLineEdit()
        self.passwd = QLineEdit()
        self.port = QLineEdit()
        self.remark = QLineEdit()
        self.passwd.setEchoMode(QLineEdit.Password)
        self.port.setValidator(QIntValidator(0, 65535))
        self.anonymousLogin = QCheckBox('匿名登录')
        confirmEdit = QPushButton('确定修改')
        confirmEdit.setFixedWidth(80)

        self.anonymousLogin.stateChanged.connect(
            self.linkManageCheckBoxChanged)

        hBox1.addWidget(QLabel('主机:   '))
        hBox1.addWidget(self.host)
        hBox2.addWidget(QLabel('用户名:'))
        hBox2.addWidget(self.userName)
        hBox3.addWidget(QLabel('密码:   '))
        hBox3.addWidget(self.passwd)
        hBox4.addWidget(QLabel('端口:   '))
        hBox4.addWidget(self.port)
        hBox6.addWidget(QLabel('备注:   '))
        hBox6.addWidget(self.remark)
        hBox5.addWidget(self.anonymousLogin)
        hBox5.addWidget(confirmEdit, Qt.AlignRight)

        linkEditLayout.addLayout(hBox1)
        linkEditLayout.addLayout(hBox2)
        linkEditLayout.addLayout(hBox3)
        linkEditLayout.addLayout(hBox4)
        linkEditLayout.addLayout(hBox6)
        linkEditLayout.addLayout(hBox5)

        for key in self.linkData:
            item = QListWidgetItem(self.linkList)
            item.setText(key)

        self.linkList.setCurrentRow(0)
        if len(self.linkData) != 0:
            tempdata = self.linkData[self.linkList.currentItem().text()]

            self.host.setText(tempdata['hostname'])
            self.port.setText(str(tempdata['port']))
            self.remark.setText(tempdata['remark'])
            if tempdata['username'] == 'anonymous':
                self.anonymousLogin.setCheckState(Qt.Checked)
            else:
                self.userName.setText(tempdata['username'])
                self.passwd.setText(tempdata['passwd'])

        cancleButtom.clicked.connect(self.linkManageDialog.close)
        self.linkList.itemClicked.connect(self.listItemClicked)
        addLinkButton.clicked.connect(self.addNewLink)
        confirmEdit.clicked.connect(self.confirmEditLink)
        confirmButtom.clicked.connect(self.saveData)
        removeLinkButton.clicked.connect(self.removeLink)
        connectButtom.clicked.connect(self.connectFromDialog)

        self.linkManageDialog.show()

    def connectFromDialog(self):
        hostName = self.host.text()
        userName = self.userName.text()
        passwd = self.passwd.text()
        port = int(self.port.text())

        try:
            self.aNewConnection(hostName, userName, passwd, port)
        except socket.gaierror:
            QMessageBox.information(self, '主机名错误', '主机名错误,请输入正确的主机名',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return
        except ConnectionRefusedError:
            QMessageBox.information(self, '连接出错', '连接失败,请检查是否输入了正确的主机名或端口',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return
        except ftplib.error_perm:
            QMessageBox.information(self, '登陆出错', '登陆失败,请检查是否输入了正确的用户名或密码',
                                    QMessageBox.Ok, QMessageBox.Ok)
            return
        self.saveData()

    def removeLink(self):
        if len(self.linkData) == 0:
            return

        rowNow = self.linkList.currentRow()
        itemNow = self.linkList.currentItem()

        self.linkData.pop(itemNow.text())
        self.linkList.removeItemWidget(itemNow)

        self.linkList.clear()

        for key in self.linkData:
            item = QListWidgetItem(self.linkList)
            item.setText(key)

        if len(self.linkData) == 0:
            self.host.setText('')
            self.port.setText('')
            self.anonymousLogin.setCheckState(Qt.Unchecked)
            self.userName.setText('')
            self.passwd.setText('')
            self.remark.setText('')
            return
        elif len(self.linkData) < rowNow + 1:
            rowNow = len(self.linkData) - 1
            self.linkList.setCurrentRow(len(self.linkData) - 1)
        else:
            self.linkList.setCurrentRow(rowNow)

        self.listItemClicked(self.linkList.currentItem())

    def saveData(self):
        self.confirmEditLink()
        with open('linkdata.json', 'w') as f:
            json.dump(self.linkData, f)
        self.linkManageDialog.close()

    def confirmEditLink(self):
        hostName = self.host.text()
        userName = self.userName.text()
        passwd = self.passwd.text()
        port = int(self.port.text())
        remark = self.remark.text()

        data = {
            'hostname': hostName,
            'username': userName,
            'passwd': passwd,
            'port': port,
            "remark": remark
        }

        self.linkData.pop(self.linkList.currentItem().text())
        self.linkData[userName + '@' + hostName + ':' + str(port) + ' ' +
                      remark] = data

        self.linkList.clear()

        for key in self.linkData:
            item = QListWidgetItem(self.linkList)
            item.setText(key)

        self.linkList.setCurrentRow(len(self.linkList) - 1)

    def addNewLink(self):
        if '新连接' in self.linkData:
            return
        self.linkData['新连接'] = {
            'hostname': '',
            'username': '',
            'passwd': '',
            'port': '',
            'remark': ''
        }
        item = QListWidgetItem(self.linkList)
        item.setText('新连接')
        self.linkList.setCurrentRow(len(self.linkList) - 1)

        self.host.setText('')
        self.port.setText('21')
        self.anonymousLogin.setCheckState(Qt.Unchecked)
        self.userName.setText('')
        self.passwd.setText('')
        self.remark.setText('')

    def listItemClicked(self, item):
        tempdata = self.linkData[item.text()]

        self.host.setText(tempdata['hostname'])
        self.port.setText(str(tempdata['port']))
        self.remark.setText(tempdata['remark'])
        if tempdata['username'] == 'anonymous':
            self.anonymousLogin.setCheckState(Qt.Checked)
        else:
            self.anonymousLogin.setCheckState(Qt.Unchecked)
            self.userName.setText(tempdata['username'])
            self.passwd.setText(tempdata['passwd'])

    def quickLinkCheckBoxChanged(self):
        if self.anonymousLoginCheckBox.checkState() == Qt.Checked:
            self.userNameInput.setText('anonymous')
            self.passwdInput.setText('')
            self.userNameInput.setEnabled(False)
            self.passwdInput.setEnabled(False)
        elif self.anonymousLoginCheckBox.checkState() == Qt.Unchecked:
            self.userNameInput.setText('')
            self.passwdInput.setText('')
            self.userNameInput.setEnabled(True)
            self.passwdInput.setEnabled(True)

    def linkManageCheckBoxChanged(self):
        if self.anonymousLogin.checkState() == Qt.Checked:
            self.userName.setText('anonymous')
            self.passwd.setText('')
            self.userName.setEnabled(False)
            self.passwd.setEnabled(False)
        elif self.anonymousLogin.checkState() == Qt.Unchecked:
            self.userName.setText('')
            self.passwd.setText('')
            self.userName.setEnabled(True)
            self.passwd.setEnabled(True)

    def aNewConnection(self, host, username, passwd, port):
        if self.FTP != None:
            try:
                self.FTP.quit()
            except AttributeError:
                pass
            except EOFError:
                pass
        self.FTP = myFtp()
        self.FTP.set_pasv(True)
        self.connectionNow['hostname'] = host
        self.connectionNow['username'] = username
        self.connectionNow['passwd'] = passwd
        self.connectionNow['port'] = port
        self.FTP.connect(host, port)
        self.FTP.login(username, passwd)

        self.serverFileInfo = []
        self.serverPath = '/'
        self.serverFileTable.clear()
        self.serverFileTree.clear()

        self.serverFileTreeRoot = QTreeWidgetItem(self.serverFileTree)
        self.serverFileTreeRoot.setText(0, '/')
        self.serverFileTree.addTopLevelItem(self.serverFileTreeRoot)

        self.Mutex.acquire()
        fileinfo = self.FTP.getdirinfo(self.serverPath)

        for i in fileinfo:
            if i[1] == 'Folder':
                node = QTreeWidgetItem(self.serverFileTreeRoot)
                node.setText(0, i[0])
                tempinfo = self.FTP.getdirinfo(self.serverPath + i[0])
                for j in tempinfo:
                    if j[1] == 'Folder':
                        tempnode = QTreeWidgetItem(node)
                        tempnode.setText(0, j[0])
                        node.addChild(tempnode)
                self.serverFileTreeRoot.addChild(node)
        self.Mutex.release()

        self.serverFileTreeRoot.setExpanded(True)

        self.serverFileTableRefresh()

        if self.timer.isActive():
            self.timer.disconnect()

        self.timer.timeout.connect(self.taskQueueRefresh)
        self.timer.start(500)

    def reconnect(self):
        self.FTP.connect(self.connectionNow['hostname'],
                         self.connectionNow['port'])
        self.FTP.login(self.connectionNow['username'],
                       self.connectionNow['passwd'])

    def taskQueueRefresh(self):
        self.lock.acquire()
        try:
            self.taskQueueTreeWidget.clear()
            if len(self.downloadingTask) != 0:
                node = QTreeWidgetItem(self.taskQueueTreeWidget)
                node.setText(0, self.downloadingTask[0]['filename'])
                node.setText(1, self.downloadingTask[0]['localpath'])
                node.setText(2, self.downloadingTask[0]['direction'])
                node.setText(3, self.downloadingTask[0]['serverpath'])
                node.setText(4, self.downloadingTask[0]['filesize'])
                node.setText(5, '正在传输')
                self.taskQueueTreeWidget.addTopLevelItem(node)

            for i in self.waitingTaskQueue:
                node = QTreeWidgetItem(self.taskQueueTreeWidget)
                node.setText(0, i['filename'])
                node.setText(1, i['localpath'])
                node.setText(2, i['direction'])
                node.setText(3, i['serverpath'])
                node.setText(4, i['filesize'])
                node.setText(5, '等待传输')
                self.taskQueueTreeWidget.addTopLevelItem(node)

            for i in self.finishedTaskQueue:
                node = QTreeWidgetItem(self.taskQueueTreeWidget)
                node.setText(0, i['filename'])
                node.setText(1, i['localpath'])
                node.setText(2, i['direction'])
                node.setText(3, i['serverpath'])
                node.setText(4, i['filesize'])
                node.setText(5, '传输完成')
                self.taskQueueTreeWidget.addTopLevelItem(node)

        finally:
            self.lock.release()

    def tableRefresh(self):
        if self.connectionNow['hostname'] != '':
            self.serverFileTable.clear()
            self.serverFileInfo.clear()

            if self.serverPath != '/':
                node = QTreeWidgetItem(self.serverFileTable)
                node.setText(0, '..')
                self.serverFileInfo.append(node)

            self.serverFileTableRefresh()

        self.localFileRefesh()

    def traversalLocalDir(self, dir, localpath, serverpath):
        fs = os.listdir(dir)
        for i in fs:
            temppath = os.path.join(dir, i)
            if os.path.isdir(temppath) == False:
                if serverpath == '/' and localpath == '/':
                    print(i + ' ' + dir + ' ' + dir + ' ' +
                          str(os.path.getsize(temppath)))
                    self.waitingTaskQueue.append({
                        'filename':
                        i,
                        'localpath':
                        dir,
                        'direction':
                        '-->',
                        'serverpath':
                        dir,
                        'filesize':
                        str(os.path.getsize(temppath))
                    })
                elif serverpath == '/':
                    self.waitingTaskQueue.append({
                        'filename':
                        i,
                        'localpath':
                        dir,
                        'direction':
                        '-->',
                        'serverpath':
                        dir[len(localpath):],
                        'filesize':
                        str(os.path.getsize(temppath))
                    })
                    print(i + ' ' + dir + ' ' + dir[len(localpath):] + ' ' +
                          str(os.path.getsize(temppath)))
                elif localpath == '/':
                    self.waitingTaskQueue.append({
                        'filename':
                        i,
                        'localpath':
                        dir,
                        'direction':
                        '-->',
                        'serverpath':
                        serverpath + dir,
                        'filesize':
                        str(os.path.getsize(temppath))
                    })
                    print(i + ' ' + dir + ' ' + serverpath + dir + ' ' +
                          str(os.path.getsize(temppath)))
                else:
                    self.waitingTaskQueue.append({
                        'filename':
                        i,
                        'localpath':
                        dir,
                        'direction':
                        '-->',
                        'serverpath':
                        serverpath + dir[len(localpath):],
                        'filesize':
                        str(os.path.getsize(temppath))
                    })
                    print(i + ' ' + dir + ' ' + serverpath +
                          dir[len(localpath):] + ' ' +
                          str(os.path.getsize(temppath)))
            else:
                if serverpath == '/' and localpath == '/':
                    print(i + ' ' + temppath + ' ' + temppath)
                    self.createServerDirQueue.append(temppath)
                elif serverpath == '/':
                    print(i + ' ' + temppath + ' ' + temppath[len(localpath):])
                    self.createServerDirQueue.append(temppath[len(localpath):])
                elif localpath == '/':
                    print(i + ' ' + temppath + ' ' + serverpath + temppath)
                    self.createServerDirQueue.append(serverpath + temppath)
                else:
                    print(i + ' ' + temppath + ' ' + serverpath +
                          temppath[len(localpath):])
                    self.createServerDirQueue.append(serverpath +
                                                     temppath[len(localpath):])
                self.traversalLocalDir(temppath, localpath, serverpath)

    def traversalServerDir(self, dir, localpath, serverpath):
        fs = self.FTP.getdirinfo(dir)
        for i in fs:
            temppath = os.path.join(dir, i[0])
            if i[1] == 'File':
                if serverpath == '/' and localpath == '/':
                    print(i[0] + ' ' + dir + ' ' + dir + ' ' + i[2])
                    self.waitingTaskQueue.append({
                        'filename': i[0],
                        'localpath': dir,
                        'direction': '<--',
                        'serverpath': dir,
                        'filesize': i[2]
                    })
                elif serverpath == '/':
                    self.waitingTaskQueue.append({
                        'filename': i[0],
                        'localpath': localpath + dir,
                        'direction': '<--',
                        'serverpath': dir,
                        'filesize': i[2]
                    })
                    print(i[0] + ' ' + localpath + dir + ' ' + dir + ' ' +
                          i[2])
                elif localpath == '/':
                    self.waitingTaskQueue.append({
                        'filename':
                        i[0],
                        'localpath':
                        dir[len(serverpath):],
                        'direction':
                        '<--',
                        'serverpath':
                        dir,
                        'filesize':
                        i[2]
                    })
                    print(i[0] + ' ' + dir[len(serverpath):] + ' ' + dir +
                          ' ' + i[2])
                else:
                    self.waitingTaskQueue.append({
                        'filename':
                        i[0],
                        'localpath':
                        localpath + dir[len(serverpath):],
                        'direction':
                        '<--',
                        'serverpath':
                        dir,
                        'filesize':
                        i[2]
                    })
                    print(i[0] + ' ' + localpath + dir[len(serverpath):] +
                          ' ' + dir + ' ' + i[2])
            else:
                if serverpath == '/' and localpath == '/':
                    print(i[0] + ' ' + temppath + ' ' + temppath)
                    os.makedirs(temppath)
                elif serverpath == '/':
                    print(i[0] + ' ' + localpath + temppath + ' ' + temppath)
                    os.makedirs(localpath + temppath)
                elif localpath == '/':
                    print(i[0] + ' ' + temppath[len(serverpath):] + ' ' +
                          temppath)
                    os.makedirs(temppath[len(serverpath):])
                else:
                    print(i[0] + ' ' + localpath + temppath[len(serverpath):] +
                          ' ' + temppath)
                    os.makedirs(localpath + temppath[len(serverpath):])
                self.traversalServerDir(temppath, localpath, serverpath)
Esempio n. 41
0
class capture(QWidget):
    filterApplied = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.initUI()
        self.packet_list = []

    def initUI(self):
        mainLayout = QVBoxLayout(self)

        filter_layout = QHBoxLayout()
        filter_label = QLabel('Filter')
        self.filter_lineEdit = QLineEdit()
        filter_apply_btn = QPushButton('Apply')
        filter_layout.addWidget(filter_label)
        filter_layout.addWidget(self.filter_lineEdit)
        filter_layout.addWidget(filter_apply_btn)
        mainLayout.addLayout(filter_layout)
        self.filter = ''

        splitterMain = QSplitter(Qt.Vertical, self)
        self.QuickView = QTableWidget(splitterMain)
        #self.QuickView.setUniformItemSizes(True)
        self.QuickView.setColumnCount(6)
        self.QuickView.setHorizontalHeaderLabels(
            ['No.', 'Time', 'Source', 'Destination', 'Protocol', 'Size'])
        self.QuickView.setColumnWidth(0, 60)
        self.QuickView.verticalHeader().setVisible(False)
        self.QuickView.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        # self.QuickView.horizontalHeader().setStretchLastSection(True)
        self.QuickView.setShowGrid(False)
        self.QuickView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.QuickView.setSelectionMode(QTableWidget.ExtendedSelection)
        self.QuickView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # self.QuickView.setLayoutMode(QListView.Batched)
        # self.QuickView.setBatchSize(20)
        self.DetailView = QTreeWidget(splitterMain)
        self.DetailView.setColumnCount(2)
        self.DetailView.setHeaderLabels(['Item', 'Detail'])
        mainLayout.addWidget(splitterMain)

        bottomLayout = QHBoxLayout()
        self.start_btn = QPushButton('Start')
        self.stop_btn = QPushButton('Stop')
        self.restart_btn = QPushButton('Restart')
        self.clear_btn = QPushButton('Clear')
        self.intercept_CheckBox = QCheckBox('Intercept Packets')
        bottomLayout.addWidget(self.start_btn)
        bottomLayout.addWidget(self.stop_btn)
        bottomLayout.addWidget(self.restart_btn)
        bottomLayout.addWidget(self.clear_btn)
        bottomLayout.addWidget(self.intercept_CheckBox)
        bottomLayout.addStretch()
        self.stop_btn.setEnabled(False)
        self.restart_btn.setEnabled(False)
        mainLayout.addLayout(bottomLayout)

        self.start_btn.clicked.connect(self.start_sniff)
        # filter_apply_btn.clicked.connect(self.apply_filter)
        self.stop_btn.clicked.connect(self.stop_sniff)
        self.QuickView.currentItemChanged.connect(self.show_current_detail)
        self.restart_btn.clicked.connect(self.restart_sniff)
        self.clear_btn.clicked.connect(self.clear_widget)
        self.count = 0

    def start_sniff(self):
        self.cap_thread = capturethread()
        self.cap_thread.newPkt.connect(self.init_display)
        self.cap_thread.start()

        self.start_btn.setEnabled(False)
        self.stop_btn.setEnabled(True)
        self.restart_btn.setEnabled(False)

    def init_display(self, item_list, pkt):
        self.packet_list.append(pkt)
        self.QuickView.insertRow(self.QuickView.rowCount())

        for i in range(6):
            self.QuickView.setItem(self.QuickView.rowCount() - 1, i,
                                   item_list[i])

    # def apply_filter(self):
    #     filter_queue=CaptureQueue.get_filter()
    #     filter_queue.queue.clear()
    #     filter_queue.put(self.filter_lineEdit.text())
    #     if self.cap_thread.isRunning():
    #         self.cap_thread.set_stopper(True)
    #         self.cap_thread.wait()
    #     self.cap_thread.start()

    #     filter_pkt_queue=CaptureQueue.get_packet_to_filter()
    #     filter_pkt_queue.put(self.packet_list)
    #     filter_pkt_queue.put(self.filter_lineEdit.text())
    #     self.filter_thread=filterthread()
    #     self.filter_thread.start()
    #     self.filter_thread.filtered.connect(self.get_filtered_pkt)

    # def get_filtered_pkt(self,packetlist):
    #     pass

    # def formatString(self, tmp):
    #     self.final_dict = collections.OrderedDict()
    #     title_pattern = re.compile(r'###[ [a-zA-Z]+ ]###')  #abstract titles
    #     tmp_titles = title_pattern.findall(tmp)
    #     self.titles = []
    #     for title in tmp_titles:
    #         refine_pattern = re.compile(r'###\[ | \]###')
    #         self.titles.append(refine_pattern.sub('', title))
    #     #print(self.titles)

    #     content_split_pattern = title_pattern  #abstract contents
    #     tmp_content = re.split(content_split_pattern, tmp)
    #     self.contents = [i for i in tmp_content if i != '']
    #     #print(self.contents)

    #     for (title, content) in zip(self.titles, self.contents):
    #         tmp_dict = {}
    #         tmp_lists = re.split(r'\n', content)
    #         tmp_lists = [i.replace(' ', '') for i in tmp_lists if i != '']

    #         #print(tmp_lists)
    #         for i in tmp_lists:
    #             tmp_item = i.split('=')
    #             #print(tmp_item)
    #             if len(tmp_item) == 2:
    #                 tmp_dict[tmp_item[0]] = tmp_item[1]
    #         self.final_dict[title] = tmp_dict
    #     #print(self.final_dict)

    def buildTree(self):
        self.DetailView.clear()
        for title in self.packetDict.keys():
            tree_item = QTreeWidgetItem(self.DetailView)
            tree_item.setText(0, title)
            tree_item.setExpanded(True)
            detail_dic = self.packetDict[title]
            for i in detail_dic.keys():
                leaf = QTreeWidgetItem(tree_item, [i, str(detail_dic[i])])
                leaf.setToolTip(1, str(detail_dic[i]))
                tree_item.addChild(leaf)
            self.DetailView.addTopLevelItem(tree_item)

    def stop_sniff(self):
        self.cap_thread.set_stopper(True)

        self.start_btn.setEnabled(True)
        self.restart_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)

    def restart_sniff(self):
        self.pkt_queue = CaptureQueue.get_pkt()
        self.label_queue = CaptureQueue.get_label()
        with self.label_queue.mutex:
            self.label_queue.queue.clear()
        with self.pkt_queue.mutex:
            self.pkt_queue.queue.clear()
        self.packet_list.clear()
        self.QuickView.clearContents()
        self.DetailView.clear()
        self.start_sniff()

    def show_current_detail(self):
        if self.packet_list:
            pkt = self.packet_list[self.QuickView.currentRow()]
            # self.text = FakeOut()
            # old = sys.stdout
            # sys.stdout = self.text
            # packet.show2()
            # sys.stdout = old
            # tmp = self.text.str
            # self.formatString(tmp)
            self.packetDict = scapy2ordereddict.to_dict(pkt)
            self.buildTree()

    def clear_widget(self):
        self.pkt_queue = CaptureQueue.get_pkt()
        self.label_queue = CaptureQueue.get_label()
        with self.label_queue.mutex:
            self.label_queue.queue.clear()
        with self.pkt_queue.mutex:
            self.pkt_queue.queue.clear()
        self.packet_list.clear()
        self.QuickView.clearContents()
        self.DetailView.clear()
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.
        '''
        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
        if ~self.display_no_responses and ~self.dis
        for child_item in self.tree.children():
        
    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)

        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   
Esempio n. 43
0
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': 'red', 'b': 'green', 'c': 'blue'}
        #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
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.
        '''
        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 on_updated_tree_item(self):
        #update the rectangle which was edited
        pass
Esempio n. 45
0
class ThermoGroup(QWidget):
    """widget used for the 'other' and 'reference' frames on the relative tab"""
    changes = Signal()

    def __init__(self, name, session, nrg_fr, thermo_co, size, *args,
                 **kwargs):
        super().__init__(*args, **kwargs)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.session = session
        self.nrg_fr = nrg_fr
        self.thermo_co = thermo_co

        layout = QGridLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setRowStretch(0, 1)

        frame = QGroupBox(name)
        frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        frame_layout = QGridLayout(frame)
        frame_layout.setContentsMargins(0, 0, 0, 0)
        frame_layout.setRowStretch(0, 1)

        self.tree = QTreeWidget()
        self.tree.setColumnCount(3)
        self.tree.setHeaderLabels(["energy", "frequencies", "remove"])
        self.tree.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.tree.setColumnWidth(0, size[0])
        self.tree.setColumnWidth(1, size[1])
        self.tree.resizeColumnToContents(2)

        root_item = self.tree.invisibleRootItem()
        plus = QTreeWidgetItem(root_item)
        plus_button = QPushButton("add molecule group")
        plus_button.setFlat(True)
        plus_button.clicked.connect(self.add_mol_group)
        plus_button2 = QPushButton("")
        plus_button2.setFlat(True)
        plus_button2.clicked.connect(self.add_mol_group)
        self.tree.setItemWidget(plus, 0, plus_button)
        self.tree.setItemWidget(plus, 1, plus_button2)
        self.tree.insertTopLevelItem(1, plus)

        self.add_mol_group()

        frame_layout.addWidget(self.tree)

        layout.addWidget(frame)

    def add_mol_group(self, *args):
        row = self.tree.topLevelItemCount()

        root_item = self.tree.invisibleRootItem()

        mol_group = QTreeWidgetItem(root_item)
        self.tree.insertTopLevelItem(row, mol_group)
        trash_button = QPushButton()
        trash_button.setFlat(True)

        trash_button.clicked.connect(
            lambda *args, parent=mol_group: self.remove_mol_group(parent))
        trash_button.setIcon(
            QIcon(self.style().standardIcon(QStyle.SP_DialogDiscardButton)))

        add_conf_button = QPushButton("add conformer")
        add_conf_button.setFlat(True)
        add_conf_button.clicked.connect(
            lambda *args, conf_group_widget=mol_group: self.add_conf_group(
                conf_group_widget))

        add_conf_button2 = QPushButton("")
        add_conf_button2.setFlat(True)
        add_conf_button2.clicked.connect(
            lambda *args, conf_group_widget=mol_group: self.add_conf_group(
                conf_group_widget))

        add_conf_child = QTreeWidgetItem(mol_group)
        self.tree.setItemWidget(add_conf_child, 0, add_conf_button)
        self.tree.setItemWidget(add_conf_child, 1, add_conf_button2)
        self.tree.setItemWidget(mol_group, 2, trash_button)

        mol_group.setText(0, "group %i" % row)

        mol_group.addChild(add_conf_child)
        self.add_conf_group(mol_group)

        self.tree.expandItem(mol_group)

        self.changes.emit()

    def add_conf_group(self, conf_group_widget):
        row = conf_group_widget.childCount()

        conformer_item = QTreeWidgetItem(conf_group_widget)
        conf_group_widget.insertChild(row, conformer_item)

        nrg_combobox = FilereaderComboBox(self.session, otherItems=['energy'])
        nrg_combobox.currentIndexChanged.connect(
            lambda *args: self.changes.emit())
        freq_combobox = FilereaderComboBox(self.session,
                                           otherItems=['frequency'])
        freq_combobox.currentIndexChanged.connect(
            lambda *args: self.changes.emit())

        trash_button = QPushButton()
        trash_button.setFlat(True)
        trash_button.clicked.connect(
            lambda *args, combobox=nrg_combobox: combobox.deleteLater())
        trash_button.clicked.connect(
            lambda *args, combobox=freq_combobox: combobox.deleteLater())
        trash_button.clicked.connect(lambda *args, child=conformer_item:
                                     conf_group_widget.removeChild(child))
        trash_button.clicked.connect(lambda *args: self.changes.emit())
        trash_button.setIcon(
            QIcon(self.style().standardIcon(QStyle.SP_DialogCancelButton)))

        self.tree.setItemWidget(conformer_item, 0, nrg_combobox)
        self.tree.setItemWidget(conformer_item, 1, freq_combobox)
        self.tree.setItemWidget(conformer_item, 2, trash_button)

        self.changes.emit()

    def compOutputs(self):
        out = []
        for mol_index in range(1, self.tree.topLevelItemCount()):
            out.append([])
            mol = self.tree.topLevelItem(mol_index)
            for conf_ndx in range(1, mol.childCount()):
                conf = mol.child(conf_ndx)
                fr = self.tree.itemWidget(conf, 1).currentData()
                if fr is None:
                    continue

                if fr not in self.thermo_co:
                    self.thermo_co[fr] = CompOutput(fr)
                out[-1].append(self.thermo_co[fr])

        return out

    def energies(self):
        out = []
        for mol_index in range(1, self.tree.topLevelItemCount()):
            out.append([])
            mol = self.tree.topLevelItem(mol_index)
            for conf_ndx in range(1, mol.childCount()):
                conf = mol.child(conf_ndx)
                fr = self.tree.itemWidget(conf, 0).currentData()
                if fr is None:
                    continue

                out[-1].append(fr.other['energy'])

        return out

    def remove_mol_group(self, parent):
        for conf_ndx in range(1, parent.childCount()):
            conf = parent.child(conf_ndx)
            self.tree.itemWidget(conf, 0).destroy()
            self.tree.itemWidget(conf, 1).destroy()

        ndx = self.tree.indexOfTopLevelItem(parent)
        self.tree.takeTopLevelItem(ndx)

        self.changes.emit()

    def deleteLater(self):
        for mol_index in range(1, self.tree.topLevelItemCount()):
            mol = self.tree.topLevelItem(mol_index)
            for conf_ndx in range(1, mol.childCount()):
                conf = mol.child(conf_ndx)
                self.tree.itemWidget(conf, 0).deleteLater()
                self.tree.itemWidget(conf, 1).deleteLater()

        super().deleteLater()
Esempio n. 46
0
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)

        #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(self.rectangles_received)  #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 type'
        ]
        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.tree.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
        #self.tree.header().setStretchLastSection(False)
        return self.tree

    def add_items(self):
        '''
        Populate viewing tree
        '''
        for rect in self.rectangles_received:
            #populate editable tree with rect data
            column = 0
            self.rect_item = QTreeWidgetItem(self.root)
            self.rect_params = [rect.get_la]
Esempio n. 47
0
    def __init__(self, *args, **kwargs):
        super().__init__()
        self.pageInfo = PageInfo("", "")
        self.setWindowTitle("河北腾云信息科技有限公司")
        self.icon = QtGui.QIcon()
        self.icon.addPixmap(QtGui.QPixmap("images/logo.ico"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(self.icon)
        self.treeWidget = QTreeWidget()
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.root = QTreeWidgetItem(self.treeWidget)
        self.treeWidget.addTopLevelItem(self.root)
        # self.setStyleSheet(helper.CommonHelper.read_css('./css/style.css'))

        # 设置列数
        self.treeWidget.setColumnCount(1)
        # 设置树形控件头部的标题
        self.treeWidget.setHeaderLabels(['财税大数据平台'])
        self.treeWidget.setFixedWidth(500)

        self.rightWidget = QWidget()
        self.rightLayout = QVBoxLayout()

        self.dataBox = QGroupBox("数据库连接")
        self.dataBox.setStyleSheet("QGroupBox{border: 1px solid black;}")
        self.connectBtn = QPushButton("生成查找树")

        self.yearLab = QLabel("年份")
        self.yearEdit = QLineEdit()

        self.dataLayout = QGridLayout()
        self.dataLayout.setContentsMargins(10, 20, 10, 15)
        self.hostLab = QLabel("主机名或ip地址:")
        self.portLab = QLabel("端口:")
        self.userLab = QLabel("用户名:")
        self.passLab = QLabel("密码")
        self.dbLab = QLabel("数据库名:")
        self.charsetLab = QLabel("字符集:")

        self.hostEdit = QLineEdit()
        self.userEdit = QLineEdit()
        self.portEdit = QLineEdit()
        self.passEdit = QLineEdit()
        self.dbEdit = QLineEdit()
        self.charsetEdit = QLineEdit()

        self.hostEdit.setText("192.168.110.201")
        self.portEdit.setText("3306")
        self.userEdit.setText("root")
        self.passEdit.setEchoMode(QLineEdit.Password)
        self.passEdit.setText("tengyun2020")
        self.dbEdit.setText("fiscal_tax")
        self.charsetEdit.setText("utf8")
        self.yearEdit.setText("2019")

        self.pageTextInfo = []

        self.dataLayout.addWidget(self.hostLab, 0, 0)
        self.dataLayout.addWidget(self.hostEdit, 0, 1)
        self.dataLayout.addWidget(self.portLab, 0, 2)
        self.dataLayout.addWidget(self.portEdit, 0, 3)
        self.dataLayout.addWidget(self.userLab, 0, 4)
        self.dataLayout.addWidget(self.userEdit, 0, 5)
        self.dataLayout.addWidget(self.yearLab, 0, 6)
        self.dataLayout.addWidget(self.yearEdit, 0, 7)
        self.dataLayout.addWidget(self.passLab, 1, 0)
        self.dataLayout.addWidget(self.passEdit, 1, 1)
        self.dataLayout.addWidget(self.dbLab, 1, 2)
        self.dataLayout.addWidget(self.dbEdit, 1, 3)
        self.dataLayout.addWidget(self.charsetLab, 1, 4)
        self.dataLayout.addWidget(self.charsetEdit, 1, 5)
        self.dataLayout.addWidget(self.connectBtn, 1, 7, 1, 1)

        self.dataBox.setLayout(self.dataLayout)

        self.budgetBox = QGroupBox("预决算信息提取")
        self.budgetBox.setStyleSheet("QGroupBox{border: 1px solid black;}")

        self.comboBox = QComboBox()
        self.comboBox.addItem("一般公共预算收支科目")
        self.comboBox.addItem("政府性基金预算收支科目")
        self.comboBox.addItem("国有资本经营预算收支科目")
        self.comboBox.addItem("社会保险基金预算收支科目")
        self.comboBox.addItem("支出经济分类科目")
        # self.comboBox.addItem("一般公共预算收入科目")
        # self.comboBox.addItem("一般公共预算支出科目")
        # self.comboBox.addItem("政府性基金预算收入科目")
        # self.comboBox.addItem("政府性基金预算支出科目")
        # self.comboBox.addItem("国有资本经营预算收入科目")
        # self.comboBox.addItem("国有资本经营预算支出科目")
        # self.comboBox.addItem("社会保险基金预算收入科目")
        # self.comboBox.addItem("社会保险基金预算支出科目")
        self.comboBox.setStyleSheet("""
                    QComboBox {border:none;background:#000000;color:#ffffff;
                    padding-left:30px;font-size:16px "SimHei";}
                    QComboBox QAbstractItemView {background:#000000;color:#ffffff;padding-left:30px;} 
                    QComboBox QAbstractItemView::item {min-height:30px;font-size:16px "SimHei";}
         """)
        self.comboBox.setView(QListView())
        self.pathLab = QLabel("文件路径:")
        self.extractBtn = QPushButton("提取信息")
        self.genBtn = QPushButton("生成Excel")
        self.initBtn = QPushButton("清空文件")
        self.codeLab = QLabel("科目编码:")
        self.subLab = QLabel("科目名称:")
        self.budgetLab = QLabel("预算数:")
        self.actualLab = QLabel("决算数:")
        self.pageLab = QLabel("页码:")
        self.pageInfoBtn = QPushButton("页面信息")
        self.regxLab = QLabel("分割符:")
        self.posLab = QLabel("名称位置:")
        self.targetLab = QLabel("目标文件路径:")
        self.boundLab = QLabel("pdf无边框表格位置:")
        self.currentPageLab = QLabel("无边框表格页码:")

        self.pathEdit = LineEdit()
        self.codeEdit = QLineEdit()
        self.subEdit = QLineEdit()
        self.budgetEdit = QLineEdit()
        self.actualEdit = QLineEdit()
        self.pageEdit = QLineEdit()
        self.regxEdit = QLineEdit()
        self.posEdit = QLineEdit()
        self.targetEdit = LineEdit()
        self.boundEdit = QLineEdit()
        self.currentPageEdit = QLineEdit()

        current_page_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"^[1-9]\d*$"), self.currentPageEdit)
        self.currentPageEdit.setValidator(current_page_validator)

        page_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(-[1-9]\d*)||(^[1-9]\d*)(,[1-9]\d*)+"),
            self.pageEdit)
        self.pageEdit.setValidator(page_validator)

        sub_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.subEdit)
        self.subEdit.setValidator(sub_validator)

        code_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.codeEdit)
        self.codeEdit.setValidator(code_validator)

        budget_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.budgetEdit)
        self.budgetEdit.setValidator(budget_validator)

        actual_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.actualEdit)
        self.actualEdit.setValidator(actual_validator)

        bound_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[0-9]\d*)(,[0-9]\d*)+"), self.boundEdit)
        self.boundEdit.setValidator(bound_validator)
        """
        self.pathEdit.setText("C:/Users/localhost/Desktop/bb/新乐市2019年政府预算公开附表.xlsx")
        self.targetEdit.setText("C:/Users/localhost/Desktop/cc")
        self.subEdit.setText("1")
        self.codeEdit.setText("")
        self.budgetEdit.setText("2")
        self.actualEdit.setText("")
        self.pageEdit.setText("1")
        self.boundEdit.setText("0,700,550,0")
        """
        self.checkBtn = QPushButton("查看")
        self.pathEdit.setObjectName("path")
        self.targetEdit.setObjectName("target")
        self.configEdit = QTextEdit()
        self.configEdit.setStyleSheet("""
            QTextEdit{font-size:14px;background:#3D1140;color:#FFFFFF;}
        """)
        self.configEdit.setFixedHeight(300)
        self.json_str = """
        {
            "一般公共预算收支科目":{
               "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "政府性基金预算收支科目":{
            "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "国有资本经营预算收支科目":{
              "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "社会保险基金预算收支科目":{
               "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "支出经济分类科目":{
             "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            }
        }
        """
        self.configEdit.setText(
            json.dumps(json.loads(self.json_str),
                       indent=4,
                       sort_keys=False,
                       ensure_ascii=False))
        self.json = {
            "一般公共预算收支科目": {},
            "政府性基金预算收支科目": {},
            "国有资本经营预算收支科目": {},
            "社会保险基金预算收支科目": {},
            "支出经济分类科目": {}
        }
        self.page_settings = QPushButton("")

        self.budgetLayout = QGridLayout()
        self.budgetLayout.setContentsMargins(10, 20, 10, 15)
        self.budgetLayout.addWidget(self.pathLab, 0, 0)
        self.budgetLayout.addWidget(self.pathEdit, 0, 1, 1, 3)
        self.budgetLayout.addWidget(self.targetLab, 1, 0)
        self.budgetLayout.addWidget(self.targetEdit, 1, 1, 1, 3)

        self.spiderBox = QGroupBox("文件下载")
        self.urlLab = QLabel("下载页地址:")
        self.urlEdit = QLineEdit()
        self.downloadLab = QLabel("文件下载路径:")
        self.downloadEdit = LineEdit()
        self.downloadEdit.setObjectName("download")

        self.downloadBtn = QPushButton("下载当前页文件")
        self.spiderLayout = QGridLayout()
        self.spiderLayout.addWidget(self.urlLab, 0, 0)
        self.spiderLayout.addWidget(self.urlEdit, 0, 1)
        # self.spiderLayout.addSpacing(20)
        self.spiderLayout.addWidget(self.downloadLab, 1, 0)
        self.spiderLayout.addWidget(self.downloadEdit, 1, 1)
        self.spiderLayout.addWidget(self.downloadBtn, 1, 2)
        self.spiderBox.setLayout(self.spiderLayout)

        url_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(
                r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
            ), self.urlEdit)
        self.urlEdit.setValidator(url_validator)

        self.budgetLayout.addWidget(self.spiderBox, 3, 0, 4, 4)
        # self.budgetLayout.addWidget(self.configEdit, 2, 0, 6, 4)
        self.budgetLayout.addWidget(self.comboBox, 8, 0, 1, 4)
        self.budgetLayout.addWidget(self.subLab, 9, 0)
        self.budgetLayout.addWidget(self.subEdit, 9, 1)
        # self.budgetLayout.addWidget(self.regxLab, 3, 2)
        # self.budgetLayout.addWidget(self.regxEdit, 3, 3)
        # self.budgetLayout.addWidget(self.posLab, 4, 2)
        # self.budgetLayout.addWidget(self.posEdit, 4, 3)

        self.budgetLayout.addWidget(self.codeLab, 9, 2)
        self.budgetLayout.addWidget(self.codeEdit, 9, 3)

        self.budgetLayout.addWidget(self.budgetLab, 10, 0)
        self.budgetLayout.addWidget(self.budgetEdit, 10, 1)
        self.budgetLayout.addWidget(self.actualLab, 10, 2)
        self.budgetLayout.addWidget(self.actualEdit, 10, 3)

        self.budgetLayout.addWidget(self.pageLab, 11, 0)
        self.budgetLayout.addWidget(self.pageEdit, 11, 1)
        self.budgetLayout.addWidget(self.pageInfoBtn, 11, 4)

        self.budgetLayout.addWidget(self.boundLab, 12, 0)
        self.budgetLayout.addWidget(self.boundEdit, 12, 1)
        self.budgetLayout.addWidget(self.currentPageLab, 12, 2)
        self.budgetLayout.addWidget(self.currentPageEdit, 12, 3)
        self.budgetLayout.addWidget(self.checkBtn, 12, 4)

        self.btnWidget = QWidget()
        self.btnLayout = QHBoxLayout()
        self.btnLayout.addWidget(self.initBtn)
        self.btnLayout.addSpacing(20)
        self.btnLayout.addWidget(self.extractBtn)
        self.btnLayout.addSpacing(20)
        self.btnLayout.addWidget(self.genBtn)

        # self.testBtn = QPushButton("测试")
        # self.btnLayout.addSpacing(20)
        # self.btnLayout.addWidget(self.testBtn)

        self.btnWidget.setLayout(self.btnLayout)
        self.budgetLayout.addWidget(self.btnWidget, 13, 0, 1, 4)

        # self.budgetLayout.addWidget(self.initBtn, 10, 0)
        # self.budgetLayout.addWidget(self.extractBtn, 10, 1)
        # self.budgetLayout.addWidget(self.genBtn, 10, 3)
        for i in range(14):
            self.budgetLayout.setRowMinimumHeight(i, 25)
        self.budgetBox.setLayout(self.budgetLayout)

        self.rightLayout.addWidget(self.dataBox)
        self.rightLayout.addSpacing(20)
        self.rightLayout.addWidget(self.budgetBox)
        self.rightLayout.addStretch(1)
        self.rightWidget.setLayout(self.rightLayout)

        # 节点全部展开
        self.treeWidget.expandAll()
        self.leftWidget = QWidget()
        self.leftLayout = QHBoxLayout()
        self.leftLayout.addWidget(self.treeWidget)

        self.leftWidget.setLayout(self.leftLayout)
        self.mainLayout = QHBoxLayout()
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        self.mainLayout.addStretch(1)
        self.mainLayout.addWidget(self.leftWidget)
        self.mainLayout.addStretch(1)
        self.mainLayout.addWidget(self.rightWidget)
        self.mainLayout.addStretch(1)
        self.centralWidget.setLayout(self.mainLayout)
        self.setMinimumSize(1200, 800)
        # 查找树
        self.tree = MultiTree({
            "id": 0,
            "pid": -1,
            "name": "政府科目",
            "code": "0"
        })
        # 预声明子线程
        self.initThread = RunThread(self.root, self.tree, "2020")
        self.downloadThread = DownloadThread("", "")
        # 子树对应字典
        self.tree_dict = {}
        self.sheet_name_list = [
            "一般公共预算收支科目", "政府性基金预算收支科目", "国有资本经营预算收支科目", "社会保险基金预算收支科目",
            "支出经济分类科目"
        ]

        self.connectBtn.clicked.connect(self.on_connect_clicked)
        self.pathEdit.clicked.connect(self.on_edit_double_clicked)
        self.checkBtn.clicked.connect(self.on_check_btn_clicked)

        self.targetEdit.clicked.connect(self.on_edit_double_clicked)
        self.downloadEdit.clicked.connect(self.on_edit_double_clicked)
        self.extractBtn.clicked.connect(self.on_extract_clicked)
        self.initBtn.clicked.connect(self.on_init_btn_clicked)
        self.genBtn.clicked.connect(self.on_gen_btn_clicked)
        self.downloadBtn.clicked.connect(self.on_download_btn_clicked)
        self.pageInfoBtn.clicked.connect(self.on_page_info_btn_clicked)
Esempio n. 48
0
File: tab.py Progetto: maphew/GDBee
    def __init__(self):
        """Initialize Tab with layout and behavior."""
        super(Tab, self).__init__()

        # regex pattern for SQL query block comments
        self.block_comment_re = re.compile(
            r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
            re.DOTALL | re.MULTILINE)

        main_layout = QVBoxLayout(self)

        # define gdb props
        self.gdb = None
        self.gdb_items = None
        self.gdb_columns_names = None
        self.gdb_schemas = None

        # connected geodatabase path toolbar
        self.connected_gdb_path_label = QLabel('')
        self.connected_gdb_path_label.setTextInteractionFlags(
            Qt.TextSelectableByMouse)
        self.connected_gdb_path_label.setToolTip(
            'Connected geodatabase that queries will be run against')
        self.connected_gdb_path_label.setText(not_connected_to_gdb_message)

        self.browse_to_gdb = QPushButton('Browse')
        self.browse_to_gdb.setShortcut(QKeySequence('Ctrl+B'))
        self.browse_to_gdb.clicked.connect(
            lambda evt, arg=True: self.connect_to_geodatabase(
                evt, triggered_with_browse=True))

        self.gdb_sql_dialect_combobox = QComboBox()
        for dialect in sql_dialects_names:
            self.gdb_sql_dialect_combobox.addItem(dialect)

        self.gdb_browse_toolbar = QToolBar()
        self.gdb_browse_toolbar.setMaximumHeight(50)
        self.gdb_browse_toolbar.addWidget(self.browse_to_gdb)
        self.gdb_browse_toolbar.addWidget(self.connected_gdb_path_label)
        self.gdb_browse_toolbar.addSeparator()
        self.gdb_browse_toolbar.addWidget(self.gdb_sql_dialect_combobox)

        # table with results
        self.table = ResultTable()

        # execute SQL query
        self.execute = QAction('Execute', self)
        self.execute.setShortcuts(
            [QKeySequence('F5'),
             QKeySequence('Ctrl+Return')])
        self.execute.triggered.connect(self.run_query)
        self.addAction(self.execute)

        # enter a SQL query
        self.query = TextEditor()
        self.query.setPlainText('')
        font = self.query.font()
        font.setFamily('Consolas')
        font.setStyleHint(QFont.Monospace)

        # TODO: add line numbers to the text editor
        font.setPointSize(14)
        self.query.setFont(font)
        self.query.setTabStopWidth(20)
        self.highlighter = Highlighter(self.query.document())

        # TODO select block of text - Ctrl+/ and they become comments
        self.completer = Completer()
        self.query.set_completer(self.completer.completer)

        # errors panel to show if query fails to execute properly
        self.errors_panel = QPlainTextEdit()
        font = self.query.font()
        font.setPointSize(12)
        self.errors_panel.setStyleSheet('color:red')
        self.errors_panel.setFont(font)
        self.errors_panel.hide()

        # splitter between the toolbar, query window, and the result set table
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.gdb_browse_toolbar)
        splitter.addWidget(self.query)
        splitter.addWidget(self.table)
        splitter.addWidget(self.errors_panel)

        # add the settings after the widget have been added
        splitter.setCollapsible(0, True)
        splitter.setCollapsible(1, False)
        splitter.setCollapsible(2, False)
        splitter.setCollapsible(3, False)
        splitter.setStretchFactor(0, 3)
        splitter.setStretchFactor(1, 7)
        splitter.setSizes((100, 200, 300))
        self.table.hide()

        # TOC
        self.toc = QTreeWidget()
        self.toc.setHeaderHidden(True)

        # second splitter between the TOC to the left and the query/table to the
        # right
        toc_splitter = QSplitter(Qt.Horizontal)
        toc_splitter.addWidget(self.toc)
        toc_splitter.addWidget(splitter)
        toc_splitter.setCollapsible(0, True)
        toc_splitter.setSizes((200, 800))  # set the TOC vs data panel

        main_layout.addWidget(toc_splitter)

        margins = QMargins()
        margins.setBottom(10)
        margins.setLeft(10)
        margins.setRight(10)
        margins.setTop(10)
        main_layout.setContentsMargins(margins)

        self.setLayout(main_layout)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.show()

        return
Esempio n. 49
0
class sender(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        MainLayout = QHBoxLayout(self)
        self.ContentTree = QTreeWidget(self)
        RightLayout = QGridLayout()
        MainLayout.addWidget(self.ContentTree)
        MainLayout.addLayout(RightLayout)

        Templates_Label = QLabel('Templates')
        self.Templates_ComboBox = QComboBox()
        Templates = ['TCP', 'UDP', 'ICMP', 'DNS']
        self.Templates_ComboBox.addItems(Templates)

        NumToSend_Label = QLabel('Num to send')
        self.NumToSend_SpinBox = QSpinBox()
        self.NumToSend_SpinBox.setValue(1)

        Interval_Label = QLabel('Interval')
        self.Interval_SpinBox = QDoubleSpinBox()
        self.Interval_SpinBox.setValue(0.0)

        Thread_Label = QLabel('Threads')
        self.Thread_SpinBox = QSpinBox()
        self.Thread_SpinBox.setValue(1)

        self.Follow_CheckBox = QCheckBox('Follow Stream')

        Send_Button = QPushButton('Send')
        Reset_Button = QPushButton('Reset')

        self.ContentTree.setColumnCount(2)
        self.ContentTree.setHeaderLabels(['Item', 'Detail'])

        RightLayout.addWidget(Templates_Label, 0, 0)
        RightLayout.addWidget(self.Templates_ComboBox, 0, 1)
        RightLayout.addWidget(NumToSend_Label, 1, 0)
        RightLayout.addWidget(self.NumToSend_SpinBox, 1, 1)
        RightLayout.addWidget(Interval_Label, 2, 0)
        RightLayout.addWidget(self.Interval_SpinBox, 2, 1)
        RightLayout.addWidget(Thread_Label, 3, 0)
        RightLayout.addWidget(self.Thread_SpinBox, 3, 1)
        RightLayout.addWidget(self.Follow_CheckBox, 4, 0)
        RightLayout.addWidget(Send_Button, 5, 0)
        RightLayout.addWidget(Reset_Button, 5, 1)
        RightLayout.setSpacing(15)
        RightLayout.setContentsMargins(10, 10, 10, 10)

        Send_Button.clicked.connect(self.SendPacket)
        Reset_Button.clicked.connect(self.reset_pkt)

        self.Templates_ComboBox.currentIndexChanged[int].connect(
            self.initTemplate)
        self.ContentTree.itemDoubleClicked[QTreeWidgetItem, int].connect(
            self.on_treeWidgetItem_doubleClicked)
        self.ContentTree.itemClicked[QTreeWidgetItem, int].connect(
            self.on_treeWidgetItem_itemClicked)
        self.initTemplate(0)

    def initPkt(self):
        self.ether_dic = {
            # 'dst': 'ff:ff:ff:ff:ff:ff',
            # 'src': '00:00:00:00:00:00',
            # 'type': 0x800
        }

        self.ip_dic = {
            # 'version': 4,
            # 'ihl': None,
            # 'tos': 0x0,
            # 'len': 0,
            # 'id': 0,
            # 'flags': 0,
            # 'ttl': 64,
            # 'proto': 'tcp',
            # 'chksum': None,
            # 'src': '127.0.0.1',
            # 'dst': '127.0.0.1'
        }
        self.tcp_dic = {
            # 'sport': 20,
            # 'dport': 80,
            # 'seq': 0,
            # 'ack': 0,
            # 'dataofs': None,
            # 'reserved': 0,
            # 'flags': 2,
            # 'window': 8192,
            # 'chksum': None,
            # 'urgptr': 0,
            # 'options': []
        }
        self.udp_dic = {}
        self.icmp_dic = {}
        self.dns_dic = {}
        self.data = b'payload'

    def SendPacket(self):
        if self.Templates_ComboBox.currentIndex() == 0:
            pkt = Ether(**self.ether_dic) / IP(**self.ip_dic) / TCP(
                **self.tcp_dic) / self.data
        elif self.Templates_ComboBox.currentIndex() == 1:
            pkt = Ether(**self.ether_dic) / IP(**self.ip_dic) / UDP(
                **self.udp_dic) / self.data
        elif self.Templates_ComboBox.currentIndex() == 2:
            pkt = Ether(**self.ether_dic) / IP(**self.ip_dic) / ICMP(
                **self.icmp_dic) / self.data
        elif self.Templates_ComboBox.currentIndex() == 3:
            pkt = Ether(**self.ether_dic) / IP(**self.ip_dic) / UDP(
                **self.udp_dic) / DNS(**self.dns_dic)

        baseNum = self.NumToSend_SpinBox.value() // self.Thread_SpinBox.value()
        remainderNum = self.NumToSend_SpinBox.value(
        ) % self.Thread_SpinBox.value()
        sendNum_list = [baseNum] * self.Thread_SpinBox.value()
        while remainderNum > 0:
            sendNum_list[remainderNum] += 1
            remainderNum -= 1
        tmp_thread = self.Thread_SpinBox.value()
        self.threadList = []  #avoid being garbage collected by Python.
        while tmp_thread > 0:
            thread = senderthread()
            self.threadList.append(thread)
            thread.set_send_num(sendNum_list[tmp_thread - 1])
            thread.set_interval(self.Interval_SpinBox.value())
            thread.set_pkt(pkt)
            thread.start()
            tmp_thread -= 1

        self.initPkt()

    def reset_pkt(self):
        self.initTemplate(self.Templates_ComboBox.currentIndex())

    def initTemplate(self, index):
        self.initPkt()
        # self.text = FakeOut()
        if index == 0:
            pkt = Ether() / IP() / TCP() / b'payload'
        elif index == 1:
            pkt = Ether() / IP() / UDP() / b'payload'
        elif index == 2:
            pkt = Ether() / IP() / ICMP() / b'payload'
        elif index == 3:
            pkt = Ether() / IP() / UDP() / DNS()
        # old = sys.stdout
        # sys.stdout = self.text
        # pkt.show2()
        # sys.stdout = old
        # tmp = self.text.str
        # self.formatString(tmp)
        self.packetDict = scapy2ordereddict.to_dict(pkt)
        self.buildTree()

    # def formatString(self, tmp):
    #     self.final_dict = collections.OrderedDict()
    #     title_pattern = re.compile(r'###[ [a-zA-Z]+ ]###')  #abstract titles
    #     tmp_titles = title_pattern.findall(tmp)
    #     self.titles = []
    #     for title in tmp_titles:
    #         refine_pattern = re.compile(r'###\[ | \]###')
    #         self.titles.append(refine_pattern.sub('', title))
    #     #print(self.titles)

    #     content_split_pattern = title_pattern  #abstract contents
    #     tmp_content = re.split(content_split_pattern, tmp)
    #     self.contents = [i for i in tmp_content if i != '']
    #     #print(self.contents)

    #     for (title, content) in zip(self.titles, self.contents):
    #         tmp_dict = {}
    #         tmp_lists = re.split(r'\n', content)
    #         tmp_lists = [i.replace(' ', '') for i in tmp_lists if i != '']

    #         #print(tmp_lists)
    #         for i in tmp_lists:
    #             tmp_item = i.split('=')
    #             #print(tmp_item)
    #             if len(tmp_item) == 2:
    #                 tmp_dict[tmp_item[0]] = tmp_item[1]
    #         self.final_dict[title] = tmp_dict
    #     #print(self.final_dict)

    def buildTree(self):
        self.ContentTree.clear()
        self.doubleclicked = False
        self.lastColumn = 0
        for title in self.packetDict.keys():
            tree_item = QTreeWidgetItem(self.ContentTree)
            tree_item.setText(0, title)
            tree_item.setExpanded(True)
            detail_dic = self.packetDict[title]
            for i in detail_dic.keys():
                #print(i,detail_dic[i])
                leaf = QTreeWidgetItem(tree_item, [i, str(detail_dic[i])])
                tree_item.addChild(leaf)
                leaf.setToolTip(1, str(detail_dic[i]))
                self.lastItem = tree_item
            self.ContentTree.addTopLevelItem(tree_item)

    def on_treeWidgetItem_doubleClicked(self, item, column):
        if column == 1:
            self.ContentTree.openPersistentEditor(item, column)
            self.pretext = item.text(1)
            self.doubleclicked = True
        self.lastColumn = column
        self.lastItem = item

    def on_treeWidgetItem_itemClicked(self, item, column):
        if self.lastColumn != column or self.lastItem != item:
            if self.doubleclicked:
                self.ContentTree.closePersistentEditor(self.lastItem,
                                                       self.lastColumn)
                self.doubleclicked = False
                if self.pretext != self.lastItem.text(1):
                    parent_title = self.lastItem.parent().text(0)
                    if parent_title == 'Ethernet':
                        self.ether_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'IP':
                        self.ip_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'UDP':
                        self.udp_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'TCP':
                        self.tcp_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'ICMP':
                        self.icmp_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'DNS':
                        self.dns_dic[self.lastItem.text(
                            0)] = self.lastItem.text(1)
                    elif parent_title == 'Raw':
                        self.data = self.lastItem.text(1)

        self.lastColumn = column
        self.lastItem = item
Esempio n. 50
0
 def __init__(self, parent):
     QTreeWidget.__init__(self)
     self.parent = parent  # type: NetworkChoiceLayout
     self.setHeaderLabels([_('Server'), _('Height')])
     self.setContextMenuPolicy(Qt.CustomContextMenu)
     self.customContextMenuRequested.connect(self.create_menu)
Esempio n. 51
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__()
        self.pageInfo = PageInfo("", "")
        self.setWindowTitle("河北腾云信息科技有限公司")
        self.icon = QtGui.QIcon()
        self.icon.addPixmap(QtGui.QPixmap("images/logo.ico"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(self.icon)
        self.treeWidget = QTreeWidget()
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.root = QTreeWidgetItem(self.treeWidget)
        self.treeWidget.addTopLevelItem(self.root)
        # self.setStyleSheet(helper.CommonHelper.read_css('./css/style.css'))

        # 设置列数
        self.treeWidget.setColumnCount(1)
        # 设置树形控件头部的标题
        self.treeWidget.setHeaderLabels(['财税大数据平台'])
        self.treeWidget.setFixedWidth(500)

        self.rightWidget = QWidget()
        self.rightLayout = QVBoxLayout()

        self.dataBox = QGroupBox("数据库连接")
        self.dataBox.setStyleSheet("QGroupBox{border: 1px solid black;}")
        self.connectBtn = QPushButton("生成查找树")

        self.yearLab = QLabel("年份")
        self.yearEdit = QLineEdit()

        self.dataLayout = QGridLayout()
        self.dataLayout.setContentsMargins(10, 20, 10, 15)
        self.hostLab = QLabel("主机名或ip地址:")
        self.portLab = QLabel("端口:")
        self.userLab = QLabel("用户名:")
        self.passLab = QLabel("密码")
        self.dbLab = QLabel("数据库名:")
        self.charsetLab = QLabel("字符集:")

        self.hostEdit = QLineEdit()
        self.userEdit = QLineEdit()
        self.portEdit = QLineEdit()
        self.passEdit = QLineEdit()
        self.dbEdit = QLineEdit()
        self.charsetEdit = QLineEdit()

        self.hostEdit.setText("192.168.110.201")
        self.portEdit.setText("3306")
        self.userEdit.setText("root")
        self.passEdit.setEchoMode(QLineEdit.Password)
        self.passEdit.setText("tengyun2020")
        self.dbEdit.setText("fiscal_tax")
        self.charsetEdit.setText("utf8")
        self.yearEdit.setText("2019")

        self.pageTextInfo = []

        self.dataLayout.addWidget(self.hostLab, 0, 0)
        self.dataLayout.addWidget(self.hostEdit, 0, 1)
        self.dataLayout.addWidget(self.portLab, 0, 2)
        self.dataLayout.addWidget(self.portEdit, 0, 3)
        self.dataLayout.addWidget(self.userLab, 0, 4)
        self.dataLayout.addWidget(self.userEdit, 0, 5)
        self.dataLayout.addWidget(self.yearLab, 0, 6)
        self.dataLayout.addWidget(self.yearEdit, 0, 7)
        self.dataLayout.addWidget(self.passLab, 1, 0)
        self.dataLayout.addWidget(self.passEdit, 1, 1)
        self.dataLayout.addWidget(self.dbLab, 1, 2)
        self.dataLayout.addWidget(self.dbEdit, 1, 3)
        self.dataLayout.addWidget(self.charsetLab, 1, 4)
        self.dataLayout.addWidget(self.charsetEdit, 1, 5)
        self.dataLayout.addWidget(self.connectBtn, 1, 7, 1, 1)

        self.dataBox.setLayout(self.dataLayout)

        self.budgetBox = QGroupBox("预决算信息提取")
        self.budgetBox.setStyleSheet("QGroupBox{border: 1px solid black;}")

        self.comboBox = QComboBox()
        self.comboBox.addItem("一般公共预算收支科目")
        self.comboBox.addItem("政府性基金预算收支科目")
        self.comboBox.addItem("国有资本经营预算收支科目")
        self.comboBox.addItem("社会保险基金预算收支科目")
        self.comboBox.addItem("支出经济分类科目")
        # self.comboBox.addItem("一般公共预算收入科目")
        # self.comboBox.addItem("一般公共预算支出科目")
        # self.comboBox.addItem("政府性基金预算收入科目")
        # self.comboBox.addItem("政府性基金预算支出科目")
        # self.comboBox.addItem("国有资本经营预算收入科目")
        # self.comboBox.addItem("国有资本经营预算支出科目")
        # self.comboBox.addItem("社会保险基金预算收入科目")
        # self.comboBox.addItem("社会保险基金预算支出科目")
        self.comboBox.setStyleSheet("""
                    QComboBox {border:none;background:#000000;color:#ffffff;
                    padding-left:30px;font-size:16px "SimHei";}
                    QComboBox QAbstractItemView {background:#000000;color:#ffffff;padding-left:30px;} 
                    QComboBox QAbstractItemView::item {min-height:30px;font-size:16px "SimHei";}
         """)
        self.comboBox.setView(QListView())
        self.pathLab = QLabel("文件路径:")
        self.extractBtn = QPushButton("提取信息")
        self.genBtn = QPushButton("生成Excel")
        self.initBtn = QPushButton("清空文件")
        self.codeLab = QLabel("科目编码:")
        self.subLab = QLabel("科目名称:")
        self.budgetLab = QLabel("预算数:")
        self.actualLab = QLabel("决算数:")
        self.pageLab = QLabel("页码:")
        self.pageInfoBtn = QPushButton("页面信息")
        self.regxLab = QLabel("分割符:")
        self.posLab = QLabel("名称位置:")
        self.targetLab = QLabel("目标文件路径:")
        self.boundLab = QLabel("pdf无边框表格位置:")
        self.currentPageLab = QLabel("无边框表格页码:")

        self.pathEdit = LineEdit()
        self.codeEdit = QLineEdit()
        self.subEdit = QLineEdit()
        self.budgetEdit = QLineEdit()
        self.actualEdit = QLineEdit()
        self.pageEdit = QLineEdit()
        self.regxEdit = QLineEdit()
        self.posEdit = QLineEdit()
        self.targetEdit = LineEdit()
        self.boundEdit = QLineEdit()
        self.currentPageEdit = QLineEdit()

        current_page_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"^[1-9]\d*$"), self.currentPageEdit)
        self.currentPageEdit.setValidator(current_page_validator)

        page_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(-[1-9]\d*)||(^[1-9]\d*)(,[1-9]\d*)+"),
            self.pageEdit)
        self.pageEdit.setValidator(page_validator)

        sub_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.subEdit)
        self.subEdit.setValidator(sub_validator)

        code_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.codeEdit)
        self.codeEdit.setValidator(code_validator)

        budget_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.budgetEdit)
        self.budgetEdit.setValidator(budget_validator)

        actual_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[1-9]\d*)(,[1-9]\d*)+"), self.actualEdit)
        self.actualEdit.setValidator(actual_validator)

        bound_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(r"(^[0-9]\d*)(,[0-9]\d*)+"), self.boundEdit)
        self.boundEdit.setValidator(bound_validator)
        """
        self.pathEdit.setText("C:/Users/localhost/Desktop/bb/新乐市2019年政府预算公开附表.xlsx")
        self.targetEdit.setText("C:/Users/localhost/Desktop/cc")
        self.subEdit.setText("1")
        self.codeEdit.setText("")
        self.budgetEdit.setText("2")
        self.actualEdit.setText("")
        self.pageEdit.setText("1")
        self.boundEdit.setText("0,700,550,0")
        """
        self.checkBtn = QPushButton("查看")
        self.pathEdit.setObjectName("path")
        self.targetEdit.setObjectName("target")
        self.configEdit = QTextEdit()
        self.configEdit.setStyleSheet("""
            QTextEdit{font-size:14px;background:#3D1140;color:#FFFFFF;}
        """)
        self.configEdit.setFixedHeight(300)
        self.json_str = """
        {
            "一般公共预算收支科目":{
               "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "政府性基金预算收支科目":{
            "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "国有资本经营预算收支科目":{
              "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "社会保险基金预算收支科目":{
               "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            },
            "支出经济分类科目":{
             "parsed":{ 
                    "page":"",
                    "code":"",
                    "budget":"",
                    "actual":"",
                    "type":""
                },
               "unparsed":{ 
                    "page":"",
                    "name":"",
                    "budget":"",
                    "actual":"",
                    "regex":{
                        "sep":"",
                        "pos":""
                    },
                    "type":""
                }
            }
        }
        """
        self.configEdit.setText(
            json.dumps(json.loads(self.json_str),
                       indent=4,
                       sort_keys=False,
                       ensure_ascii=False))
        self.json = {
            "一般公共预算收支科目": {},
            "政府性基金预算收支科目": {},
            "国有资本经营预算收支科目": {},
            "社会保险基金预算收支科目": {},
            "支出经济分类科目": {}
        }
        self.page_settings = QPushButton("")

        self.budgetLayout = QGridLayout()
        self.budgetLayout.setContentsMargins(10, 20, 10, 15)
        self.budgetLayout.addWidget(self.pathLab, 0, 0)
        self.budgetLayout.addWidget(self.pathEdit, 0, 1, 1, 3)
        self.budgetLayout.addWidget(self.targetLab, 1, 0)
        self.budgetLayout.addWidget(self.targetEdit, 1, 1, 1, 3)

        self.spiderBox = QGroupBox("文件下载")
        self.urlLab = QLabel("下载页地址:")
        self.urlEdit = QLineEdit()
        self.downloadLab = QLabel("文件下载路径:")
        self.downloadEdit = LineEdit()
        self.downloadEdit.setObjectName("download")

        self.downloadBtn = QPushButton("下载当前页文件")
        self.spiderLayout = QGridLayout()
        self.spiderLayout.addWidget(self.urlLab, 0, 0)
        self.spiderLayout.addWidget(self.urlEdit, 0, 1)
        # self.spiderLayout.addSpacing(20)
        self.spiderLayout.addWidget(self.downloadLab, 1, 0)
        self.spiderLayout.addWidget(self.downloadEdit, 1, 1)
        self.spiderLayout.addWidget(self.downloadBtn, 1, 2)
        self.spiderBox.setLayout(self.spiderLayout)

        url_validator = QtGui.QRegExpValidator(
            QtCore.QRegExp(
                r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
            ), self.urlEdit)
        self.urlEdit.setValidator(url_validator)

        self.budgetLayout.addWidget(self.spiderBox, 3, 0, 4, 4)
        # self.budgetLayout.addWidget(self.configEdit, 2, 0, 6, 4)
        self.budgetLayout.addWidget(self.comboBox, 8, 0, 1, 4)
        self.budgetLayout.addWidget(self.subLab, 9, 0)
        self.budgetLayout.addWidget(self.subEdit, 9, 1)
        # self.budgetLayout.addWidget(self.regxLab, 3, 2)
        # self.budgetLayout.addWidget(self.regxEdit, 3, 3)
        # self.budgetLayout.addWidget(self.posLab, 4, 2)
        # self.budgetLayout.addWidget(self.posEdit, 4, 3)

        self.budgetLayout.addWidget(self.codeLab, 9, 2)
        self.budgetLayout.addWidget(self.codeEdit, 9, 3)

        self.budgetLayout.addWidget(self.budgetLab, 10, 0)
        self.budgetLayout.addWidget(self.budgetEdit, 10, 1)
        self.budgetLayout.addWidget(self.actualLab, 10, 2)
        self.budgetLayout.addWidget(self.actualEdit, 10, 3)

        self.budgetLayout.addWidget(self.pageLab, 11, 0)
        self.budgetLayout.addWidget(self.pageEdit, 11, 1)
        self.budgetLayout.addWidget(self.pageInfoBtn, 11, 4)

        self.budgetLayout.addWidget(self.boundLab, 12, 0)
        self.budgetLayout.addWidget(self.boundEdit, 12, 1)
        self.budgetLayout.addWidget(self.currentPageLab, 12, 2)
        self.budgetLayout.addWidget(self.currentPageEdit, 12, 3)
        self.budgetLayout.addWidget(self.checkBtn, 12, 4)

        self.btnWidget = QWidget()
        self.btnLayout = QHBoxLayout()
        self.btnLayout.addWidget(self.initBtn)
        self.btnLayout.addSpacing(20)
        self.btnLayout.addWidget(self.extractBtn)
        self.btnLayout.addSpacing(20)
        self.btnLayout.addWidget(self.genBtn)

        # self.testBtn = QPushButton("测试")
        # self.btnLayout.addSpacing(20)
        # self.btnLayout.addWidget(self.testBtn)

        self.btnWidget.setLayout(self.btnLayout)
        self.budgetLayout.addWidget(self.btnWidget, 13, 0, 1, 4)

        # self.budgetLayout.addWidget(self.initBtn, 10, 0)
        # self.budgetLayout.addWidget(self.extractBtn, 10, 1)
        # self.budgetLayout.addWidget(self.genBtn, 10, 3)
        for i in range(14):
            self.budgetLayout.setRowMinimumHeight(i, 25)
        self.budgetBox.setLayout(self.budgetLayout)

        self.rightLayout.addWidget(self.dataBox)
        self.rightLayout.addSpacing(20)
        self.rightLayout.addWidget(self.budgetBox)
        self.rightLayout.addStretch(1)
        self.rightWidget.setLayout(self.rightLayout)

        # 节点全部展开
        self.treeWidget.expandAll()
        self.leftWidget = QWidget()
        self.leftLayout = QHBoxLayout()
        self.leftLayout.addWidget(self.treeWidget)

        self.leftWidget.setLayout(self.leftLayout)
        self.mainLayout = QHBoxLayout()
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        self.mainLayout.addStretch(1)
        self.mainLayout.addWidget(self.leftWidget)
        self.mainLayout.addStretch(1)
        self.mainLayout.addWidget(self.rightWidget)
        self.mainLayout.addStretch(1)
        self.centralWidget.setLayout(self.mainLayout)
        self.setMinimumSize(1200, 800)
        # 查找树
        self.tree = MultiTree({
            "id": 0,
            "pid": -1,
            "name": "政府科目",
            "code": "0"
        })
        # 预声明子线程
        self.initThread = RunThread(self.root, self.tree, "2020")
        self.downloadThread = DownloadThread("", "")
        # 子树对应字典
        self.tree_dict = {}
        self.sheet_name_list = [
            "一般公共预算收支科目", "政府性基金预算收支科目", "国有资本经营预算收支科目", "社会保险基金预算收支科目",
            "支出经济分类科目"
        ]

        self.connectBtn.clicked.connect(self.on_connect_clicked)
        self.pathEdit.clicked.connect(self.on_edit_double_clicked)
        self.checkBtn.clicked.connect(self.on_check_btn_clicked)

        self.targetEdit.clicked.connect(self.on_edit_double_clicked)
        self.downloadEdit.clicked.connect(self.on_edit_double_clicked)
        self.extractBtn.clicked.connect(self.on_extract_clicked)
        self.initBtn.clicked.connect(self.on_init_btn_clicked)
        self.genBtn.clicked.connect(self.on_gen_btn_clicked)
        self.downloadBtn.clicked.connect(self.on_download_btn_clicked)
        self.pageInfoBtn.clicked.connect(self.on_page_info_btn_clicked)
        # self.testBtn.clicked.connect(self.find_code_by_name)

    @pyqtSlot()
    def on_page_info_btn_clicked(self):
        if self.pageEdit.text().strip() == "":
            QMessageBox.information(self, "提示", '    页码不能为空!    ')
            return
        page = process_param(self.pageEdit.text().strip())
        if len(page) > 0:
            suffix = self.pathEdit.text().split(".")[-1]
            if suffix.lower() == "doc" or suffix.lower(
            ) == "docx" or suffix.lower() == "pdf":
                pdf = camelot.read_pdf(self.pathEdit.text().strip().replace(
                    "docx", "pdf").replace("doc", "pdf"),
                                       flavor='stream',
                                       pages=str(page[0]))
                print(len(pdf))
                if len(pdf) > 0:
                    info = ""
                    for i, row in enumerate(pdf[0].df.values.tolist()):
                        info += ",".join(row) + "\n"
                    self.pageInfo = PageInfo(page[0], info)
                    self.pageInfo.setWindowModality(QtCore.Qt.ApplicationModal)
                    self.pageInfo.show()
            elif suffix.lower() == "xls" or suffix.lower() == "xlsx":
                wb = xlrd.open_workbook(self.pathEdit.text().strip())
                sheet_names = wb.sheet_names()
                info = "\n"
                for i, sheet_name in enumerate(sheet_names):
                    info += str(i + 1) + "\t" + sheet_name + "\n"
                self.pageInfo = PageInfo(page[0], info)
                self.pageInfo.setWindowModality(QtCore.Qt.ApplicationModal)
                self.pageInfo.show()
            else:
                pass

    @pyqtSlot()
    def on_download_btn_clicked(self):
        if self.urlEdit.text().strip() == "":
            QMessageBox.information(self, "提示", '    url地址不能为空!    ')
            return
        if self.downloadEdit.text().strip() == "":
            QMessageBox.information(self, "提示", '    文件夹地址不能为空!    ')
            return

        self.downloadThread = DownloadThread(
            url=self.urlEdit.text().strip(),
            path=self.downloadEdit.text().strip())
        self.downloadThread.resSignal.connect(
            lambda _msg: self.on_download_thread(_msg))
        self.downloadThread.start()

        # downloader = DownLoader(timeout=30, url=self.urlEdit.text().strip(), path=self.downloadEdit.text().strip())
        # downloader.download_file()
        # QMessageBox.information(self, "提示", '    文件下载完成!    ')
        # pass

    # @staticmethod
    # def check_excel_is_open(path):
    #     file_name = path.split("\\")[-1]
    #     print(file_name)
    #     print(path)
    #     print(path.replace(file_name, '~$' + file_name))
    #     if os.path.exists(path.replace(file_name, '~$' + file_name)):
    #         print("True")
    #         return True
    #     print("False")
    #     return False

    @pyqtSlot()
    def on_gen_btn_clicked(self):
        if len(self.json) > 0:
            # print(os.path.join(self.targetEdit.text().strip(), "预决算.xls"))
            # if self.check_excel_is_open(os.path.join(self.targetEdit.text().strip().replace("/", "\\"), "预决算.xls")):
            #     QMessageBox.information(self, "提示", '    Excel文件已经打开,请先关闭!    ')
            #     return
            excel_writer = Excel(
                os.path.join(self.targetEdit.text().strip().replace("/", "\\"),
                             "预决算.xls"), self.sheet_name_list, self.json)
            try:
                excel_writer.write_excel()
            except:
                QMessageBox.information(self, "提示", '    写入失败查看是否文件已经打开!    ')
                return

            QMessageBox.information(self, "提示", '    Json信息写入Excel成功!    ')

    @pyqtSlot()
    def on_init_btn_clicked(self):
        try:
            if self.targetEdit.text().strip() == "" or not os.path.isdir(
                    self.targetEdit.text().strip()):
                QMessageBox.information(self, "提示", '    输入不能为空,或者路径有错误!    ')
            else:
                self.json.clear()
                for file in os.listdir(self.targetEdit.text().strip().replace(
                        "/", "\\")):
                    # print(os.path.join(self.targetEdit.text().strip().replace("/", "\\"), file))
                    if os.path.isfile(
                            os.path.join(
                                self.targetEdit.text().strip().replace(
                                    "/", "\\"), file)):
                        try:
                            os.remove(
                                os.path.join(
                                    self.targetEdit.text().strip().replace(
                                        "/", "\\"), file))
                        except:
                            QMessageBox.information(self, "提示",
                                                    '    删除文件失败请查看是否打开!    ')
                            return
                QMessageBox.information(self, "提示", '    清空文件成功!    ')
        except Exception as e:
            QMessageBox.information(self, "提示", e)

    @pyqtSlot()
    def on_check_btn_clicked(self):
        # self.find_code_by_name()
        if self.currentPageEdit.text().strip() == "" or self.pathEdit.text(
        ).strip() == "":
            QMessageBox.information(self, "提示", '    输入不能为空!    ')
            return
        elif not self.pathEdit.text().strip().endswith(".pdf"):
            QMessageBox.information(self, "提示", '    只有PDF文件需要次操作!    ')
            return
        else:
            print(self.pathEdit.text().strip().replace('.docx',
                                                       '.pdf').replace(
                                                           ".doc", '.pdf'))
            pdf = camelot.read_pdf(self.pathEdit.text().strip().replace(
                '.docx', '.pdf').replace(".doc", '.pdf'),
                                   flavor='stream',
                                   pages=self.currentPageEdit.text().strip())
            if pdf:
                plt = camelot.plot(pdf[0], kind='textedge')
                plt.show()
                axis('tight')
                fig = pylab.gcf()
                fig.canvas.set_window_title(
                    "第" + self.currentPageEdit.text().strip() + "页表格解析示意图")

    @pyqtSlot()
    def on_extract_clicked(self):
        # print(self.tree_dict)
        # self.find_code("")
        #
        if len(self.tree_dict) == 0:
            QMessageBox.information(self, "提示", '    未生成查找树!    ')
            return
        if self.pathEdit.text().strip() == "" or self.targetEdit.text().strip(
        ) == "":
            QMessageBox.information(self, "提示", '    文件路径和目标路径不能为空!    ')
            return
        if self.pageEdit.text().strip() == "":
            QMessageBox.information(self, "提示", '    页码不能为空!    ')
            return
        if self.budgetEdit.text().strip() == "" and self.actualEdit.text(
        ).strip() == "":
            QMessageBox.information(self, "提示", '    预算数、决算数不能同时为空!    ')
            return
        if self.subEdit.text().strip() == "" and self.codeEdit.text().strip(
        ) == "":
            QMessageBox.information(self, "提示", '    科目名称和科目编码不能同时为空!    ')
            return
        if self.subEdit.text().strip() != "" and self.codeEdit.text().strip(
        ) != "":
            QMessageBox.information(self, "提示", '    科目名称和科目编码不能同时非空!    ')
            return
        try:
            process_file(self.pathEdit.text().strip())
            suffix = self.pathEdit.text().split(".")[-1]
            # print(self.pathEdit.text())
            page = process_param(self.pageEdit.text().strip())
            if suffix.lower() == "doc" or suffix.lower(
            ) == "docx" or suffix.lower() == "pdf":
                bound_info = self.boundEdit.text().strip()
                print(bound_info)
                if bound_info != "":
                    if bound_info.endswith(","):
                        bound_info = bound_info.rstrip(",")
                    # print(page)
                    if len(page) > 0:
                        # print((list(map(str, page))))
                        pdf = camelot.read_pdf(self.pathEdit.text().strip(),
                                               flavor='stream',
                                               pages=','.join(
                                                   list(map(str, page))),
                                               table_areas=[bound_info])
                        print(len(pdf))
                        for i in range(len(pdf)):
                            table_list = []
                            for row_data in pdf[i].df.values.tolist():
                                table_list.append(row_data)
                            self.parse(table_list)
                        QMessageBox.information(self, "提示", '    提取信息结束!    ')
                        print(self.json)
                else:
                    """
                    pdf = pdfplumber.open(self.pathEdit.text().strip())
                    # print(pdf.pages)
                    # print(len(pdf.pages))
                    # print(page)
                    for i, _page in enumerate(pdf.pages):
                        if i + 1 in page:
                            table_list = []
                            print(_page.extract_text())
                            for pdf_table in _page.extract_tables():
                                for row in pdf_table:
                                    table_list.append(row)
                                    print(row)
                            print(table_list)
                            self.parse(table_list)
                    """
                    if len(page) > 0:
                        # print((list(map(str, page))))
                        if suffix.lower() == "doc" or suffix.lower() == "docx":
                            pdf = camelot.read_pdf(
                                self.pathEdit.text().strip().replace(
                                    "." + suffix, ".pdf"),
                                flavor='stream',
                                pages=','.join(list(map(str, page))))
                        else:
                            pdf = camelot.read_pdf(
                                self.pathEdit.text().strip(),
                                flavor='stream',
                                pages=','.join(list(map(str, page))))
                        # print(len(pdf))
                        for i in range(len(pdf)):
                            table_list = []
                            for row_data in pdf[i].df.values.tolist():
                                table_list.append(row_data)
                            self.parse(table_list)
                    QMessageBox.information(self, "提示", '    提取信息结束!    ')

            elif suffix.lower() == "xls" or suffix.lower() == "xlsx":
                wb = xlrd.open_workbook(self.pathEdit.text().strip())
                sheet_names = wb.sheet_names()
                for i, sheet_name in enumerate(sheet_names):
                    # print(sheet_name)
                    if i + 1 in page:
                        table = wb.sheet_by_index(i)
                        table_list = []
                        print(table.nrows)

                        for ii in range(table.nrows):
                            # print(type(table.row_values(ii)))
                            # print(table.row_values(ii))
                            table_list.append(table.row_values(ii))
                        print(table_list)
                        self.parse(table_list)
                QMessageBox.information(self, "提示", '    提取信息结束!    ')
        except:
            QMessageBox.information(self, "提示", "提取信息失败请查看输入是否有误!")

    @pyqtSlot()
    def find_code_by_name(self):
        """
        Test of new method for finding the code
        :param name_list:
        :return:
        """
        pdf = camelot.read_pdf(r'C:\Users\localhost\Desktop\政府性基金预算支出表.pdf',
                               flavor='stream',
                               pages='1')
        for i in range(len(pdf)):
            name_list = []
            for row_data in pdf[i].df.values.tolist():
                name = re.sub(r'\s+', '', row_data[0])
                name = name.split("、")[-1]
                name = name.split(":")[-1]
                if name.strip() != "":
                    name_list.append(name.strip())
            self.tree.prepare_search_name(self.tree_dict.get("政府性基金预算收支科目"))
            res = []
            for name in name_list:
                res.append(self.tree.search_node_by_name(name, 0.8))
            for item in res:
                print(item)

        pass

    def backtracking(self, index, data_list, res=[]):
        if index == len(data_list) - 1:
            return
        if len(data_list[index]) == 0:
            return
        for data in data_list:
            res_temp = res[:]
            if len(res_temp) == 0:
                pass
            for item in res_temp:
                if data.get("pid") == item.get("id"):
                    pass

        pass

    def find_code(self, name_list):
        """
        print(self.comboBox.currentText())
        print(self.tree_dict.get(self.comboBox.currentText()))
        name_list = ["一般公共服务支出", "人大事务", "行政运行", "政协事务", "行政运行", "机关服务", "教育支出", "教育管理事务", "行政运行"]
        name_list = ["我拉个区", "一般公共服务支出", "援助其他地区支出", "垃圾", "一般公共服务", "国防支出", "公共安全支出", "教育支出"]
        name_list = ["一般公共服务支出", "援助其他地区支出", "一般公共服务", "国防支出", "公共安全支出", "教育支出"]
        """
        try:
            self.tree.prepare_search_name(
                self.tree_dict.get(self.comboBox.currentText()))
            res = []
            mark = ""
            for i, name in enumerate(name_list):
                search_res = self.tree.search_name(name)
                # print(search_res)
                # res.append(search_res)
                if len(search_res) == 1:
                    mark = search_res[0]
                    # print(i, search_res[0])
                    res.append((i, mark))
                elif len(search_res) > 1:
                    search_res.sort(key=lambda j: len(j))
                    for search_item in search_res:
                        if search_item.startswith(mark):
                            # print(i, search_item)
                            mark = search_item
                            res.append((i, mark))
                            break
                        elif len(search_item) == len(mark):
                            # print(i, search_item)
                            mark = search_item
                            res.append((i, mark))
                            break
            return res
        except Exception as e:
            QMessageBox.information(self, "提示", e)

    def parse(self, data_list):
        # print(data_list)
        try:
            if len(data_list) == 0:
                QMessageBox.information(self, "提示", '    表格解析失败!    ')
                return
            budget_num = process_param(self.budgetEdit.text().strip())
            actual_num = process_param(self.actualEdit.text().strip())
            if self.codeEdit.text().strip() != "":
                code_num = process_param(self.codeEdit.text().strip())
                if (len(budget_num) > 0 and len(budget_num) != len(code_num)
                    ) or (len(actual_num) > 0
                          and len(actual_num) != len(code_num)):
                    QMessageBox.information(self, "提示", '    长度不对应!    ')
                    return
                if (len(budget_num) > 0 and budget_num[-1] > len(data_list[0])
                    ) or (len(actual_num) > 0 and actual_num[-1] > len(
                        data_list[0])) or code_num[-1] > len(data_list[0]):
                    QMessageBox.information(self, "提示", '    列数越界!    ')
                    return
                for data in data_list:
                    for i in range(len(code_num)):
                        key = re.sub(r'\s+', '', str(data[code_num[i] - 1]))
                        # print(key)
                        if isinstance(data[code_num[i] - 1], float):
                            key = str(int(data[code_num[i] - 1]))
                        if key and key.isdigit():
                            if len(budget_num) > 0:
                                if self.json.get(self.comboBox.currentText().
                                                 strip()).get(key):
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).get(key).update(
                                        {"预算数": data[budget_num[i] - 1]})
                                else:
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).update({
                                        key: {
                                            "预算数": data[budget_num[i] - 1]
                                        }
                                    })
                            if len(actual_num) > 0:
                                if self.json.get(self.comboBox.currentText().
                                                 strip()).get(key):
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).get(key).update(
                                        {"决算数": data[actual_num[i] - 1]})
                                else:
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).update({
                                        key: {
                                            "决算数": data[actual_num[i] - 1]
                                        }
                                    })
            else:
                sub_num = process_param(self.subEdit.text().strip())
                if (len(budget_num) > 0 and len(budget_num) != len(sub_num)
                    ) or (len(actual_num) > 0
                          and len(actual_num) != len(sub_num)):
                    QMessageBox.information(self, "提示", '    长度不对应!    ')
                    return
                if (len(budget_num) > 0 and budget_num[-1] > len(data_list[0])
                    ) or (len(actual_num) > 0 and actual_num[-1] > len(
                        data_list[0])) or sub_num[-1] > len(data_list[0]):
                    QMessageBox.information(self, "提示", '    列数越界!    ')
                    return
                name_list = []
                for i in range(len(data_list)):
                    row_name = []
                    for j in range(len(sub_num)):
                        name = re.sub(r'\s+', '', data_list[i][sub_num[j] - 1])
                        name = name.split("、")[-1]
                        name = name.split(":")[-1]
                        row_name.append(name)
                    name_list.append(row_name)
                name_array = np.array(name_list)
                for j in range(len(sub_num)):
                    for index_code in self.find_code(name_array[:,
                                                                j].tolist()):
                        key = index_code[1]
                        if key.isdigit():
                            if len(budget_num) > 0:
                                if self.json.get(self.comboBox.currentText().
                                                 strip()).get(key):
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).get(key).update({
                                        "预算数":
                                        data_list[index_code[0]][budget_num[j]
                                                                 - 1]
                                    })
                                else:
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).update({
                                        key: {
                                            "预算数":
                                            data_list[index_code[0]][
                                                budget_num[j] - 1]
                                        }
                                    })
                            if len(actual_num) > 0:
                                print("------------>", actual_num[j] - 1,
                                      type(actual_num[j]))
                                print("___________", data_list[index_code[0]])
                                if self.json.get(self.comboBox.currentText().
                                                 strip()).get(key):
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).get(key).update({
                                        "决算数":
                                        data_list[index_code[0]][actual_num[j]
                                                                 - 1]
                                    })
                                else:
                                    self.json.get(self.comboBox.currentText(
                                    ).strip()).update({
                                        key: {
                                            "决算数":
                                            data_list[index_code[0]][
                                                actual_num[j] - 1]
                                        }
                                    })
        except Exception as e:
            QMessageBox.information(self, "提示", e)

    # def check_input(self, num, budget, actual, data):
    #     if (len(budget) > 0 and len(budget) != len(num)) or (
    #             len(actual) > 0 and len(actual) != len(num)):
    #         QMessageBox.information(self, "提示", '    长度不对应!    ')
    #         return
    #     if budget[-1] >= len(data[0]) or actual[-1] >= len(data[0]) or num[-1] >= len(
    #             data[0]):
    #         QMessageBox.information(self, "提示", '    列数越界!    ')
    #         return

    @pyqtSlot()
    def on_edit_double_clicked(self):
        if self.sender().objectName() == "path":
            filepath = QFileDialog.getOpenFileName(self, "请选择文件路径", "/")
            if filepath:
                self.pathEdit.setText(filepath[0].strip())
        elif self.sender().objectName() == "target":
            directory = QFileDialog.getExistingDirectory(self, "请选择文件夹路径", "/")
            if directory:
                self.targetEdit.setText(directory.strip())
        elif self.sender().objectName() == "download":
            directory = QFileDialog.getExistingDirectory(self, "请选择文件夹路径", "/")
            if directory:
                self.downloadEdit.setText(directory.strip())
        else:
            pass

    @pyqtSlot()
    def on_connect_clicked(self):
        print("connect button is clicked!")
        if self.hostEdit.text().strip() == "" or self.portEdit.text().strip(
        ) == "" or self.userEdit.text().strip() == "" or self.yearEdit.text(
        ).strip() == "" or self.passEdit.text().strip(
        ) == "" or self.dbEdit.text().strip() == "" or self.charsetEdit.text(
        ).strip() == "":
            QMessageBox.information(self, "提示", '    输入不能为空!    ')

        else:
            year = self.yearEdit.text().strip()
            self.tree = MultiTree({
                "id": 0,
                "pid": -1,
                "name": year + "年政府科目",
                "code": "0"
            })

            self.treeWidget.clear()
            self.root = QTreeWidgetItem(self.treeWidget)
            self.root.setText(0, year + "年树状结构生成中...")
            self.treeWidget.addTopLevelItem(self.root)

            self.initThread = RunThread(self.root, self.tree, year)
            self.initThread.resSignal.connect(
                lambda _year, _tree: self.on_init_thread(_year, _tree))
            self.initThread.start()

    @pyqtSlot()
    def on_download_thread(self, msg):
        if msg == "ok":
            QMessageBox.information(self, "提示", '    文件下载成功!    ')
        elif msg == "fail":
            QMessageBox.information(self, "提示", '    文件下载失败!    ')
        else:
            pass
            # QMessageBox.information(self, "提示", msg)

    @pyqtSlot()
    def on_init_thread(self, year, tree):
        self.tree = tree
        self.root.setText(0, year + "年树状结构")
        # 遍历树状结构
        # self.tree.traverse(self.tree)
        self.tree_dict.clear()
        self.generate_tree_dict()
        self.treeWidget.expandAll()

    def generate_tree_dict(self):
        self.tree_dict.update({
            "一般公共预算收入":
            self.tree.tree.children[0].children[0],
            "一般公共预算支出":
            self.tree.tree.children[0].children[1],
            "政府性基金预算收入":
            self.tree.tree.children[1].children[0],
            "政府性基金预算支出":
            self.tree.tree.children[1].children[1],
            "国有资本经营预算收入":
            self.tree.tree.children[2].children[0],
            "国有资本经营预算支出":
            self.tree.tree.children[2].children[1],
            "社会保险基金预算收入":
            self.tree.tree.children[3].children[0],
            "社会保险基金预算支出":
            self.tree.tree.children[3].children[1],
            "支出经济分类科目":
            self.tree.tree.children[4],
            "一般公共预算收支科目":
            self.tree.tree.children[0],
            "政府性基金预算收支科目":
            self.tree.tree.children[1],
            "国有资本经营预算收支科目":
            self.tree.tree.children[2],
            "社会保险基金预算收支科目":
            self.tree.tree.children[3]
        })
Esempio n. 52
0
class NTFSLogFileDialog(QDialog, QObject):
    complete = pyqtSignal()

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        QObject.__init__(self)
        self.selectedPartition = -1
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Import File System Log File")
        # self.setFixedSize(570, 300)
        self.setFixedSize(self.sizeHint())
        self.layout = QBoxLayout(QBoxLayout.TopToBottom, self)
        self.spacerItem1 = QSpacerItem(10, 5)
        self.layout.addItem(self.spacerItem1)
        self.setLayout(self.layout)

        # First Group
        self.diskRawChkBox = QCheckBox(
            "In this case, it's possible to carve some files.", self)
        self.diskRawChkBox.stateChanged.connect(
            lambda: self.selectedType(self.diskRawChkBox))
        self.diskRawGroupBox = QGroupBox(self)
        self.diskRawGroupBox.setStyleSheet("margin-top: 0;")
        self.diskRawGroupBox.setDisabled(True)
        diskRawGroupBoxLayout = QHBoxLayout(self.diskRawGroupBox)
        self.diskRawGroupBox.setLayout(diskRawGroupBoxLayout)

        self.diskRawLabel = QLabel("Disk Raw: ", self)
        self.diskRawTextBox = QLineEdit()
        self.diskRawTextBox.setReadOnly(True)
        self.diskRawTextBox.setFixedWidth(400)

        self.browseDiskRawBtn = QPushButton("...", self)
        self.browseDiskRawBtn.setFixedWidth(50)
        self.browseDiskRawBtn.clicked.connect(self.btnClicekd)
        self.browseDiskRawBtn.setCursor(QCursor(Qt.PointingHandCursor))

        diskRawGroupBoxLayout.addWidget(self.diskRawLabel)
        diskRawGroupBoxLayout.addWidget(self.diskRawTextBox)
        diskRawGroupBoxLayout.addWidget(self.browseDiskRawBtn)

        self.layout.addWidget(self.diskRawChkBox)
        self.layout.addWidget(self.diskRawGroupBox)

        # Second Group
        self.ntfsLogFileChkBox = QCheckBox(
            "In this case, NTFS Log analysis only supported.", self)
        self.ntfsLogFileChkBox.stateChanged.connect(
            lambda: self.selectedType(self.ntfsLogFileChkBox))

        self.ntfsLogGroupBox = QGroupBox(self)
        self.ntfsLogGroupBox.setStyleSheet("margin-top: 0;")
        self.ntfsLogGroupBox.setDisabled(True)
        ntfsLogGroupBoxLayout = QGridLayout(self)
        self.ntfsLogGroupBox.setLayout(ntfsLogGroupBoxLayout)

        self.mftLabel = QLabel("$MFT: ", self)
        self.mftPathTextBox = QLineEdit(self)
        self.mftPathTextBox.setReadOnly(True)
        self.mftPathTextBox.setFixedWidth(400)
        self.browseMFTBtn = QPushButton("...", self)
        self.browseMFTBtn.setFixedWidth(50)
        self.browseMFTBtn.clicked.connect(self.btnClicekd)
        self.browseMFTBtn.setCursor(QCursor(Qt.PointingHandCursor))

        self.usnjrnlLabel = QLabel("$UsnJrnl: ", self)
        self.usnjrnlPathTextBox = QLineEdit(self)
        self.usnjrnlPathTextBox.setReadOnly(True)
        self.usnjrnlPathTextBox.setFixedWidth(400)
        self.browseUsnJrnlBtn = QPushButton("...", self)
        self.browseUsnJrnlBtn.setFixedWidth(50)
        self.browseUsnJrnlBtn.clicked.connect(self.btnClicekd)
        self.browseUsnJrnlBtn.setCursor(QCursor(Qt.PointingHandCursor))

        self.logfileLabel = QLabel("$LogFile: ", self)
        self.logfilePathTextBox = QLineEdit(self)
        self.logfilePathTextBox.setReadOnly(True)
        self.logfilePathTextBox.setFixedWidth(400)
        self.browseLogFileBtn = QPushButton("...", self)
        self.browseLogFileBtn.setFixedWidth(50)
        self.browseLogFileBtn.clicked.connect(self.btnClicekd)
        self.browseLogFileBtn.setCursor(QCursor(Qt.PointingHandCursor))

        ntfsLogGroupBoxLayout.addWidget(self.mftLabel, 0, 0)
        ntfsLogGroupBoxLayout.addWidget(self.mftPathTextBox, 0, 1)
        ntfsLogGroupBoxLayout.addWidget(self.browseMFTBtn, 0, 2)
        ntfsLogGroupBoxLayout.addWidget(self.usnjrnlLabel, 1, 0)
        ntfsLogGroupBoxLayout.addWidget(self.usnjrnlPathTextBox, 1, 1)
        ntfsLogGroupBoxLayout.addWidget(self.browseUsnJrnlBtn, 1, 2)
        ntfsLogGroupBoxLayout.addWidget(self.logfileLabel, 2, 0)
        ntfsLogGroupBoxLayout.addWidget(self.logfilePathTextBox, 2, 1)
        ntfsLogGroupBoxLayout.addWidget(self.browseLogFileBtn, 2, 2)

        self.submitBtn = QPushButton("Submit", self)
        self.submitBtn.setFixedSize(100, 40)
        self.submitBtn.setCursor(QCursor(Qt.PointingHandCursor))

        self.loggingLabel = QLabel("Loading...", self)
        self.loggingLabel.setFixedHeight(20)
        self.loggingLabel.setAlignment(Qt.AlignCenter)
        self.loggingLabel.hide()

        self.loadingBar = QProgressBar(self)
        self.loadingBar.setFixedHeight(10)
        self.loadingBar.setTextVisible(False)
        self.loadingBar.hide()

        from modules.UI.LoadingScreen import LoadingBarThread
        self.barThread = LoadingBarThread(self)
        self.barThread.change_value.connect(self.loadingBar.setValue)

        self.spacerItem2 = QSpacerItem(10, 15)
        self.spacerItem3 = QSpacerItem(10, 20)
        self.layout.addItem(self.spacerItem2)
        self.layout.addWidget(self.ntfsLogFileChkBox)
        self.layout.addWidget(self.ntfsLogGroupBox)
        self.layout.addItem(self.spacerItem3)
        self.layout.addWidget(self.submitBtn, alignment=Qt.AlignHCenter)

        self.setWindowModality(Qt.WindowModal)
        self.show()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()

    def selectedType(self, b):
        if b is self.diskRawChkBox:
            if b.isChecked():
                self.ntfsLogFileChkBox.setChecked(False)
                self.ntfsLogGroupBox.setDisabled(True)
                self.diskRawGroupBox.setDisabled(False)
            else:
                self.diskRawGroupBox.setDisabled(True)
        else:
            if b.isChecked():
                self.diskRawChkBox.setChecked(False)
                self.diskRawGroupBox.setDisabled(True)
                self.ntfsLogGroupBox.setDisabled(False)
            else:
                self.ntfsLogGroupBox.setDisabled(True)

    def btnClicekd(self):
        sender = self.sender()
        fileName = QFileDialog.getOpenFileName(self)
        if sender is self.browseDiskRawBtn:
            self.diskRawTextBox.setText(fileName[0])
        elif sender is self.browseMFTBtn:
            self.mftPathTextBox.setText(fileName[0])
        elif sender is self.browseUsnJrnlBtn:
            self.usnjrnlPathTextBox.setText(fileName[0])
        elif sender is self.browseLogFileBtn:
            self.logfilePathTextBox.setText(fileName[0])

    def ready(self):
        self.submitBtn.hide()
        self.layout.removeWidget(self.submitBtn)
        self.layout.addWidget(self.loggingLabel,
                              alignment=Qt.AlignBottom | Qt.AlignHCenter)
        self.layout.addWidget(self.loadingBar)
        self.loggingLabel.show()
        self.loadingBar.show()
        self.barThread.start()

    def resume(self):
        if self.barThread.cnt < 50:
            self.barThread.cnt = 100
            return
        self.barThread.toggle_status()

    def changeInterface(self, contents):
        from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem

        self.layout.removeWidget(self.diskRawChkBox)
        self.diskRawChkBox.hide()
        self.layout.removeWidget(self.diskRawGroupBox)
        self.diskRawGroupBox.hide()
        self.layout.removeItem(self.spacerItem2)
        self.layout.removeWidget(self.ntfsLogFileChkBox)
        self.ntfsLogFileChkBox.hide()
        self.layout.removeWidget(self.ntfsLogGroupBox)
        self.ntfsLogGroupBox.hide()
        self.layout.removeItem(self.spacerItem3)
        self.layout.removeWidget(self.submitBtn)

        self.diskNameLabel = QLabel("Image Name:\t" + contents[0][0], self)
        self.diskSizeLabel = QLabel(
            "Image Size:\t{} Bytes".format(contents[0][1]), self)
        self.diskSizeLabel.setFixedHeight(20)
        self.diskSizeLabel.setAlignment(Qt.AlignVCenter)
        self.diskPartLabel = QLabel("Partition:", self)
        self.diskPartLabel.setFixedHeight(20)
        self.diskPartLabel.setAlignment(Qt.AlignBottom)

        self.partitionTree = QTreeWidget(self)
        self.partitionTree.setHeaderLabels([
            "Order", "File System", "Active", "Starting Offset",
            "Total Sector", "Size"
        ])
        self.partitionTree.itemChanged.connect(self.itemChanged)
        self.partitionTree.resizeColumnToContents(2)
        self.partitionTree.resizeColumnToContents(3)
        self.partitionTree.resizeColumnToContents(4)
        self.partitionTree.headerItem().setTextAlignment(0, Qt.AlignCenter)
        self.partitionTree.headerItem().setTextAlignment(1, Qt.AlignCenter)

        self.partitionItems = []
        for row in range(1, 5):
            self.partitionTree.headerItem().setTextAlignment(
                row + 1, Qt.AlignCenter)
            item = QTreeWidgetItem(self.partitionTree)
            item.setText(0, str(row))
            item.setTextAlignment(0, Qt.AlignLeft)
            if not contents[row]:
                item.setText(1, "None")
                item.setCheckState(0, Qt.Unchecked)
                item.setDisabled(True)
                continue
            for col in range(5):
                item.setText(col + 1, contents[row][col])
                item.setTextAlignment(col + 1, Qt.AlignCenter)
            item.setTextAlignment(1, Qt.AlignLeft)
            item.setCheckState(0, Qt.Unchecked)
            self.partitionItems.append(item)

        self.layout.addWidget(self.diskNameLabel)
        self.layout.addWidget(self.diskSizeLabel)
        self.layout.addWidget(self.diskPartLabel)
        self.layout.addWidget(self.partitionTree)
        self.layout.addItem(QSpacerItem(10, 10))
        self.layout.addWidget(self.submitBtn, alignment=Qt.AlignCenter)

    def itemChanged(self, changedItem, p_int):
        if changedItem.checkState(0) == Qt.Checked:
            self.selectedPartition = int(changedItem.text(0))
            for item in self.partitionItems:
                if item is not changedItem:
                    item.setCheckState(0, Qt.Unchecked)
Esempio n. 53
0
class ConfigurationWidget(QWidget):
    """
    Class implementing a dialog for the configuration of eric6.
    
    @signal preferencesChanged() emitted after settings have been changed
    @signal masterPasswordChanged(str, str) emitted after the master
        password has been changed with the old and the new password
    @signal accepted() emitted to indicate acceptance of the changes
    @signal rejected() emitted to indicate rejection of the changes
    """
    preferencesChanged = pyqtSignal()
    masterPasswordChanged = pyqtSignal(str, str)
    accepted = pyqtSignal()
    rejected = pyqtSignal()

    DefaultMode = 0
    HelpBrowserMode = 1
    TrayStarterMode = 2
    HexEditorMode = 3
    WebBrowserMode = 4

    def __init__(self,
                 parent=None,
                 fromEric=True,
                 displayMode=DefaultMode,
                 expandedEntries=None):
        """
        Constructor
        
        @param parent The parent widget of this dialog. (QWidget)
        @keyparam fromEric flag indicating a dialog generation from within the
            eric6 ide (boolean)
        @keyparam displayMode mode of the configuration dialog
            (DefaultMode, HelpBrowserMode, TrayStarterMode, HexEditorMode,
             WebBrowserMode)
        @exception RuntimeError raised to indicate an invalid dialog mode
        @keyparam expandedEntries list of entries to be shown expanded
            (list of strings)
        """
        assert displayMode in (
            ConfigurationWidget.DefaultMode,
            ConfigurationWidget.HelpBrowserMode,
            ConfigurationWidget.TrayStarterMode,
            ConfigurationWidget.HexEditorMode,
            ConfigurationWidget.WebBrowserMode,
        )

        super(ConfigurationWidget, self).__init__(parent)
        self.fromEric = fromEric
        self.displayMode = displayMode
        self.__webEngine = getWebBrowserSupport() == "QtWebEngine"
        expandedEntries = [] if expandedEntries is None else expandedEntries[:]

        self.__setupUi()

        self.itmDict = {}

        if not fromEric:
            from PluginManager.PluginManager import PluginManager
            try:
                self.pluginManager = e5App().getObject("PluginManager")
            except KeyError:
                self.pluginManager = PluginManager(self)
                e5App().registerObject("PluginManager", self.pluginManager)

            from VirtualEnv.VirtualenvManager import VirtualenvManager
            try:
                self.virtualenvManager = e5App().getObject("VirtualEnvManager")
            except KeyError:
                self.virtualenvManager = VirtualenvManager(self)
                e5App().registerObject("VirtualEnvManager",
                                       self.virtualenvManager)

        if displayMode == ConfigurationWidget.DefaultMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "applicationPage": [
                    self.tr("Application"), "preferences-application.png",
                    "ApplicationPage", None, None
                ],
                "condaPage":
                [self.tr("Conda"), "miniconda.png", "CondaPage", None, None],
                "cooperationPage": [
                    self.tr("Cooperation"), "preferences-cooperation.png",
                    "CooperationPage", None, None
                ],
                "corbaPage": [
                    self.tr("CORBA"), "preferences-orbit.png", "CorbaPage",
                    None, None
                ],
                "diffPage": [
                    self.tr("Diff"), "diffFiles.png", "DiffColoursPage", None,
                    None
                ],
                "emailPage": [
                    self.tr("Email"), "preferences-mail_generic.png",
                    "EmailPage", None, None
                ],
                "graphicsPage": [
                    self.tr("Graphics"), "preferences-graphics.png",
                    "GraphicsPage", None, None
                ],
                "hexEditorPage": [
                    self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage",
                    None, None
                ],
                "iconsPage": [
                    self.tr("Icons"), "preferences-icons.png", "IconsPage",
                    None, None
                ],
                "ircPage": [self.tr("IRC"), "irc.png", "IrcPage", None, None],
                "logViewerPage": [
                    self.tr("Log-Viewer"), "preferences-logviewer.png",
                    "LogViewerPage", None, None
                ],
                "microPythonPage": [
                    self.tr("MicroPython"), "micropython", "MicroPythonPage",
                    None, None
                ],
                "mimeTypesPage": [
                    self.tr("Mimetypes"), "preferences-mimetypes.png",
                    "MimeTypesPage", None, None
                ],
                "networkPage": [
                    self.tr("Network"), "preferences-network.png",
                    "NetworkPage", None, None
                ],
                "notificationsPage": [
                    self.tr("Notifications"), "preferences-notifications.png",
                    "NotificationsPage", None, None
                ],
                "pipPage": [
                    self.tr("Python Package Management"), "pypi.png",
                    "PipPage", None, None
                ],
                "pluginManagerPage": [
                    self.tr("Plugin Manager"), "preferences-pluginmanager.png",
                    "PluginManagerPage", None, None
                ],
                "printerPage": [
                    self.tr("Printer"), "preferences-printer.png",
                    "PrinterPage", None, None
                ],
                "protobufPage": [
                    self.tr("Protobuf"), "protobuf.png", "ProtobufPage", None,
                    None
                ],
                "pythonPage": [
                    self.tr("Python"), "preferences-python.png", "PythonPage",
                    None, None
                ],
                "qtPage": [
                    self.tr("Qt"), "preferences-qtlogo.png", "QtPage", None,
                    None
                ],
                "securityPage": [
                    self.tr("Security"), "preferences-security.png",
                    "SecurityPage", None, None
                ],
                "shellPage": [
                    self.tr("Shell"), "preferences-shell.png", "ShellPage",
                    None, None
                ],
                "tasksPage":
                [self.tr("Tasks"), "task.png", "TasksPage", None, None],
                "templatesPage": [
                    self.tr("Templates"), "preferences-template.png",
                    "TemplatesPage", None, None
                ],
                "trayStarterPage": [
                    self.tr("Tray Starter"), "erict.png", "TrayStarterPage",
                    None, None
                ],
                "vcsPage": [
                    self.tr("Version Control Systems"), "preferences-vcs.png",
                    "VcsPage", None, None
                ],
                "0debuggerPage": [
                    self.tr("Debugger"), "preferences-debugger.png", None,
                    None, None
                ],
                "debuggerGeneralPage": [
                    self.tr("General"), "preferences-debugger.png",
                    "DebuggerGeneralPage", "0debuggerPage", None
                ],
                "debuggerPython2Page": [
                    self.tr("Python2"), "preferences-pyDebugger.png",
                    "DebuggerPython2Page", "0debuggerPage", None
                ],
                "debuggerPython3Page": [
                    self.tr("Python3"), "preferences-pyDebugger.png",
                    "DebuggerPython3Page", "0debuggerPage", None
                ],
                "0editorPage": [
                    self.tr("Editor"), "preferences-editor.png", None, None,
                    None
                ],
                "editorAPIsPage": [
                    self.tr("APIs"), "preferences-api.png", "EditorAPIsPage",
                    "0editorPage", None
                ],
                "editorAutocompletionPage": [
                    self.tr("Autocompletion"),
                    "preferences-autocompletion.png",
                    "EditorAutocompletionPage", "0editorPage", None
                ],
                "editorAutocompletionQScintillaPage": [
                    self.tr("QScintilla"), "qscintilla.png",
                    "EditorAutocompletionQScintillaPage",
                    "editorAutocompletionPage", None
                ],
                "editorCalltipsPage": [
                    self.tr("Calltips"), "preferences-calltips.png",
                    "EditorCalltipsPage", "0editorPage", None
                ],
                "editorCalltipsQScintillaPage": [
                    self.tr("QScintilla"), "qscintilla.png",
                    "EditorCalltipsQScintillaPage", "editorCalltipsPage", None
                ],
                "editorDocViewerPage": [
                    self.tr("Documentation Viewer"), "codeDocuViewer.png",
                    "EditorDocViewerPage", "0editorPage", None
                ],
                "editorGeneralPage": [
                    self.tr("General"), "preferences-general.png",
                    "EditorGeneralPage", "0editorPage", None
                ],
                "editorFilePage": [
                    self.tr("Filehandling"), "preferences-filehandling.png",
                    "EditorFilePage", "0editorPage", None
                ],
                "editorSearchPage": [
                    self.tr("Searching"), "preferences-search.png",
                    "EditorSearchPage", "0editorPage", None
                ],
                "editorSpellCheckingPage": [
                    self.tr("Spell checking"), "preferences-spellchecking.png",
                    "EditorSpellCheckingPage", "0editorPage", None
                ],
                "editorStylesPage": [
                    self.tr("Style"), "preferences-styles.png",
                    "EditorStylesPage", "0editorPage", None
                ],
                "editorSyntaxPage": [
                    self.tr("Code Checkers"), "preferences-debugger.png",
                    "EditorSyntaxPage", "0editorPage", None
                ],
                "editorTypingPage": [
                    self.tr("Typing"), "preferences-typing.png",
                    "EditorTypingPage", "0editorPage", None
                ],
                "editorExportersPage": [
                    self.tr("Exporters"), "preferences-exporters.png",
                    "EditorExportersPage", "0editorPage", None
                ],
                "1editorLexerPage": [
                    self.tr("Highlighters"),
                    "preferences-highlighting-styles.png", None, "0editorPage",
                    None
                ],
                "editorHighlightersPage": [
                    self.tr("Filetype Associations"),
                    "preferences-highlighter-association.png",
                    "EditorHighlightersPage", "1editorLexerPage", None
                ],
                "editorHighlightingStylesPage": [
                    self.tr("Styles"), "preferences-highlighting-styles.png",
                    "EditorHighlightingStylesPage", "1editorLexerPage", None
                ],
                "editorKeywordsPage": [
                    self.tr("Keywords"), "preferences-keywords.png",
                    "EditorKeywordsPage", "1editorLexerPage", None
                ],
                "editorPropertiesPage": [
                    self.tr("Properties"), "preferences-properties.png",
                    "EditorPropertiesPage", "1editorLexerPage", None
                ],
                "1editorMouseClickHandlers": [
                    self.tr("Mouse Click Handlers"),
                    "preferences-mouse-click-handler.png",
                    "EditorMouseClickHandlerPage", "0editorPage", None
                ],
                "0helpPage":
                [self.tr("Help"), "preferences-help.png", None, None, None],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation.png",
                    "HelpDocumentationPage", "0helpPage", None
                ],
                "helpViewersPage": [
                    self.tr("Help Viewers"), "preferences-helpviewers.png",
                    "HelpViewersPage", "0helpPage", None
                ],
                "0projectPage": [
                    self.tr("Project"), "preferences-project.png", None, None,
                    None
                ],
                "projectBrowserPage": [
                    self.tr("Project Viewer"), "preferences-project.png",
                    "ProjectBrowserPage", "0projectPage", None
                ],
                "projectPage": [
                    self.tr("Project"), "preferences-project.png",
                    "ProjectPage", "0projectPage", None
                ],
                "multiProjectPage": [
                    self.tr("Multiproject"), "preferences-multiproject.png",
                    "MultiProjectPage", "0projectPage", None
                ],
                "0interfacePage": [
                    self.tr("Interface"), "preferences-interface.png", None,
                    None, None
                ],
                "interfacePage": [
                    self.tr("Interface"), "preferences-interface.png",
                    "InterfacePage", "0interfacePage", None
                ],
                "viewmanagerPage": [
                    self.tr("Viewmanager"), "preferences-viewmanager.png",
                    "ViewmanagerPage", "0interfacePage", None
                ],
            }
            if self.__webEngine:
                self.configItems.update({
                    "0webBrowserPage":
                    [self.tr("Web Browser"), "ericWeb.png", None, None, None],
                    "webBrowserAppearancePage": [
                        self.tr("Appearance"), "preferences-styles.png",
                        "WebBrowserAppearancePage", "0webBrowserPage", None
                    ],
                    "webBrowserPage": [
                        self.tr("eric6 Web Browser"), "ericWeb.png",
                        "WebBrowserPage", "0webBrowserPage", None
                    ],
                    "webBrowserFlashCookieManagerPage": [
                        self.tr("Flash Cookie Manager"), "flashCookie16.png",
                        "WebBrowserFlashCookieManagerPage", "0webBrowserPage",
                        None
                    ],
                    "webBrowserVirusTotalPage": [
                        self.tr("VirusTotal Interface"), "virustotal.png",
                        "WebBrowserVirusTotalPage", "0webBrowserPage", None
                    ],
                    "webBrowserSpellCheckingPage": [
                        self.tr("Spell checking"),
                        "preferences-spellchecking.png",
                        "WebBrowserSpellCheckingPage", "0webBrowserPage", None
                    ],
                })

            self.configItems.update(
                e5App().getObject("PluginManager").getPluginConfigData())

        elif displayMode == ConfigurationWidget.WebBrowserMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "interfacePage": [
                    self.tr("Interface"), "preferences-interface.png",
                    "WebBrowserInterfacePage", None, None
                ],
                "networkPage": [
                    self.tr("Network"), "preferences-network.png",
                    "NetworkPage", None, None
                ],
                "printerPage": [
                    self.tr("Printer"), "preferences-printer.png",
                    "PrinterPage", None, None
                ],
                "securityPage": [
                    self.tr("Security"), "preferences-security.png",
                    "SecurityPage", None, None
                ],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation.png",
                    "HelpDocumentationPage", None, None
                ],
                "webBrowserAppearancePage": [
                    self.tr("Appearance"), "preferences-styles.png",
                    "WebBrowserAppearancePage", None, None
                ],
                "webBrowserPage": [
                    self.tr("eric6 Web Browser"), "ericWeb.png",
                    "WebBrowserPage", None, None
                ],
                "webBrowserFlashCookieManagerPage": [
                    self.tr("Flash Cookie Manager"), "flashCookie16.png",
                    "WebBrowserFlashCookieManagerPage", None, None
                ],
                "webBrowserVirusTotalPage": [
                    self.tr("VirusTotal Interface"), "virustotal.png",
                    "WebBrowserVirusTotalPage", None, None
                ],
                "webBrowserSpellCheckingPage": [
                    self.tr("Spell checking"), "preferences-spellchecking.png",
                    "WebBrowserSpellCheckingPage", None, None
                ],
            }

        elif displayMode == ConfigurationWidget.TrayStarterMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "trayStarterPage": [
                    self.tr("Tray Starter"), "erict.png", "TrayStarterPage",
                    None, None
                ],
            }

        elif displayMode == ConfigurationWidget.HexEditorMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "hexEditorPage": [
                    self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage",
                    None, None
                ],
            }

        else:
            raise RuntimeError("Illegal mode value: {0}".format(displayMode))

        # generate the list entries
        self.__expandedEntries = []
        for key in sorted(self.configItems.keys()):
            pageData = self.configItems[key]
            if pageData[3]:
                if pageData[3] in self.itmDict:
                    pitm = self.itmDict[pageData[3]]  # get the parent item
                else:
                    continue
            else:
                pitm = self.configList
            self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key,
                                                      pageData[1])
            self.itmDict[key].setData(0, Qt.UserRole, key)
            if (not self.fromEric
                    or displayMode != ConfigurationWidget.DefaultMode
                    or key in expandedEntries):
                self.itmDict[key].setExpanded(True)
        self.configList.sortByColumn(0, Qt.AscendingOrder)

        # set the initial size of the splitter
        self.configSplitter.setSizes([200, 600])

        self.configList.itemActivated.connect(self.__showConfigurationPage)
        self.configList.itemClicked.connect(self.__showConfigurationPage)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.rejected)

        if displayMode in [
                ConfigurationWidget.HelpBrowserMode,
                ConfigurationWidget.TrayStarterMode,
                ConfigurationWidget.HexEditorMode,
                ConfigurationWidget.WebBrowserMode
        ]:
            self.configListSearch.hide()

        if displayMode not in [
                ConfigurationWidget.TrayStarterMode,
                ConfigurationWidget.HexEditorMode
        ]:
            self.__initLexers()

    def accept(self):
        """
        Public slot to accept the buttonBox accept signal.
        """
        if not isMacPlatform():
            wdg = self.focusWidget()
            if wdg == self.configList:
                return

        self.accepted.emit()

    def __setupUi(self):
        """
        Private method to perform the general setup of the configuration
        widget.
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 650)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Horizontal)
        self.configSplitter.setObjectName("configSplitter")

        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListSearch = E5ClearableLineEdit(
            self, self.tr("Enter search text..."))
        self.configListSearch.setObjectName("configListSearch")
        self.leftVBoxLayout.addWidget(self.configListSearch)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListSearch.textChanged.connect(self.__searchTextChanged)

        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setObjectName("scrollArea")

        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Box)
        self.configStack.setFrameShadow(QFrame.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)

        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(20, 20, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png')))
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)

        self.verticalLayout_2.addWidget(self.configSplitter)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Apply
                                          | QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.Reset)
        self.buttonBox.setObjectName("buttonBox")
        if (not self.fromEric
                and self.displayMode == ConfigurationWidget.DefaultMode):
            self.buttonBox.button(QDialogButtonBox.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))

        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr("Please select an entry of the list \n"
                    "to display the configuration page."))

        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)

        self.configStack.setCurrentWidget(self.emptyPage)

        self.configList.setFocus()

    def __searchTextChanged(self, text):
        """
        Private slot to handle a change of the search text.
        
        @param text text to search for (string)
        """
        self.__searchChildItems(self.configList.invisibleRootItem(), text)

    def __searchChildItems(self, parent, text):
        """
        Private method to enable child items based on a search string.
        
        @param parent reference to the parent item (QTreeWidgetItem)
        @param text text to search for (string)
        @return flag indicating an enabled child item (boolean)
        """
        childEnabled = False
        text = text.lower()
        for index in range(parent.childCount()):
            itm = parent.child(index)
            if itm.childCount() > 0:
                enable = (self.__searchChildItems(itm, text) or text == ""
                          or text in itm.text(0).lower())
            else:
                enable = text == "" or text in itm.text(0).lower()
            if enable:
                childEnabled = True
            itm.setDisabled(not enable)

        return childEnabled

    def __initLexers(self):
        """
        Private method to initialize the dictionary of preferences lexers.
        """
        import QScintilla.Lexers
        from .PreferencesLexer import (PreferencesLexer,
                                       PreferencesLexerLanguageError)

        self.lexers = {}
        for language in QScintilla.Lexers.getSupportedLanguages():
            if language not in self.lexers:
                try:
                    self.lexers[language] = PreferencesLexer(language, self)
                except PreferencesLexerLanguageError:
                    pass

    def __importConfigurationPage(self, name):
        """
        Private method to import a configuration page module.
        
        @param name name of the configuration page module (string)
        @return reference to the configuration page module
        """
        modName = "Preferences.ConfigurationPages.{0}".format(name)
        try:
            mod = __import__(modName)
            components = modName.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod
        except ImportError:
            E5MessageBox.critical(
                self, self.tr("Configuration Page Error"),
                self.tr("""<p>The configuration page <b>{0}</b>"""
                        """ could not be loaded.</p>""").format(name))
            return None

    def __showConfigurationPage(self, itm, column):
        """
        Private slot to show a selected configuration page.
        
        @param itm reference to the selected item (QTreeWidgetItem)
        @param column column that was selected (integer) (ignored)
        """
        pageName = itm.getPageName()
        self.showConfigurationPageByName(pageName, setCurrent=False)

    def __initPage(self, pageData):
        """
        Private method to initialize a configuration page.
        
        @param pageData data structure for the page to initialize
        @return reference to the initialized page
        """
        page = None
        if isinstance(pageData[2], types.FunctionType):
            page = pageData[2](self)
        else:
            mod = self.__importConfigurationPage(pageData[2])
            if mod:
                page = mod.create(self)
        if page is not None:
            self.configStack.addWidget(page)
            pageData[-1] = page
            try:
                page.setMode(self.displayMode)
            except AttributeError:
                pass
        return page

    def showConfigurationPageByName(self, pageName, setCurrent=True):
        """
        Public slot to show a named configuration page.
        
        @param pageName name of the configuration page to show (string)
        @param setCurrent flag indicating to set the current item (boolean)
        """
        if pageName == "empty" or pageName not in self.configItems:
            page = self.emptyPage
        else:
            pageData = self.configItems[pageName]
            if pageData[-1] is None and pageData[2] is not None:
                # the page was not loaded yet, create it
                page = self.__initPage(pageData)
            else:
                page = pageData[-1]
            if page is None:
                page = self.emptyPage
            elif setCurrent:
                items = self.configList.findItems(
                    pageData[0], Qt.MatchFixedString | Qt.MatchRecursive)
                for item in items:
                    if item.data(0, Qt.UserRole) == pageName:
                        self.configList.setCurrentItem(item)
        self.configStack.setCurrentWidget(page)
        ssize = self.scrollArea.size()
        if self.scrollArea.horizontalScrollBar():
            ssize.setHeight(ssize.height() -
                            self.scrollArea.horizontalScrollBar().height() - 2)
        if self.scrollArea.verticalScrollBar():
            ssize.setWidth(ssize.width() -
                           self.scrollArea.verticalScrollBar().width() - 2)
        psize = page.minimumSizeHint()
        self.configStack.resize(max(ssize.width(), psize.width()),
                                max(ssize.height(), psize.height()))

        if page != self.emptyPage:
            page.polishPage()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
        else:
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)

        # reset scrollbars
        for sb in [
                self.scrollArea.horizontalScrollBar(),
                self.scrollArea.verticalScrollBar()
        ]:
            if sb:
                sb.setValue(0)

        self.__currentConfigurationPageName = pageName

    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.
        
        @return page name of the current page (string)
        """
        return self.__currentConfigurationPageName

    def calledFromEric(self):
        """
        Public method to check, if invoked from within eric.
        
        @return flag indicating invocation from within eric (boolean)
        """
        return self.fromEric

    def getPage(self, pageName):
        """
        Public method to get a reference to the named page.
        
        @param pageName name of the configuration page (string)
        @return reference to the page or None, indicating page was
            not loaded yet
        """
        return self.configItems[pageName][-1]

    def getLexers(self):
        """
        Public method to get a reference to the lexers dictionary.
        
        @return reference to the lexers dictionary
        """
        return self.lexers

    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        for pageData in self.configItems.values():
            if pageData[-1]:
                pageData[-1].save()
                # page was loaded (and possibly modified)
                QApplication.processEvents()  # ensure HMI is responsive

    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.buttonBox.button(QDialogButtonBox.Apply):
            self.on_applyButton_clicked()
        elif button == self.buttonBox.button(QDialogButtonBox.Reset):
            self.on_resetButton_clicked()

    @pyqtSlot()
    def on_applyButton_clicked(self):
        """
        Private slot called to apply the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            page = self.configStack.currentWidget()
            savedState = page.saveState()
            page.save()
            self.preferencesChanged.emit()
            if savedState is not None:
                page.setState(savedState)
            page.polishPage()

    @pyqtSlot()
    def on_resetButton_clicked(self):
        """
        Private slot called to reset the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            currentPage = self.configStack.currentWidget()
            savedState = currentPage.saveState()
            pageName = self.configList.currentItem().getPageName()
            self.configStack.removeWidget(currentPage)
            if pageName == "editorHighlightingStylesPage":
                self.__initLexers()
            self.configItems[pageName][-1] = None

            self.showConfigurationPageByName(pageName)
            if savedState is not None:
                self.configStack.currentWidget().setState(savedState)

    def getExpandedEntries(self):
        """
        Public method to get a list of expanded entries.
        
        @return list of expanded entries (list of string)
        """
        return self.__expandedEntries

    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemCollapsed(self, item):
        """
        Private slot handling a list entry being collapsed.
        
        @param item reference to the collapsed item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName in self.__expandedEntries:
            self.__expandedEntries.remove(pageName)

    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemExpanded(self, item):
        """
        Private slot handling a list entry being expanded.
        
        @param item reference to the expanded item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName not in self.__expandedEntries:
            self.__expandedEntries.append(pageName)

    def isUsingWebEngine(self):
        """
        Public method to get an indication, if QtWebEngine is being used.
        
        @return flag indicating the use of QtWebEngine
        @rtype bool
        """
        return (self.__webEngine
                or self.displayMode == ConfigurationWidget.WebBrowserMode)
Esempio n. 54
0
File: tab.py Progetto: maphew/GDBee
class Tab(QWidget):
    """Tab in the QTableWidget where user executes query and sees the result."""

    # ----------------------------------------------------------------------
    def __init__(self):
        """Initialize Tab with layout and behavior."""
        super(Tab, self).__init__()

        # regex pattern for SQL query block comments
        self.block_comment_re = re.compile(
            r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
            re.DOTALL | re.MULTILINE)

        main_layout = QVBoxLayout(self)

        # define gdb props
        self.gdb = None
        self.gdb_items = None
        self.gdb_columns_names = None
        self.gdb_schemas = None

        # connected geodatabase path toolbar
        self.connected_gdb_path_label = QLabel('')
        self.connected_gdb_path_label.setTextInteractionFlags(
            Qt.TextSelectableByMouse)
        self.connected_gdb_path_label.setToolTip(
            'Connected geodatabase that queries will be run against')
        self.connected_gdb_path_label.setText(not_connected_to_gdb_message)

        self.browse_to_gdb = QPushButton('Browse')
        self.browse_to_gdb.setShortcut(QKeySequence('Ctrl+B'))
        self.browse_to_gdb.clicked.connect(
            lambda evt, arg=True: self.connect_to_geodatabase(
                evt, triggered_with_browse=True))

        self.gdb_sql_dialect_combobox = QComboBox()
        for dialect in sql_dialects_names:
            self.gdb_sql_dialect_combobox.addItem(dialect)

        self.gdb_browse_toolbar = QToolBar()
        self.gdb_browse_toolbar.setMaximumHeight(50)
        self.gdb_browse_toolbar.addWidget(self.browse_to_gdb)
        self.gdb_browse_toolbar.addWidget(self.connected_gdb_path_label)
        self.gdb_browse_toolbar.addSeparator()
        self.gdb_browse_toolbar.addWidget(self.gdb_sql_dialect_combobox)

        # table with results
        self.table = ResultTable()

        # execute SQL query
        self.execute = QAction('Execute', self)
        self.execute.setShortcuts(
            [QKeySequence('F5'),
             QKeySequence('Ctrl+Return')])
        self.execute.triggered.connect(self.run_query)
        self.addAction(self.execute)

        # enter a SQL query
        self.query = TextEditor()
        self.query.setPlainText('')
        font = self.query.font()
        font.setFamily('Consolas')
        font.setStyleHint(QFont.Monospace)

        # TODO: add line numbers to the text editor
        font.setPointSize(14)
        self.query.setFont(font)
        self.query.setTabStopWidth(20)
        self.highlighter = Highlighter(self.query.document())

        # TODO select block of text - Ctrl+/ and they become comments
        self.completer = Completer()
        self.query.set_completer(self.completer.completer)

        # errors panel to show if query fails to execute properly
        self.errors_panel = QPlainTextEdit()
        font = self.query.font()
        font.setPointSize(12)
        self.errors_panel.setStyleSheet('color:red')
        self.errors_panel.setFont(font)
        self.errors_panel.hide()

        # splitter between the toolbar, query window, and the result set table
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.gdb_browse_toolbar)
        splitter.addWidget(self.query)
        splitter.addWidget(self.table)
        splitter.addWidget(self.errors_panel)

        # add the settings after the widget have been added
        splitter.setCollapsible(0, True)
        splitter.setCollapsible(1, False)
        splitter.setCollapsible(2, False)
        splitter.setCollapsible(3, False)
        splitter.setStretchFactor(0, 3)
        splitter.setStretchFactor(1, 7)
        splitter.setSizes((100, 200, 300))
        self.table.hide()

        # TOC
        self.toc = QTreeWidget()
        self.toc.setHeaderHidden(True)

        # second splitter between the TOC to the left and the query/table to the
        # right
        toc_splitter = QSplitter(Qt.Horizontal)
        toc_splitter.addWidget(self.toc)
        toc_splitter.addWidget(splitter)
        toc_splitter.setCollapsible(0, True)
        toc_splitter.setSizes((200, 800))  # set the TOC vs data panel

        main_layout.addWidget(toc_splitter)

        margins = QMargins()
        margins.setBottom(10)
        margins.setLeft(10)
        margins.setRight(10)
        margins.setTop(10)
        main_layout.setContentsMargins(margins)

        self.setLayout(main_layout)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.show()

        return

    # ----------------------------------------------------------------------
    def connect_to_geodatabase(self, evt, triggered_with_browse=True):
        """Connect to geodatabase by letting user browse to a gdb folder."""
        if triggered_with_browse:
            gdb_connect_dialog = QFileDialog(self)
            gdb_connect_dialog.setFileMode(QFileDialog.Directory)
            gdb_path = gdb_connect_dialog.getExistingDirectory()

            # TODO: add a filter to show only .gdb folders?
            # https://stackoverflow.com/questions/4893122/filtering-in-qfiledialog
            if gdb_path and gdb_path.endswith('.gdb'):
                self.gdb = Geodatabase(gdb_path)
                if self.gdb.is_valid():
                    self.connected_gdb_path_label.setText(self.gdb.path)
                    self._set_gdb_items_highlight()
                    self._set_gdb_items_complete()
                    self._fill_toc()
                else:
                    msg = QMessageBox()
                    msg.setText('This is not a valid file geodatabase')
                    msg.setWindowTitle('Validation error')
                    msg.setStandardButtons(QMessageBox.Ok)
                    msg.exec_()
        else:
            if self.gdb.is_valid():
                self._set_gdb_items_highlight()
                self._set_gdb_items_complete()

        return

    # ----------------------------------------------------------------------
    def wheelEvent(self, event):  # noqa: N802
        """Override built-in method to handle mouse wheel scrolling.

        Necessary to do when the tab is focused.
        """
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if event.angleDelta().y() > 0:  # scroll forward
                self.query.zoomIn(1)
            else:
                self.query.zoomOut(1)
        return

    # ----------------------------------------------------------------------
    def run_query(self):
        """Run SQL query and draw the record set and call table drawing."""
        if not self.gdb:
            self.print_sql_execute_errors(not_connected_to_gdb_message)
            return
        try:
            if not self.gdb.is_valid():
                return

            # use the text of what user selected, if none -> need to run the
            # whole query
            part_sql_query = self.query.textCursor().selection().toPlainText()

            if part_sql_query:
                sql_query = part_sql_query
            else:
                sql_query = self.query.toPlainText()

            if sql_query:
                # removing block comments and single line comments
                sql_query = self.block_comment_re.sub(
                    self._strip_block_comments, sql_query)
                sql_query = self._strip_single_comments(sql_query)
            else:
                return

            # TODO: add threading to allow user to cancel a long running query
            QApplication.setOverrideCursor(Qt.WaitCursor)
            start_time = time.time()
            self.gdb.open_connection()
            res, errors = self.gdb.execute_sql(
                sql_query, self.gdb_sql_dialect_combobox.currentText())
            end_time = time.time()
            if errors:
                self.print_sql_execute_errors(errors)

            if res:
                self.table.show()
                self.errors_panel.hide()
                self.draw_result_table(res)
                msg = 'Executed in {exec_time:.1f} secs | {rows} rows'.format(
                    exec_time=end_time - start_time,
                    rows=self.table.table_data.number_layer_rows)
                self.update_app_status_bar(msg)

        except Exception as err:
            print(err)
        finally:
            QApplication.restoreOverrideCursor()
        return

    # ----------------------------------------------------------------------
    def result_should_include_geometry(self):
        """Get the setting defining whether to include the geometry column."""
        try:
            return self.parentWidget().parentWidget().parentWidget(
            ).do_include_geometry.isChecked()
        except BaseException:
            return True

    # ----------------------------------------------------------------------
    def update_app_status_bar(self, message):
        """Update app status bar with the execution result details."""
        try:
            self.parentWidget().parentWidget().parentWidget().statusBar(
            ).showMessage(message)
        except BaseException:
            pass
        return

    # ----------------------------------------------------------------------
    def draw_result_table(self, res):
        """Draw table with the record set received from the geodatabase."""
        geom_col_name = res.GetGeometryColumn(
        )  # shape col was in the sql query
        self.geometry_isin_query = bool(geom_col_name)

        self.table.draw_result(res,
                               show_shapes=bool(
                                   self.result_should_include_geometry()))
        self.table.view.resizeColumnsToContents()
        return

    # ----------------------------------------------------------------------
    def print_sql_execute_errors(self, err):
        """Print to a special panel errors that occurred during execution."""
        self.table.hide()
        self.errors_panel.show()
        self.errors_panel.setPlainText(err)
        return

    # ----------------------------------------------------------------------
    def _set_gdb_items_highlight(self):
        """Set completer and highlight properties for geodatabase items."""
        self.gdb_items = self.gdb.get_items()
        self.highlighter.set_highlight_rules_gdb_items(self.gdb_items, 'Table')

        self.gdb_schemas = self.gdb.get_schemas()
        self.gdb_columns_names = sorted(list(
            set(
                itertools.chain.from_iterable(
                    [i.keys() for i in self.gdb_schemas.values()]))),
                                        key=lambda x: x.lower())

    # ----------------------------------------------------------------------
    def _set_gdb_items_complete(self):
        """Update completer rules to include geodatabase items."""
        self.completer.update_completer_string_list(self.gdb_items +
                                                    self.gdb_columns_names)
        self.highlighter.set_highlight_rules_gdb_items(self.gdb_columns_names,
                                                       'Column')
        return

    # ----------------------------------------------------------------------
    def _fill_toc(self):
        """Fill TOC with geodatabase datasets and columns."""
        self.toc.clear()
        if not self.gdb_items:
            return

        for tbl_name in sorted(self.gdb_items, key=lambda i: i.lower()):
            if tbl_name.islower() or tbl_name.isupper():
                item = QTreeWidgetItem([tbl_name.title()])
            else:
                item = QTreeWidgetItem([tbl_name])
            font = QFont()
            font.setBold(True)
            item.setFont(0, font)

            for col_name, col_type in sorted(
                    self.gdb_schemas[tbl_name].items()):
                if col_name.islower() or col_name.isupper():
                    col_name = col_name.title()

                item_child = QTreeWidgetItem(
                    ['{0} ({1})'.format(col_name, col_type)])
                item.addChild(item_child)
            self.toc.addTopLevelItem(item)
        return

    # ----------------------------------------------------------------------
    def _do_toc_hide_show(self):
        """Hide TOC with tables and columns."""
        if self.toc.isVisible():
            self.toc.setVisible(False)
        else:
            self.toc.setVisible(True)
        return

    # ----------------------------------------------------------------------
    def _strip_block_comments(self, sql_query):
        """Strip the block comments in SQL query."""
        start, mid, end = sql_query.group(1, 2, 3)
        if mid is None:
            # this is a single-line comment
            return ''
        elif start is not None or end is not None:
            # this is a multi-line comment at start/end of a line
            return ''
        elif '\n' in mid:
            # this is a multi-line comment with line break
            return '\n'
        else:
            # this is a multi-line comment without line break
            return ' '

    # ----------------------------------------------------------------------
    def _strip_single_comments(self, sql_query):
        """Strip the single line comments in SQL query."""
        clean_query = []
        for line in sql_query.rstrip().split('\n'):
            clean_line = line.split('--')[0]
            if clean_line:
                clean_query.append(clean_line)
        return ' '.join([line for line in clean_query])
Esempio n. 55
0
    def __setupUi(self):
        """
        Private method to perform the general setup of the configuration
        widget.
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 650)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Horizontal)
        self.configSplitter.setObjectName("configSplitter")

        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListSearch = E5ClearableLineEdit(
            self, self.tr("Enter search text..."))
        self.configListSearch.setObjectName("configListSearch")
        self.leftVBoxLayout.addWidget(self.configListSearch)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListSearch.textChanged.connect(self.__searchTextChanged)

        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setObjectName("scrollArea")

        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Box)
        self.configStack.setFrameShadow(QFrame.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)

        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(20, 20, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png')))
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)

        self.verticalLayout_2.addWidget(self.configSplitter)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Apply
                                          | QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.Reset)
        self.buttonBox.setObjectName("buttonBox")
        if (not self.fromEric
                and self.displayMode == ConfigurationWidget.DefaultMode):
            self.buttonBox.button(QDialogButtonBox.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))

        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr("Please select an entry of the list \n"
                    "to display the configuration page."))

        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)

        self.configStack.setCurrentWidget(self.emptyPage)

        self.configList.setFocus()
Esempio n. 56
0
    def changeInterface(self, contents):
        from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem

        self.layout.removeWidget(self.diskRawChkBox)
        self.diskRawChkBox.hide()
        self.layout.removeWidget(self.diskRawGroupBox)
        self.diskRawGroupBox.hide()
        self.layout.removeItem(self.spacerItem2)
        self.layout.removeWidget(self.ntfsLogFileChkBox)
        self.ntfsLogFileChkBox.hide()
        self.layout.removeWidget(self.ntfsLogGroupBox)
        self.ntfsLogGroupBox.hide()
        self.layout.removeItem(self.spacerItem3)
        self.layout.removeWidget(self.submitBtn)

        self.diskNameLabel = QLabel("Image Name:\t" + contents[0][0], self)
        self.diskSizeLabel = QLabel(
            "Image Size:\t{} Bytes".format(contents[0][1]), self)
        self.diskSizeLabel.setFixedHeight(20)
        self.diskSizeLabel.setAlignment(Qt.AlignVCenter)
        self.diskPartLabel = QLabel("Partition:", self)
        self.diskPartLabel.setFixedHeight(20)
        self.diskPartLabel.setAlignment(Qt.AlignBottom)

        self.partitionTree = QTreeWidget(self)
        self.partitionTree.setHeaderLabels([
            "Order", "File System", "Active", "Starting Offset",
            "Total Sector", "Size"
        ])
        self.partitionTree.itemChanged.connect(self.itemChanged)
        self.partitionTree.resizeColumnToContents(2)
        self.partitionTree.resizeColumnToContents(3)
        self.partitionTree.resizeColumnToContents(4)
        self.partitionTree.headerItem().setTextAlignment(0, Qt.AlignCenter)
        self.partitionTree.headerItem().setTextAlignment(1, Qt.AlignCenter)

        self.partitionItems = []
        for row in range(1, 5):
            self.partitionTree.headerItem().setTextAlignment(
                row + 1, Qt.AlignCenter)
            item = QTreeWidgetItem(self.partitionTree)
            item.setText(0, str(row))
            item.setTextAlignment(0, Qt.AlignLeft)
            if not contents[row]:
                item.setText(1, "None")
                item.setCheckState(0, Qt.Unchecked)
                item.setDisabled(True)
                continue
            for col in range(5):
                item.setText(col + 1, contents[row][col])
                item.setTextAlignment(col + 1, Qt.AlignCenter)
            item.setTextAlignment(1, Qt.AlignLeft)
            item.setCheckState(0, Qt.Unchecked)
            self.partitionItems.append(item)

        self.layout.addWidget(self.diskNameLabel)
        self.layout.addWidget(self.diskSizeLabel)
        self.layout.addWidget(self.diskPartLabel)
        self.layout.addWidget(self.partitionTree)
        self.layout.addItem(QSpacerItem(10, 10))
        self.layout.addWidget(self.submitBtn, alignment=Qt.AlignCenter)
Esempio n. 57
0
class JapanCoronaInfoWidget(QDialog):
    def __init__(self, data_url, parent=None, window_title='Default'):
        super(JapanCoronaInfoWidget, self).__init__(parent)

        self.dataset = ArcGISWrapper(data_url)
        self._adjust_attributes()
        self.feature_names = self.dataset.get_fields()
        self.sorting_feature_name = self.feature_names[0]

        self.feature_checkboxes = dict()
        self._create_feature_selection_checkbox_group()
        self._connect_feature_selection_checkboxes()
        self.data_treeview = QTreeWidget()

        sort_combo_box = QComboBox()
        sort_combo_box.addItems(self.feature_names)

        sort_label = QLabel('&Sort by:')
        sort_label.setBuddy(sort_combo_box)

        top_layout = QHBoxLayout()
        top_layout.addWidget(sort_label)
        top_layout.addWidget(sort_combo_box)

        self.main_layout = QGridLayout()
        self.main_layout.addLayout(top_layout, 0, 0)
        self.main_layout.addWidget(self.feature_selection_groupbox, 1, 0)
        self.main_layout.addWidget(self.data_treeview, 2, 0)

        sort_combo_box.activated[str].connect(self._main_feature_changed)
        self._update_gui_on_change()

        self.setLayout(self.main_layout)
        self.setWindowTitle(window_title)

    def _adjust_attributes(self):
        for f in self.dataset.features:
            j_date = f['attributes']['Date']
            if j_date != 'N.A.':
                # Cut first 10 characters from json date to allow epoch conversion
                date_str = datetime.datetime.fromtimestamp(int(
                    j_date[:10])).strftime('%x')
                f['attributes']['Date'] = date_str

    def _create_feature_selection_checkbox_group(self):
        self.feature_selection_groupbox = QGroupBox('Feature selection')
        self.feature_selection_groupbox.setCheckable(False)
        # self.feature_selection_groupbox.setChecked(False)

        layout = QHBoxLayout()
        for f in self.feature_names:
            t = QCheckBox('{}'.format(f))
            t.setChecked(True)
            self.feature_checkboxes[f] = {'handle': t, 'enabled': True}
            layout.addWidget(t)
        self.feature_selection_groupbox.setLayout(layout)

    def _update_gui_on_change(self):
        # TODO disable sorting feature checkbox
        # .... some code ....
        self._update_treeview()

    def _update_checkbox_states(self):
        for cb in self.feature_checkboxes:
            if self.feature_checkboxes[cb]['handle'].checkState(
            ) == Qt.Checked:
                self.feature_checkboxes[cb]['enabled'] = True
            else:
                self.feature_checkboxes[cb]['enabled'] = False
        self._update_gui_on_change()

    def _connect_feature_selection_checkboxes(self):
        for cb in self.feature_checkboxes:
            self.feature_checkboxes[cb]['handle'].stateChanged.connect(
                self._update_checkbox_states)

    def _main_feature_changed(self, feature_name):
        self.sorting_feature_name = feature_name
        self._update_gui_on_change()

    def _create_treeview_headers(self, root_feature):
        # Create new TreeWidget to purge the headers as well
        self.data_treeview = QTreeWidget()
        self.main_layout.addWidget(self.data_treeview, 2, 0)

        headers = [root_feature]
        for n, feature_name in enumerate(self.feature_names):
            # If column is enabled and not the sorting feature add it to the header list
            if self.feature_checkboxes[feature_name][
                    'enabled'] is True and feature_name != self.sorting_feature_name:
                headers.append(feature_name)

        self.data_treeview.setHeaderLabels(headers)

    def _fill_treeview(self, case_data):
        for d in sorted(case_data):
            tree_root = QTreeWidgetItem(self.data_treeview)
            tree_root.setText(0, '{} ({})'.format(d, len(case_data[d])))
            for case in case_data[d]:
                sub_item = QTreeWidgetItem(tree_root)
                sub_item.setText(0, str(d))
                offset = 0
                for column, case_item in enumerate(case):
                    if self.feature_checkboxes[case_item][
                            'enabled'] is True and case_item != self.sorting_feature_name:
                        sub_item.setText(column + 1 - offset,
                                         str(case[case_item]))
                    else:
                        offset = offset + 1
Esempio n. 58
0
class TreeSymbolsWidget(QDialog):
    """ Class of Dialog for Tree Symbols """

    dockWidget = pyqtSignal('PyQt_PyObject')
    undockWidget = pyqtSignal('PyQt_PyObject')

    def __init__(self, parent=None):
        super(TreeSymbolsWidget, self).__init__(parent)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.tree = QTreeWidget()
        self.tree.setFrameShape(0)
        vbox.addWidget(self.tree)
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(self.tree.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.tree.header().setSectionResizeMode(0,
                                                QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.actualSymbols = ('', {})
        self.docstrings = {}
        self.collapsedItems = {}

        self.tree.itemClicked.connect(self._go_to_definition)
        self.tree.itemActivated.connect(self._go_to_definition)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)

        self.customContextMenuRequested['const QPoint &'].connect(
            self._menu_context_tree)
        # self.connect(
        #    self,
        #    SIGNAL("customContextMenuRequested(const QPoint &)"),
        #    self._menu_context_tree)
        # self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem *)"),
        #             self._item_collapsed)
        # self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem *)"),
        #             self._item_expanded)

        IDE.register_service('symbols_explorer', self)
        # ExplorerContainer.register_tab(translations.TR_TAB_SYMBOLS, self)

    def install_tab(self):
        """ Connect signals for goingdown """

        ide = IDE.get_service('ide')
        ide.goingDown.connect(self.close)

    def _menu_context_tree(self, point):
        """Context menu"""
        index = self.tree.indexAt(point)
        if not index.isValid():
            return

        menu = QMenu(self)
        f_all = menu.addAction(translations.TR_FOLD_ALL)
        u_all = menu.addAction(translations.TR_UNFOLD_ALL)
        menu.addSeparator()
        u_class = menu.addAction(translations.TR_UNFOLD_CLASSES)
        u_class_method = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_METHODS)
        u_class_attr = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_ATTRIBUTES)
        menu.addSeparator()
        # save_state = menu.addAction(self.tr("Save State"))

        # self.connect(f_all, SIGNAL("triggered()"),
        #             lambda: self.tree.collapseAll())
        # self.connect(u_all, SIGNAL("triggered()"),
        #             lambda: self.tree.expandAll())
        # self.connect(u_class, SIGNAL("triggered()"), self._unfold_class)
        # self.connect(u_class_method, SIGNAL("triggered()"),
        #             self._unfold_class_method)
        # self.connect(u_class_attr, SIGNAL("triggered()"),
        #              self._unfold_class_attribute)
        # self.connect(save_state, SIGNAL("triggered()"),
        #    self._save_symbols_state)

        menu.exec_(QCursor.pos())

    def _get_classes_root(self):
        """Return the root of classes"""
        class_root = None
        for i in range(self.tree.topLevelItemCount()):
            item = self.tree.topLevelItem(i)
            if item.isClass and not item.isClickable:
                class_root = item
                break
        return class_root

    def _unfold_class(self):
        """Method to Unfold Classes"""
        self.tree.collapseAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return

        classes_root.setExpanded(True)

    def _unfold_class_method(self):
        """Method to Unfold Methods"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        # for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            # for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                # METHODS ROOT!!
                if not item.isMethod and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _unfold_class_attribute(self):
        """Method to Unfold Attributes"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        # for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            # for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                # ATTRIBUTES ROOT!!
                if not item.isAttribute and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _save_symbols_state(self):
        """Method to Save a persistent Symbols state"""
        # filename = self.actualSymbols[0]
        # TODO: persist self.collapsedItems[filename] in QSettings
        pass

    def _get_expand(self, item):
        """
        Returns True or False to be used as setExpanded() with the items
        It method is based on the click that the user made in the tree
        """
        name = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        collapsed_items = self.collapsedItems.get(filename, [])
        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check and name in collapsed_items:
            return False
        return True

    @staticmethod
    def _get_unique_name(item):
        """
        Returns a string used as unique name
        """
        # className_Attributes/className_Functions
        parent = item.parent()
        if parent:
            return "%s_%s" % (parent.text(0), item.text(0))
        return "_%s" % item.text(0)

    def update_symbols_tree(self, symbols, filename='', parent=None):
        """Method to Update the symbols on the Tree"""
        TIP = "{} {}"
        if not parent:
            if filename == self.actualSymbols[0] and \
                    self.actualSymbols[1] and not symbols:
                return

            if symbols == self.actualSymbols[1]:
                # Nothing new then return
                return

            # we have new symbols refresh it
            self.tree.clear()
            self.actualSymbols = (filename, symbols)
            self.docstrings = symbols.get('docstrings', {})
            parent = self.tree
        if 'attributes' in symbols:
            globalAttribute = ItemTree(parent, [translations.TR_ATTRIBUTES])
            globalAttribute.isClickable = False
            globalAttribute.isAttribute = True
            globalAttribute.setExpanded(self._get_expand(globalAttribute))
            globalAttribute.setToolTip(
                0,
                TIP.format(len(symbols['attributes']),
                           translations.TR_ATTRIBUTES))
            for glob in sorted(symbols['attributes']):
                globItem = ItemTree(globalAttribute, [glob],
                                    lineno=symbols['attributes'][glob])
                globItem.isAttribute = True
                # globItem.setIcon(
                #    0, ui_tools.colored_icon(":img/attr", "#5dade2"))
                globItem.setIcon(0, QIcon(":img/attr"))
                globItem.setExpanded(self._get_expand(globItem))

        if 'functions' in symbols and symbols['functions']:
            functionsItem = ItemTree(parent, [translations.TR_FUNCTIONS])
            functionsItem.isClickable = False
            functionsItem.isMethod = True
            functionsItem.setExpanded(self._get_expand(functionsItem))
            functionsItem.setToolTip(
                0,
                TIP.format(len(symbols['functions']),
                           translations.TR_FUNCTIONS))
            for func in sorted(symbols['functions']):
                item = ItemTree(functionsItem, [func],
                                lineno=symbols['functions'][func]['lineno'])
                tooltip = self.create_tooltip(
                    func, symbols['functions'][func]['lineno'])
                item.isMethod = True
                item.setIcon(0, QIcon(":img/function"))
                # item.setIcon(
                #    0, ui_tools.colored_icon(":img/function", "#9FA8DA"))
                item.setToolTip(0, tooltip)
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(
                    symbols['functions'][func]['functions'], parent=item)
        if 'classes' in symbols and symbols['classes']:
            classItem = ItemTree(parent, [translations.TR_CLASSES])
            classItem.isClickable = False
            classItem.isClass = True
            classItem.setExpanded(self._get_expand(classItem))
            classItem.setToolTip(
                0, TIP.format(len(symbols['classes']),
                              translations.TR_CLASSES))
            for claz in sorted(symbols['classes']):
                line_number = symbols['classes'][claz]['lineno']
                item = ItemTree(classItem, [claz], lineno=line_number)
                item.isClass = True
                tooltip = self.create_tooltip(claz, line_number)
                item.setToolTip(0, tooltip)
                # item.setIcon(0, ui_tools.colored_icon(":img/class", "#FFCC80"))
                # item.setIcon(0, ui_tools.get_icon('class', '#FFCC80'))
                item.setIcon(0, ui_tools.get_icon('class'))
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(symbols['classes'][claz]['members'],
                                         parent=item)

    def _go_to_definition(self, item):
        """ Takes and item object and goes to definition on the editor """

        main_container = IDE.get_service('main_container')
        if item.isClickable and main_container:
            main_container.editor_go_to_line(item.lineno - 1)

    def create_tooltip(self, name, lineno):
        """Takes a name and line number and returns a tooltip"""
        doc = self.docstrings.get(lineno, None)
        if doc is None:
            doc = ''
        else:
            doc = '\n' + doc
        tooltip = name + doc
        return tooltip

    def _item_collapsed(self, item):
        """When item collapsed"""
        super(TreeSymbolsWidget, self).collapseItem(item)

        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check:
            n = self._get_unique_name(item)
            filename = self.actualSymbols[0]
            self.collapsedItems.setdefault(filename, [])
            if n not in self.collapsedItems[filename]:
                self.collapsedItems[filename].append(n)

    def _item_expanded(self, item):
        """When item expanded"""
        super(TreeSymbolsWidget, self).expandItem(item)

        n = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        if n in self.collapsedItems.get(filename, []):
            self.collapsedItems[filename].remove(n)
            if not len(self.collapsedItems[filename]):
                # no more items, free space
                del self.collapsedItems[filename]

    def clean(self):
        """
        Reset the tree and reset attributes
        """
        self.tree.clear()
        self.collapsedItems = {}

    def reject(self):
        if self.parent() is None:
            self.dockWidget.emit(self)

    def closeEvent(self, event):
        """On Close event handling"""

        self.dockWidget.emit(self)
        # self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)
        event.ignore()
 def __init__(self, parent):
     QTreeWidget.__init__(self)
     self.parent = parent
     self.setHeaderLabels([_('Connected node'), _('Height')])
     self.setContextMenuPolicy(Qt.CustomContextMenu)
     self.customContextMenuRequested.connect(self.create_menu)
Esempio n. 60
0
class BookmarksWindow(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(BookmarksWindow, self).__init__(parent)
        self.setWindowTitle("Bookmarks")
        self.topLevelOperatorView = topLevelOperatorView
        self.bookmark_tree = QTreeWidget(self)
        self.bookmark_tree.setHeaderLabels(["Location", "Notes"])
        self.bookmark_tree.setSizePolicy(QSizePolicy.Preferred,
                                         QSizePolicy.Preferred)
        self.bookmark_tree.setColumnWidth(0, 200)
        self.bookmark_tree.setColumnWidth(1, 300)

        self.note_edit = QLineEdit(self)
        self.add_bookmark_button = QPushButton("Add Bookmark",
                                               self,
                                               clicked=self.add_bookmark)

        geometry = self.geometry()
        geometry.setSize(QSize(520, 520))
        self.setGeometry(geometry)

        layout = QVBoxLayout()
        layout.addWidget(self.bookmark_tree)
        layout.addWidget(self.note_edit)
        layout.addWidget(self.add_bookmark_button)
        self.setLayout(layout)

        self._load_bookmarks()

        self.bookmark_tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.bookmark_tree.customContextMenuRequested.connect(
            self.showContextMenu)

        self.bookmark_tree.itemDoubleClicked.connect(self._handle_doubleclick)

    def _handle_doubleclick(self, item, col):
        """
        Navigate to the bookmark
        """
        data = item.data(0, Qt.UserRole).toPyObject()
        if data is None:
            return

        (coord, notes) = data
        axes = self.topLevelOperatorView.InputImages.meta.getAxisKeys()
        axes = axes[:-1]  # drop channel
        axes = sorted(axes)
        assert len(axes) == len(coord)
        tagged_coord = dict(list(zip(axes, coord)))
        tagged_location = OrderedDict(list(zip("txyzc", (0, 0, 0, 0, 0))))
        tagged_location.update(tagged_coord)
        t = list(tagged_location.values())[0]
        coord3d = list(tagged_location.values())[1:4]

        self.parent().editor.posModel.time = t
        self.parent().editor.navCtrl.panSlicingViews(coord3d, [0, 1, 2])
        self.parent().editor.posModel.slicingPos = coord3d

    def showContextMenu(self, pos):
        item = self.bookmark_tree.itemAt(pos)
        data = item.data(0, Qt.UserRole).toPyObject()
        if data is None:
            return

        def delete_bookmark():
            (coord, notes) = data
            bookmarks = list(self.topLevelOperatorView.Bookmarks.value)
            i = bookmarks.index((coord, notes))
            bookmarks.pop(i)
            self.topLevelOperatorView.Bookmarks.setValue(bookmarks)
            self._load_bookmarks()

        menu = QMenu(parent=self)
        menu.addAction(QAction("Delete", menu, triggered=delete_bookmark))
        globalPos = self.bookmark_tree.viewport().mapToGlobal(pos)
        menu.exec_(globalPos)
        # selection = menu.exec_( globalPos )
        # if selection is removeLanesAction:
        #    self.removeLanesRequested.emit( self._selectedLanes )

    def add_bookmark(self):
        coord_txyzc = self.parent().editor.posModel.slicingPos5D
        tagged_coord_txyzc = dict(list(zip("txyzc", coord_txyzc)))
        axes = self.topLevelOperatorView.InputImages.meta.getAxisKeys()
        axes = axes[:-1]  # drop channel
        axes = sorted(axes)
        coord = tuple(tagged_coord_txyzc[c] for c in axes)

        notes = str(self.note_edit.text())
        bookmarks = list(self.topLevelOperatorView.Bookmarks.value)
        bookmarks.append((coord, notes))
        self.topLevelOperatorView.Bookmarks.setValue(bookmarks)

        self._load_bookmarks()

    def _load_bookmarks(self):
        self.bookmark_tree.clear()
        lane_index = self.topLevelOperatorView.current_view_index()
        lane_nickname = self.topLevelOperatorView.InputImages.meta.nickname or "Lane {}".format(
            lane_index)
        bookmarks = self.topLevelOperatorView.Bookmarks.value
        group_item = QTreeWidgetItem(self.bookmark_tree, [lane_nickname])

        for coord, notes in bookmarks:
            item = QTreeWidgetItem(group_item, [])
            item.setText(0, str(coord))
            item.setData(0, Qt.UserRole, (coord, notes))
            item.setText(1, notes)

        self.bookmark_tree.expandAll()