Beispiel #1
0
class charsPanel(QWidget):
    def __init__(self, parent=None):
        super(charsPanel, self).__init__(parent)
        # Do the layout: refresh button and filter popup at the top,
        # with a table below.
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        topLayout = QHBoxLayout()
        mainLayout.addLayout(topLayout, 0)
        self.refreshButton = QPushButton("Refresh")
        self.filterMenu = QComboBox()
        topLayout.addWidget(self.refreshButton, 0)
        topLayout.addStretch(1)
        topLayout.addWidget(self.filterMenu, 0)
        self.view = QTableView()
        self.view.setCornerButtonEnabled(False)
        self.view.setWordWrap(False)
        self.view.setAlternatingRowColors(True)
        mainLayout.addWidget(self.view, 1)
        # Set up the table model/view. Pass to the model a pointer
        # to the view so it can query the row under the mouse.
        self.model = myTableModel(view=self.view)
        #Interpose a sort filter proxy between the view and the model.
        self.proxy = mySortFilterProxy(self)
        self.proxy.setSourceModel(self.model)
        self.view.setModel(self.proxy)
        # Hook up the refresh button clicked signal to refresh below
        self.connect(self.refreshButton, SIGNAL("clicked()"), self.refresh)
        # Populate the filter popup with rows:
        # 0 : All - no filter
        # 1 : not 7-bit - show only things not in the 7-bit code
        # 2 : not Latin-1 - show only things outside Latin-1
        self.filterMenu.addItem(QString(u"All"))
        self.filterMenu.addItem(QString(u"\u00ac" + u" 7-bit"))
        self.filterMenu.addItem(QString(u"\u00ac" + u" Latin-1"))
        # The filters refer to these properties, called with a QChar C
        self.lambdaAll = lambda C: True
        self.lambdaNotAscii = lambda C: (C.unicode() < 32) or (C.unicode() >
                                                               126)
        self.lambdaNotLatin = lambda C: (C.toLatin1() == b'\x00')
        self.filterLambda = self.lambdaAll
        # Connect a user-selection in the popup to our filter method.
        self.connect(self.filterMenu, SIGNAL("activated(int)"), self.filter)
        # Connect doubleclicked from our table view to self.findThis
        self.connect(self.view, SIGNAL("doubleClicked(QModelIndex)"),
                     self.findThis)
        # Connect the model reset signals to functions to place and clear
        # a status message.
        self.connect(self.model, SIGNAL("modelAboutToBeReset()"),
                     self.sigResetStarting)
        self.connect(self.model, SIGNAL("modelReset()"), self.sigResetOver)

    # This slot receives a double-click on the table. Figure out which
    # character it is and get the Find panel set up to search for it.
    def findThis(self, qmi):
        rep = None
        if qmi.column() == 3:
            # doubleclick in entity column, put entity in the replace field
            rep = qmi.data(Qt.DisplayRole).toString()
        if qmi.column() != 0:
            # get reference to column 0
            qmi = qmi.sibling(qmi.row(), 0)
        qs = qmi.data(Qt.DisplayRole).toString()
        # Call for a find with respect case on, whole word and regex off
        IMC.findPanel.censusFinder(qs, rep, False, False)

    # this slot gets the activated(row) signal from the combo-box.
    # Based on the row, set self.filterLambda to a lambda that will
    # accept or reject a given QChar value.
    def filter(self, row):
        if row == 1: self.filterLambda = self.lambdaNotAscii
        elif row == 2: self.filterLambda = self.lambdaNotLatin
        else: self.filterLambda = self.lambdaAll
        self.model.reset()

    # This slot receives the main window's docWillChange signal.
    # It comes with a file path but we can ignore that.
    def docWillChange(self):
        #self.view.setSortingEnabled(False)
        self.model.beginResetModel()

    # Subroutine to reset the visual appearance of the table view,
    # invoked on table reset or docHasChanged because on instantiation
    # we have no data until a file is opened.
    def setUpTableView(self):
        self.view.resizeColumnsToContents()
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.resizeRowsToContents()
        self.view.setSortingEnabled(True)

    # This slot receives the main window's docHasChanged signal.
    # Let the table view populate with all-new metadata (or empty
    # data if the command was File>New).
    def docHasChanged(self):
        self.model.endResetModel()
        self.setUpTableView()

    # This slot receives the click of the refresh button. Tell the
    # model we are resetting everything so the view will suck up new
    # data. Then call our editor to rebuild the metadata.
    def refresh(self):
        #self.view.setSortingEnabled(False)
        self.model.beginResetModel()
        IMC.editWidget.rebuildMetadata()
        self.model.endResetModel()
        self.setUpTableView()

    # The model emits signals when it is starting to rebuild the table
    # and when it has finished rebuilding the table. Use these to put up
    # a status message, as the wait can be significant.
    def sigResetStarting(self):
        pqMsgs.showStatusMsg(QString(u"Rebuilding Character Table..."))

    def sigResetOver(self):
        pqMsgs.clearStatusMsg()
Beispiel #2
0
class pagesPanel(QWidget):
    def __init__(self, parent=None):
        super(pagesPanel, self).__init__(parent)
        # The layout is very basic, the table with an Update button.
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        hlayout = QHBoxLayout()
        self.updateButton = QPushButton("Update")
        self.insertText = QLineEdit()
        self.insertText.setFont(pqMsgs.getMonoFont())
        self.insertButton = QPushButton("Insert")
        hlayout.addWidget(self.updateButton,0)
        hlayout.addWidget(self.insertText,1) # text gets all available room
        hlayout.addWidget(self.insertButton,0)
        mainLayout.addLayout(hlayout)
        self.view = QTableView()
        self.view.setCornerButtonEnabled(False)
        self.view.setWordWrap(False)
        self.view.setAlternatingRowColors(True)
        self.view.setSortingEnabled(False)
        self.c1Delegate = formatDelegate()
        self.view.setItemDelegateForColumn(1,self.c1Delegate)
        self.c2Delegate = actionDelegate()
        self.view.setItemDelegateForColumn(2,self.c2Delegate)
        self.c3Delegate = folioDelegate()
        self.view.setItemDelegateForColumn(3,self.c3Delegate)
        mainLayout.addWidget(self.view,1)
        # Set up the table model/view.
        self.model = myTableModel()
        self.view.setModel(self.model)
        # Connect the double-clicked signal of the view
        self.connect(self.view, SIGNAL("doubleClicked(QModelIndex)"),
                    self.goToRow)
        # Connect the update button to the model's update method
        self.connect(self.updateButton, SIGNAL("clicked()"),self.model.updateFolios)
        # Connect the insert button to our insert method
        self.connect(self.insertButton, SIGNAL("clicked()"),self.insertMarkers)

    # This slot receives a double-click from the table view,
    # passing an index. If the click is in column 0, the scan number,
    # get the row; use it to get a text cursor from the page table
    # and make that the editor's cursor, thus moving to the top of that page.
    # Double-click on cols 1-3 initiates editing and maybe someday a
    # doubleclick on column 5 will do something with the proofer info.
    def goToRow(self,index):
        if index.column() == 0:
            tc = IMC.pageTable.getCursor(index.row())
            IMC.editWidget.setTextCursor(tc)
            IMC.editWidget.setFocus(Qt.TabFocusReason)

    # This slot receives the main window's docWillChange signal.
    # It comes with a file path but we can ignore that.
    def docWillChange(self):
        self.model.beginResetModel()

    # Subroutine to reset the visual appearance of the table view,
    # invoked on table reset because on instantiation we have no table.
    def setUpTableView(self):
        # Header text is supplied by the table model headerData method
        # Here we are going to set the column widths of the first 4
        # columns to a uniform 7 ens each based on the current font.
        # However, at least on Mac OS, the headers are rendered with a
        # much smaller font than the data, so we up it by 50%.
        hdr = self.view.horizontalHeader()
        pix = hdr.fontMetrics().width(QString("9999999"))
        hdr.resizeSection(0,pix)
        hdr.resizeSection(3,pix)
        pix += pix/2
        hdr.resizeSection(1,pix)
        hdr.resizeSection(2,pix)
        self.view.resizeColumnToContents(4)

    # This slot receives the main window's docHasChanged signal.
    # Let the table view populate with all-new metadata (or empty
    # data if the command was File>New).
    def docHasChanged(self):
        self.model.endResetModel()
        self.setUpTableView()

    # On the Insert button being pressed, make some basic sanity checks
    # and get user go-ahead then insert the given text at the head of
    # every page.
    def insertMarkers(self):
        # Copy the text and if it is empty, complain and exit.
        qi = QString(self.insertText.text())
        if qi.isEmpty() :
            pqMsgs.warningMsg("No insert text specified")
            return
        # See how many pages are involved: all the ones that aren't marked skip
        n = 0
        for i in range(IMC.pageTable.size()):
            if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip :
                n += 1
        if n == 0 : # page table empty or all rows marked skip
            pqMsgs.warningMsg("No pages to give folios to")
            return
        m = "Insert this string at the top of {0} pages?".format(n)
        b = pqMsgs.okCancelMsg(QString(m),pqMsgs.trunc(qi,35))
        if b :
            # Convert any '\n' in the text to the QT line delimiter char
            # we do this in the copy so the lineEdit text doesn't change
            qi.replace(QString(u'\\n'),QString(IMC.QtLineDelim))
            # get a cursor on the edit document
            tc = QTextCursor(IMC.editWidget.textCursor())
            tc.beginEditBlock() # start single undoable operation
            # Working from the end of the document backward, go to the
            # top of each page and insert the string
            for i in reversed( range( IMC.pageTable.size() ) ) :
                if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip :
                    # Note the page's start position and set our work cursor to it
                    pos = IMC.pageTable.getCursor(i).position()
                    tc.setPosition(pos)
                    # Make a copy of the insert string replacing %f with this folio
                    f = IMC.pageTable.getDisplay(i)
                    qf = QString(qi)
                    qf.replace(QString(u'%f'),f,Qt.CaseInsensitive)
                    tc.insertText(qf)
                    # The insertion goes in ahead of the saved cursor position so now
                    # it points after the inserted string. Put it back where it was.
                    IMC.pageTable.setPosition(i, pos)
            tc.endEditBlock() # wrap up the undo op
Beispiel #3
0
class pagesPanel(QWidget):
    def __init__(self, parent=None):
        super(pagesPanel, self).__init__(parent)
        # The layout is very basic, the table with an Update button.
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        hlayout = QHBoxLayout()
        self.updateButton = QPushButton("Update")
        self.insertText = QLineEdit()
        self.insertText.setFont(pqMsgs.getMonoFont())
        self.insertButton = QPushButton("Insert")
        hlayout.addWidget(self.updateButton, 0)
        hlayout.addWidget(self.insertText, 1)  # text gets all available room
        hlayout.addWidget(self.insertButton, 0)
        mainLayout.addLayout(hlayout)
        self.view = QTableView()
        self.view.setCornerButtonEnabled(False)
        self.view.setWordWrap(False)
        self.view.setAlternatingRowColors(True)
        self.view.setSortingEnabled(False)
        self.c1Delegate = formatDelegate()
        self.view.setItemDelegateForColumn(1, self.c1Delegate)
        self.c2Delegate = actionDelegate()
        self.view.setItemDelegateForColumn(2, self.c2Delegate)
        self.c3Delegate = folioDelegate()
        self.view.setItemDelegateForColumn(3, self.c3Delegate)
        mainLayout.addWidget(self.view, 1)
        # Set up the table model/view.
        self.model = myTableModel()
        self.view.setModel(self.model)
        # Connect the double-clicked signal of the view
        self.connect(self.view, SIGNAL("doubleClicked(QModelIndex)"),
                     self.goToRow)
        # Connect the update button to the model's update method
        self.connect(self.updateButton, SIGNAL("clicked()"),
                     self.model.updateFolios)
        # Connect the insert button to our insert method
        self.connect(self.insertButton, SIGNAL("clicked()"),
                     self.insertMarkers)

    # This slot receives a double-click from the table view,
    # passing an index. If the click is in column 0, the scan number,
    # get the row; use it to get a text cursor from the page table
    # and make that the editor's cursor, thus moving to the top of that page.
    # Double-click on cols 1-3 initiates editing and maybe someday a
    # doubleclick on column 5 will do something with the proofer info.
    def goToRow(self, index):
        if index.column() == 0:
            tc = IMC.pageTable.getCursor(index.row())
            IMC.editWidget.setTextCursor(tc)
            IMC.editWidget.setFocus(Qt.TabFocusReason)

    # This slot receives the main window's docWillChange signal.
    # It comes with a file path but we can ignore that.
    def docWillChange(self):
        self.model.beginResetModel()

    # Subroutine to reset the visual appearance of the table view,
    # invoked on table reset because on instantiation we have no table.
    def setUpTableView(self):
        # Header text is supplied by the table model headerData method
        # Here we are going to set the column widths of the first 4
        # columns to a uniform 7 ens each based on the current font.
        # However, at least on Mac OS, the headers are rendered with a
        # much smaller font than the data, so we up it by 50%.
        hdr = self.view.horizontalHeader()
        pix = hdr.fontMetrics().width(QString("9999999"))
        hdr.resizeSection(0, pix)
        hdr.resizeSection(3, pix)
        pix += pix / 2
        hdr.resizeSection(1, pix)
        hdr.resizeSection(2, pix)
        self.view.resizeColumnToContents(4)

    # This slot receives the main window's docHasChanged signal.
    # Let the table view populate with all-new metadata (or empty
    # data if the command was File>New).
    def docHasChanged(self):
        self.model.endResetModel()
        self.setUpTableView()

    # On the Insert button being pressed, make some basic sanity checks
    # and get user go-ahead then insert the given text at the head of
    # every page.
    def insertMarkers(self):
        # Copy the text and if it is empty, complain and exit.
        qi = QString(self.insertText.text())
        if qi.isEmpty():
            pqMsgs.warningMsg("No insert text specified")
            return
        # See how many pages are involved: all the ones that aren't marked skip
        n = 0
        for i in range(IMC.pageTable.size()):
            if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip:
                n += 1
        if n == 0:  # page table empty or all rows marked skip
            pqMsgs.warningMsg("No pages to give folios to")
            return
        m = "Insert this string at the top of {0} pages?".format(n)
        b = pqMsgs.okCancelMsg(QString(m), pqMsgs.trunc(qi, 35))
        if b:
            # Convert any '\n' in the text to the QT line delimiter char
            # we do this in the copy so the lineEdit text doesn't change
            qi.replace(QString(u'\\n'), QString(IMC.QtLineDelim))
            # get a cursor on the edit document
            tc = QTextCursor(IMC.editWidget.textCursor())
            tc.beginEditBlock()  # start single undoable operation
            # Working from the end of the document backward, go to the
            # top of each page and insert the string
            for i in reversed(range(IMC.pageTable.size())):
                if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip:
                    # Note the page's start position and set our work cursor to it
                    pos = IMC.pageTable.getCursor(i).position()
                    tc.setPosition(pos)
                    # Make a copy of the insert string replacing %f with this folio
                    f = IMC.pageTable.getDisplay(i)
                    qf = QString(qi)
                    qf.replace(QString(u'%f'), f, Qt.CaseInsensitive)
                    tc.insertText(qf)
                    # The insertion goes in ahead of the saved cursor position so now
                    # it points after the inserted string. Put it back where it was.
                    IMC.pageTable.setPosition(i, pos)
            tc.endEditBlock()  # wrap up the undo op
Beispiel #4
0
class charsPanel(QWidget):
    def __init__(self, parent=None):
        super(charsPanel, self).__init__(parent)
        # Do the layout: refresh button and filter popup at the top,
        # with a table below.
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        topLayout = QHBoxLayout()
        mainLayout.addLayout(topLayout, 0)
        self.refreshButton = QPushButton("Refresh")
        self.filterMenu = QComboBox()
        topLayout.addWidget(self.refreshButton, 0)
        topLayout.addStretch(1)
        topLayout.addWidget(self.filterMenu, 0)
        self.view = QTableView()
        self.view.setCornerButtonEnabled(False)
        self.view.setWordWrap(False)
        self.view.setAlternatingRowColors(True)
        mainLayout.addWidget(self.view, 1)
        # Set up the table model/view. Pass to the model a pointer
        # to the view so it can query the row under the mouse.
        self.model = myTableModel(view=self.view)
        # Interpose a sort filter proxy between the view and the model.
        self.proxy = mySortFilterProxy(self)
        self.proxy.setSourceModel(self.model)
        self.view.setModel(self.proxy)
        # Hook up the refresh button clicked signal to refresh below
        self.connect(self.refreshButton, SIGNAL("clicked()"), self.refresh)
        # Populate the filter popup with rows:
        # 0 : All - no filter
        # 1 : not 7-bit - show only things not in the 7-bit code
        # 2 : not Latin-1 - show only things outside Latin-1
        self.filterMenu.addItem(QString("All"))
        self.filterMenu.addItem(QString("\u00ac" + " 7-bit"))
        self.filterMenu.addItem(QString("\u00ac" + " Latin-1"))
        # The filters refer to these properties, called with a QChar C
        self.lambdaAll = lambda C: True
        self.lambdaNotAscii = lambda C: (C.unicode() < 32) or (C.unicode() > 126)
        self.lambdaNotLatin = lambda C: (C.toLatin1() == b"\x00")
        self.filterLambda = self.lambdaAll
        # Connect a user-selection in the popup to our filter method.
        self.connect(self.filterMenu, SIGNAL("activated(int)"), self.filter)
        # Connect doubleclicked from our table view to self.findThis
        self.connect(self.view, SIGNAL("doubleClicked(QModelIndex)"), self.findThis)
        # Connect the model reset signals to functions to place and clear
        # a status message.
        self.connect(self.model, SIGNAL("modelAboutToBeReset()"), self.sigResetStarting)
        self.connect(self.model, SIGNAL("modelReset()"), self.sigResetOver)

    # This slot receives a double-click on the table. Figure out which
    # character it is and get the Find panel set up to search for it.
    def findThis(self, qmi):
        rep = None
        if qmi.column() == 3:
            # doubleclick in entity column, put entity in the replace field
            rep = qmi.data(Qt.DisplayRole).toString()
        if qmi.column() != 0:
            # get reference to column 0
            qmi = qmi.sibling(qmi.row(), 0)
        qs = qmi.data(Qt.DisplayRole).toString()
        # Call for a find with respect case on, whole word and regex off
        IMC.findPanel.censusFinder(qs, rep, False, False)

    # this slot gets the activated(row) signal from the combo-box.
    # Based on the row, set self.filterLambda to a lambda that will
    # accept or reject a given QChar value.
    def filter(self, row):
        if row == 1:
            self.filterLambda = self.lambdaNotAscii
        elif row == 2:
            self.filterLambda = self.lambdaNotLatin
        else:
            self.filterLambda = self.lambdaAll
        self.model.reset()

    # This slot receives the main window's docWillChange signal.
    # It comes with a file path but we can ignore that.
    def docWillChange(self):
        # self.view.setSortingEnabled(False)
        self.model.beginResetModel()

    # Subroutine to reset the visual appearance of the table view,
    # invoked on table reset or docHasChanged because on instantiation
    # we have no data until a file is opened.
    def setUpTableView(self):
        self.view.resizeColumnsToContents()
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.resizeRowsToContents()
        self.view.setSortingEnabled(True)

    # This slot receives the main window's docHasChanged signal.
    # Let the table view populate with all-new metadata (or empty
    # data if the command was File>New).
    def docHasChanged(self):
        self.model.endResetModel()
        self.setUpTableView()

    # This slot receives the click of the refresh button. Tell the
    # model we are resetting everything so the view will suck up new
    # data. Then call our editor to rebuild the metadata.
    def refresh(self):
        # self.view.setSortingEnabled(False)
        self.model.beginResetModel()
        IMC.editWidget.rebuildMetadata()
        self.model.endResetModel()
        self.setUpTableView()

    # The model emits signals when it is starting to rebuild the table
    # and when it has finished rebuilding the table. Use these to put up
    # a status message, as the wait can be significant.
    def sigResetStarting(self):
        pqMsgs.showStatusMsg(QString("Rebuilding Character Table..."))

    def sigResetOver(self):
        pqMsgs.clearStatusMsg()