Exemplo n.º 1
0
class HistoryManagerWidget(QWidget):

    def __init__(self):
        super().__init__()

        self.listHistory = []
        self.nam = QtNetwork.QNetworkAccessManager()

        self.setting = QSettings()

        self.searchLineEdit = QLineEdit()
        self.tableView = QTableView()
        self.columnComboBox = QComboBox()
        self.searchLabel = QLabel()
        self.searchLabel.setText("Filter")

        self.model = QStandardItemModel(self)

        searchHbox = QHBoxLayout()
        searchHbox.addWidget(self.searchLabel)
        searchHbox.addWidget(self.searchLineEdit)
        searchHbox.addWidget(self.columnComboBox)

        self.header = "Order ID;Order Status;Card ID;Menu ID;Menu Name;Price;Qty;" \
                 "Item Status;Table Number;Order Time;Modified Time".split(";")
        self.model.setHorizontalHeaderLabels(self.header)
        self.tableView.horizontalHeader().setStretchLastSection(True)

        hboxLayout = QHBoxLayout()
        self.backButton = QPushButton()
        self.backButton.setText("Back")

        self.refreshButton = QPushButton()
        self.refreshButton.setText("Refresh")
        self.refreshButton.clicked.connect(self.refresh)

        self.saveCSVButton = QPushButton()
        self.saveCSVButton.setText("Save as CSV")
        self.saveCSVButton.clicked.connect(self.saveCSV)

        hboxLayout.addWidget(self.backButton)
        hboxLayout.addWidget(self.refreshButton)
        hboxLayout.addWidget(self.saveCSVButton)

        widgetTitleLabel = QLabel()
        widgetTitleLabel.setAlignment(Qt.AlignCenter)
        widgetTitleLabel.setText("History Manager")

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(widgetTitleLabel)
        mainLayout.addLayout(searchHbox)
        mainLayout.addWidget(self.tableView)
        mainLayout.addLayout(hboxLayout)

        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)

        self.tableView.setModel(self.proxy)
        self.columnComboBox.addItems(self.header)

        self.searchLineEdit.textChanged.connect(self.on_lineEdit_textChanged)
        self.columnComboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)

        self.horizontalHeader = self.tableView.horizontalHeader()

        self.setLayout(mainLayout)

    def saveCSV(self):
        data = ""
        rows = self.model.rowCount()
        columns = self.model.columnCount()

        if rows>0:
            for title in self.header:
                data += title
                data += ","
            data += "\n"
            for i in range(rows):
                for j in range(columns):
                    index = self.model.index(i,j)
                    # print(str(self.model.data(index)))
                    data += str(self.model.data(index))
                    data += ","
                data += "\n"

            name, _ = QFileDialog.getSaveFileName(self, 'Save File', "History SELFO.csv", "csv(*.csv)")
            if name:
                file = open(name, 'w')
                file.write(data)
                file.close()
        else:
            QMessageBox.critical(self, "Error", "No Data")

    def clear(self):
        self.listHistory.clear()
        self.model.clear()
        self.model.setHorizontalHeaderLabels(self.header)

    def refresh(self):
        self.clear()
        self.doRequestOrderDetail()

    def populateList(self):
        for rowName in range(len(self.listHistory)):
            self.model.invisibleRootItem().appendRow(
                [QStandardItem("{}".format(self.listHistory[rowName][column]))
                 for column in range(len(self.header))
                 ]
            )
        self.tableView.resizeColumnsToContents()

    def closeHistoryManager(self):
        self.mainWindow.stackedWidget.removeWidget(self)

    def doRequestOrderDetail(self):
        url = self.setting.value("baseURL", "")
        url += "/orderdetail/?sellerID=" + str(self.setting.value("sellerID", "")) \
               # + "&itemStatus=" + "placed"
        req = QtNetwork.QNetworkRequest(QUrl(url))

        reply = self.nam.get(req)
        reply.finished.connect(self.handleResponseOrderDetail)

    def handleResponseOrderDetail(self):
        reply = self.sender()

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()
            data = json.loads(str(bytes_string, 'utf-8'))
            # print(data)

            for history in data:
                # id = history['id']
                orderID = history['orderID']
                orderStatus = history['orderStatus']
                cardID = history['cardID']
                # sellerID = history['sellerID']
                menuID = history['menuID']
                menuName = history['menuName']
                itemStatus = history['itemStatus']
                price = formatRupiah(history['price'])
                qty = history['qty']
                tableNumber = history['tableNumber']
                rawOrderTime = history['orderTime']
                orderTime = datetime.datetime.strptime(
                    rawOrderTime, "%Y-%m-%dT%H:%M:%S.%f+07:00").strftime("%d %b %Y %H:%M:%S")
                rawModifiedTime = history['modifiedTime']
                if rawModifiedTime is not None:
                    modifiedTime = datetime.datetime.strptime(
                        rawModifiedTime, "%Y-%m-%dT%H:%M:%S.%f+07:00").strftime("%d %b %Y %H:%M:%S")
                else:
                    modifiedTime = "null"
                historyItem = [orderID, orderStatus, cardID, menuID, menuName, price, qty, itemStatus, tableNumber, orderTime, modifiedTime]
                self.listHistory.append(historyItem)

            self.populateList()

        else:
            errorMessage = "Error occured: " + str(er) + "\n" + str(reply.errorString())
            QMessageBox.critical(self, "Error Order Detail", errorMessage)
        reply.deleteLater()

    def on_view_horizontalHeader_sectionClicked(self, logicalIndex):
        self.logicalIndex   = logicalIndex
        self.menuValues     = QMenu(self)
        self.signalMapper   = QSignalMapper(self)

        self.columnComboBox.blockSignals(True)
        self.columnComboBox.setCurrentIndex(self.logicalIndex)
        self.columnComboBox.blockSignals(True)

        valuesUnique = [    self.model.item(row, self.logicalIndex).text()
                            for row in range(self.model.rowCount())
                            ]

        actionAll = QAction("All", self)
        actionAll.triggered.connect(self.on_actionAll_triggered)
        self.menuValues.addAction(actionAll)
        self.menuValues.addSeparator()

        for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)
            action.triggered.connect(self.signalMapper.map)
            self.menuValues.addAction(action)

        self.signalMapper.mapped.connect(self.on_signalMapper_mapped)

        headerPos = self.tableView.mapToGlobal(self.horizontalHeader.pos())

        posY = headerPos.y() + self.horizontalHeader.height()
        posX = headerPos.x() + self.horizontalHeader.sectionPosition(self.logicalIndex)

        self.menuValues.exec_(QPoint(posX, posY))

    def on_actionAll_triggered(self):
        filterColumn = self.logicalIndex
        filterString = QRegExp(  "",
                                        Qt.CaseInsensitive,
                                        QRegExp.RegExp
                                        )

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def on_signalMapper_mapped(self, i):
        stringAction = self.signalMapper.mapping(i).text()
        filterColumn = self.logicalIndex
        filterString = QRegExp(  stringAction,
                                        Qt.CaseSensitive,
                                        QRegExp.FixedString
                                        )

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def on_lineEdit_textChanged(self, text):
        search = QRegExp(    text,
                                    Qt.CaseInsensitive,
                                    QRegExp.RegExp
                                    )

        self.proxy.setFilterRegExp(search)

    def on_comboBox_currentIndexChanged(self, index):
        self.proxy.setFilterKeyColumn(index)
class ScanTableWidget(QWidget):
    """
    Used for displaying information in a table.

    ===============================  =========================================
    **Signals:**
    sigScanClicked                   Emitted when the user has clicked
                                     on a row of the table and returns the
                                     current index. This index contains
                                     information about the current rows column
                                     data.

    ===============================  =========================================
    """

    sigScanClicked = pyqtSignal(QModelIndex, name="scanClicked")

    header = [
        "MS level",
        "Index",
        "RT (min)",
        "precursor m/z",
        "charge",
        "ID",
        "PeptideSeq",
        "PeptideIons",
    ]

    def __init__(self, ms_experiment, *args):
        QWidget.__init__(self, *args)
        self.ms_experiment = ms_experiment

        self.table_model = ScanTableModel(self, self.ms_experiment,
                                          self.header)
        self.table_view = QTableView()

        # register a proxy class for filering and sorting the scan table
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.table_model)

        self.table_view.sortByColumn(1, Qt.AscendingOrder)

        # setup selection model
        self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.setModel(self.proxy)
        self.table_view.setSelectionModel(QItemSelectionModel(self.proxy))

        # header
        self.horizontalHeader = self.table_view.horizontalHeader()
        self.horizontalHeader.sectionClicked.connect(self.onHeaderClicked)

        # enable sorting
        self.table_view.setSortingEnabled(True)

        # connect signals to slots
        self.table_view.selectionModel().currentChanged.connect(
            self.onCurrentChanged)  # keyboard moves to new row
        self.horizontalHeader.sectionClicked.connect(self.onHeaderClicked)

        layout = QVBoxLayout(self)
        layout.addWidget(self.table_view)
        self.setLayout(layout)

        # hide column 7 with the PepIon data, intern information usage
        self.table_view.setColumnHidden(7, True)

        # Add rt in minutes for better TIC interaction
        self.table_view.setItemDelegateForColumn(2, RTUnitDelegate(self))
        self.table_view.setColumnWidth(2, 160)

        # default : first row selected. in OpenMSWidgets

    def onRowSelected(self, index):
        """se_comment: hard-refactoring to comply to pep8"""
        if index.siblingAtColumn(1).data() is None:
            return  # prevents crash if row gets filtered out
        self.curr_spec = self.ms_experiment.getSpectrum(
            index.siblingAtColumn(1).data())
        self.scanClicked.emit(index)

    def onCurrentChanged(self, new_index, old_index):
        self.onRowSelected(new_index)

    def onHeaderClicked(self, logicalIndex):
        if logicalIndex != 0:
            return  # allow filter on first column only for now

        self.logicalIndex = logicalIndex
        self.menuValues = QMenu(self)
        self.signalMapper = QSignalMapper(self)

        # get unique values from (unfiltered) model
        valuesUnique = set([
            self.table_model.index(row, self.logicalIndex).data()
            for row in range(
                self.table_model.rowCount(
                    self.table_model.index(-1, self.logicalIndex)))
        ])

        if len(valuesUnique) == 1:
            return  # no need to select anything

        actionAll = QAction("Show All", self)
        actionAll.triggered.connect(self.onShowAllRows)
        self.menuValues.addAction(actionAll)
        self.menuValues.addSeparator()
        """se_comment: hard-refactoring to comply to pep8"""
        l: enumerate = enumerate(sorted(list(set(valuesUnique))))
        for actionNumber, actionName in l:
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)
            action.triggered.connect(self.signalMapper.map)
            self.menuValues.addAction(action)

        self.signalMapper.mapped.connect(self.onSignalMapper)

        # get screen position of table header and open menu
        headerPos = self.table_view.mapToGlobal(self.horizontalHeader.pos())
        posY = headerPos.y() + self.horizontalHeader.height()
        posX = headerPos.x() + \
            self.horizontalHeader.sectionPosition(self.logicalIndex)
        self.menuValues.exec_(QPoint(posX, posY))

    def onShowAllRows(self):
        filterColumn = self.logicalIndex
        filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def onSignalMapper(self, i):
        stringAction = self.signalMapper.mapping(i).text()
        filterColumn = self.logicalIndex
        filterString = QRegExp(stringAction, Qt.CaseSensitive,
                               QRegExp.FixedString)

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)
Exemplo n.º 3
0
class FilterableTable(SQLTable):
    """a filterable Table Widget that displays content of an SQLite table;
    for individual widgets, subclass 
     and overwrite the create_model method;
    add_color_proxy should be an (INT allele_status-column, INT lab_status-column) tuple
    """
    def __init__(self, log, mydb = ": memory :", add_color_proxy = False, header_dic = None):
        super().__init__(log, mydb)
        self.add_color_proxy = add_color_proxy
        self.header_dic = header_dic
        self.create_model()
        self.fill_UI()
        self.create_filter_model()
        self.update_filterbox()
        
    def fill_UI(self):
        """sets up the layout
        """
        self.log.debug("\t- Setting up the table...")
        self.table = QTableView()
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.header = self.table.horizontalHeader() # table header
        self.header.setSectionResizeMode(QHeaderView.ResizeToContents)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setAlternatingRowColors(True)
#         self.header.sectionClicked.connect(self.on_header_sectionClicked)
        
        mode = QAbstractItemView.SingleSelection
        self.table.setSelectionMode(mode)
        
        self.grid.addWidget(self.table, 2, 0, 10, 10)

        self.filter_lbl = QLabel("Filter:", self)
        self.grid.addWidget(self.filter_lbl, 1, 2)
        
        self.filter_entry = QLineEdit(self)
        self.grid.addWidget(self.filter_entry, 1, 3)
        self.filter_entry.textChanged.connect(self.on_filter_entry_textChanged)
        self.filter_text = ""
        
        self.filter_cb = QComboBox(self)
        self.grid.addWidget(self.filter_cb, 1, 4)
        self.filter_cb.currentIndexChanged.connect(self.on_filter_cb_IndexChanged)
        
        self.filter_btn = QPushButton("Filter!", self)
        self.grid.addWidget(self.filter_btn, 1, 5)
        self.filter_btn.clicked.connect(self.on_filter_btn_clicked)
        
        self.unfilter_btn = QPushButton("Remove Filter", self)
        self.grid.addWidget(self.unfilter_btn, 1, 6)
        self.unfilter_btn.clicked.connect(self.on_actionAll_triggered)
        
        self.log.debug("\t=> Done!")
    
    def update_filterbox(self):
        """fills the filter-combobox with the header values 
        after the model has been created and set
        """
        column_num = self.model.columnCount()
        if self.header_dic:
            columns = [self.header_dic[i] for i in self.header_dic]
        else:
            columns = [self.proxy.headerData(i, Qt.Horizontal) for i in range(column_num)]
        self.filter_cb.addItems(columns)

    def create_filter_model(self):
        """creates the filter-proxy-model on top of self.model
        """
        self.log.debug("Creating filter model...")
        self.proxy = QSortFilterProxyModel(self)
        if self.add_color_proxy:
            (allele_status_column, lab_status_column) = self.add_color_proxy
            self.log.debug("adding color filter to columns {} and {}".format(allele_status_column, lab_status_column))
            self.color_proxy = ColorProxyModel(self, allele_status_column, lab_status_column)
            self.color_proxy.setSourceModel(self.model)
            self.proxy.setSourceModel(self.color_proxy)
        else:
            self.proxy.setSourceModel(self.model)
        self.table.setSortingEnabled(True)
        self.table.setModel(self.proxy)
        
    def on_filter_cb_IndexChanged(self, index):
        """restricts RegEx filter to selected column
        """
        self.log.debug("Combobox: colum {} selected".format(index))
        self.proxy.setFilterKeyColumn(index)
    
    def on_filter_entry_textChanged(self, text):
        """stores content of filter_entry as self.text 
        """
        self.log.debug("filter text: '{}'".format(text))
        self.filter_text = text
    
    def on_filter_btn_clicked(self):
        """activates RegEx filter to current content of filter_entry and filter_cb
        """
        column = self.filter_cb.currentIndex()
        self.log.debug("Filtering column {} for '{}'".format(column, self.filter_text))
        self.proxy.setFilterKeyColumn(column)
        search = QRegExp(self.filter_text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
    
    def on_header_sectionClicked(self, logicalIndex):
        """opens a dialog to choose between all unique values for this column,
        or revert to 'All'
        """
        self.log.debug("Header clicked: column {}".format(logicalIndex))
        self.logicalIndex = logicalIndex
        menuValues = QMenu(self)
        self.signalMapper = QSignalMapper(self)  
  
        self.filter_cb.setCurrentIndex(self.logicalIndex)
        self.filter_cb.blockSignals(True)
        self.proxy.setFilterKeyColumn(self.logicalIndex)
        
        valuesUnique = [str(self.model.index(row, self.logicalIndex).data())
                        for row in range(self.model.rowCount())
                        ]
        
        actionAll = QAction("All", self)
        actionAll.triggered.connect(self.on_actionAll_triggered)
        menuValues.addAction(actionAll)
        menuValues.addSeparator()
        
        for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):              
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)  
            action.triggered.connect(self.signalMapper.map)  
            menuValues.addAction(action)
  
        self.signalMapper.mapped.connect(self.on_signalMapper_mapped)  
  
        headerPos = self.table.mapToGlobal(self.header.pos())        
        posY = headerPos.y() + self.header.height()
        posX = headerPos.x() + self.header.sectionViewportPosition(self.logicalIndex)
  
        menuValues.exec_(QPoint(posX, posY))
      
    def on_actionAll_triggered(self):
        """reverts table to unfiltered state
        """
        self.log.debug("Unfiltering...")
        filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(filterString)
        self.filter_entry.setText("")
  
    def on_signalMapper_mapped(self, i):
        """filters current column to mapping text
        """
        text = self.signalMapper.mapping(i).text()
        self.log.debug("Filtering column {} to '{}'".format(self.logicalIndex, text))
        filterString = QRegExp(text, Qt.CaseSensitive, QRegExp.FixedString)
        self.proxy.setFilterRegExp(filterString)