def showDialog(self, currentCard=None):
        if currentCard:
            did = currentCard.did
        else:
            did = mw._selectedDeck()['id']

        cardInfo = self._getCardInfo(did)
        if not cardInfo:
            showInfo('Please select an Incremental Reading deck.')
            return

        dialog = QDialog(mw)
        layout = QVBoxLayout()
        self.cardListWidget = QListWidget()
        self.cardListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)

        posWidth = len(str(len(cardInfo) + 1))
        for i, card in enumerate(cardInfo, start=1):
            text = '❰ {} ❱\t{}'.format(str(i).zfill(posWidth), card['title'])
            item = QListWidgetItem(text)
            item.setData(Qt.UserRole, card)
            self.cardListWidget.addItem(item)

        upButton = QPushButton('Up')
        upButton.clicked.connect(self._moveUp)
        downButton = QPushButton('Down')
        downButton.clicked.connect(self._moveDown)
        randomizeButton = QPushButton('Randomize')
        randomizeButton.clicked.connect(self._randomize)

        controlsLayout = QHBoxLayout()
        controlsLayout.addStretch()
        controlsLayout.addWidget(upButton)
        controlsLayout.addWidget(downButton)
        controlsLayout.addWidget(randomizeButton)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                     | QDialogButtonBox.Save)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        buttonBox.setOrientation(Qt.Horizontal)

        layout.addLayout(controlsLayout)
        layout.addWidget(self.cardListWidget)
        layout.addWidget(buttonBox)

        dialog.setLayout(layout)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.resize(500, 500)
        choice = dialog.exec_()

        if choice == 1:
            cids = []
            for i in range(self.cardListWidget.count()):
                card = self.cardListWidget.item(i).data(Qt.UserRole)
                cids.append(card['id'])

            self.reorder(cids)
    def showDialog(self, currentCard=None):
        # Handle for dialog open without a current card from IR model
        did = None
        cid = None
        if not currentCard:
            deck = mw._selectedDeck()
            did = deck['id']
        else:
            did = currentCard.did
            cid = currentCard.id

        cardDataList = self.getCardDataList(did, cid)
        if not cardDataList:
            showInfo(_('Please select an Incremental Reading deck.'))
            return

        d = QDialog(mw)
        l = QVBoxLayout()
        w = AnkiWebView()
        l.addWidget(w)

        script = '''
        var cardList = new Array();
        '''
        index = 0
        for cardData in cardDataList:
            index += 1
            script += "card = new Object();"
            script += "card.id = " + str(cardData['id']) + ";"
            script += "card.title = '" + str(cardData['title']) + "';"
            script += "card.isCurrent = " + str(cardData['isCurrent']) + ";"
            script += "card.checkbox = document.createElement('input');"
            script += "card.checkbox.type = 'checkbox';"
            if cardData['isCurrent'] == 'true':
                script += "card.checkbox.setAttribute('checked', 'true');"
            script += "cardList[cardList.length] = card;"

        script += """
        function buildCardData() {
            var container = document.getElementById('cardList');
            container.innerHTML = '';
            var list = document.createElement('div');
            list.setAttribute('style','overflow:auto;');
            var table = document.createElement('table');
            list.appendChild(table);
            container.appendChild(list);
            var row;
            var col;
            var cardData;
            for (var i = 0; i < cardList.length; i++) {
                row = document.createElement('tr');
                row.setAttribute('id','row' + i);
                cardData = cardList[i];

                col = document.createElement('td');
                col.setAttribute('style','width:4em;');
                col.innerHTML = '' + i;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:10em;');
                col.innerHTML = '' + cardData.id;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:30em;');
                col.innerHTML = '' + cardData.title;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:2em;');
                col.appendChild(cardData.checkbox);
                row.appendChild(col);

                table.appendChild(row);
            }
        }

        function reposition(origIndex, newIndex, isTopOfRange) {
            if (newIndex < 0 || newIndex > (cardList.length-1)) return -1;
            if (cardList[newIndex].checkbox.checked) return -1;

            if (isTopOfRange) {
                document.getElementById('newPos').value = newIndex;
            }
            var removedCards = cardList.splice(origIndex,1);
            cardList.splice(newIndex, 0, removedCards[0]);
            return newIndex;
        }

        function moveSelectedUp() {
            var topOfRange = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    if (i == topOfRange) {
                        if (document.getElementById('anchor').checked) {
                            continue; //Don't move end of range if anchored.
                        } else {
                            reposition(i, i - 1, true);
                        }
                    } else {
                        reposition(i, i - 1, false);
                    }
                }
            }
            buildCardData();
        }

        function moveSelectedDown() {
            var topOfRange = -1;
            var bottomOfRange = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    bottomOfRange = i;
                }
            }
            for (var i = cardList.length-1; i > -1; i--) {
                if (cardList[i].checkbox.checked) {
                    if (i == bottomOfRange &&
                            document.getElementById('anchor').checked) {
                        continue; //Don't move end of range if anchored.
                    }
                    if (i == topOfRange) {
                        reposition(i, i + 1, true);
                    } else {
                        reposition(i, i + 1, false);
                    }
                }
            }
            buildCardData();
        }

        function selectAll() {
            for (var i = 0; i < cardList.length; i++) {
                cardList[i].checkbox.checked = true;
            }
        }

        function selectNone() {
            for (var i = 0; i < cardList.length; i++) {
                cardList[i].checkbox.checked = false;
            }
        }

        function directMove() {
            var newIndex = document.getElementById('newPos').value;
            var topOfRange = -1;
            origIndex = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    if (origIndex == -1) {
                        origIndex = i;
                        sizeOfMove = (newIndex - origIndex);
                    }
                }
            }
            if (sizeOfMove < 0) {
                for (var i = 0; i < cardList.length; i++) {
                    if (cardList[i].checkbox.checked) {
                        if (i == topOfRange) {
                            reposition(i, i + sizeOfMove, true);
                        } else {
                            reposition(i, i + sizeOfMove, false);
                        }
                    }
                }
            } else {
                for (var i = cardList.length-1; i > -1; i--) {
                    if (cardList[i].checkbox.checked) {
                        if (i == topOfRange) {
                            reposition(i, i + sizeOfMove, true);
                        } else {
                            reposition(i, i + sizeOfMove, false);
                        }
                    }
                }
            }
            buildCardData();
        }

        function updatePositions() {
            var cids = new Array();
            for (var i=0; i < cardList.length; i++) {
                cids[cids.length] = parseInt(cardList[i].id);
            }
            return cids.join();
        };
        """

        newPosField = "<span style='font-weight:bold'>Card Position: </span><input type='text' id='newPos' size='5' value='0' />&nbsp;<span style='font-weight:bold'>of " + str(
            len(cardDataList)) + "</span>&nbsp;&nbsp;"
        newPosField += "<input type='button' value='Apply' onclick='directMove()' />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-weight:bold'>Pin Top/Bottom? </span><input type='checkbox' id='anchor'/>"

        upDownButtons = "<input type='button' value='Move Up' onclick='moveSelectedUp()'/><input type='button' value='Move Down' onclick='moveSelectedDown()'/>"
        upDownButtons += "<input type='button' value='Select All' onclick='selectAll()'/><input type='button' value='Select None' onclick='selectNone()'/>"

        html = "<html><head><script>" + script + "</script></head><body onLoad='buildCardData()'>"
        html += "<p>" + newPosField
        html += "<p>" + upDownButtons
        html += "<div id='cardList'></div>"
        html += "</body></html>"
        w.stdHtml(html)
        bb = QDialogButtonBox(QDialogButtonBox.Close | QDialogButtonBox.Save)
        bb.accepted.connect(d.accept)
        bb.rejected.connect(d.reject)
        bb.setOrientation(Qt.Horizontal)
        l.addWidget(bb)
        d.setLayout(l)
        d.setWindowModality(Qt.WindowModal)
        d.resize(500, 500)
        choice = d.exec_()
        if choice == 1:
            if ANKI_21:
                cids = w.page().runJavaScript('updatePositions()',
                                              self.callback)
            else:
                cids = w.page().mainFrame().evaluateJavaScript(
                    'updatePositions()')
                self.repositionCards(cids)
        elif currentCard:
            self.repositionCard(currentCard, -1)
Пример #3
0
    def showDialog(self, currentCard=None):
        if currentCard:
            self.did = currentCard.did
        elif mw._selectedDeck():
            self.did = mw._selectedDeck()['id']
        else:
            return

        if not self._getCardInfo(self.did):
            showInfo('Please select an Incremental Reading deck.')
            return

        dialog = QDialog(mw)
        layout = QVBoxLayout()
        self.cardListWidget = QListWidget()
        self.cardListWidget.setAlternatingRowColors(True)
        self.cardListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.cardListWidget.setWordWrap(True)
        self.cardListWidget.itemDoubleClicked.connect(lambda: showBrowser(
            self.cardListWidget.currentItem().data(Qt.UserRole)['nid']))

        self._updateListItems()

        upButton = QPushButton('Up')
        upButton.clicked.connect(self._moveUp)
        downButton = QPushButton('Down')
        downButton.clicked.connect(self._moveDown)
        topButton = QPushButton('Top')
        topButton.clicked.connect(self._moveToTop)
        bottomButton = QPushButton('Bottom')
        bottomButton.clicked.connect(self._moveToBottom)
        randomizeButton = QPushButton('Randomize')
        randomizeButton.clicked.connect(self._randomize)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(topButton)
        controlsLayout.addWidget(upButton)
        controlsLayout.addWidget(downButton)
        controlsLayout.addWidget(bottomButton)
        controlsLayout.addStretch()
        controlsLayout.addWidget(randomizeButton)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                     | QDialogButtonBox.Save)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        buttonBox.setOrientation(Qt.Horizontal)

        layout.addLayout(controlsLayout)
        layout.addWidget(self.cardListWidget)
        layout.addWidget(buttonBox)

        dialog.setLayout(layout)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.resize(500, 500)
        choice = dialog.exec_()

        if choice == 1:
            cids = []
            for i in range(self.cardListWidget.count()):
                card = self.cardListWidget.item(i).data(Qt.UserRole)
                cids.append(card['id'])

            self.reorder(cids)
Пример #4
0
 def showIRSchedulerDialog(self, currentCard):
     #Handle for dialog open without a current card from IRead2 model
     deckID = None;
     cardID = None;
     if(currentCard == None):
         deck = mw._selectedDeck();
         deckID = deck['id'];
     else:
         deckID = currentCard.did;
         cardID = currentCard.id;
     
     #Get the card data for the deck. Make sure it is an Incremental Reading deck (has IRead2 cards) before showing dialog
     cardDataList = self.getCardDataList(deckID, cardID);
     hasIRead2Cards = False;
     for cd in cardDataList:
         if(cd['title'] != 'No Title'): hasIRead2Cards = True;
     if(hasIRead2Cards == False):
         showInfo(_("Please select an Incremental Reading deck."))
         return;
     
     d = QDialog(self.mw)
     l = QVBoxLayout()
     l.setMargin(0)
     w = AnkiWebView()
     l.addWidget(w)
     #Add python object to take values back from javascript
     callback = IRSchedulerCallback();
     #callback.setCard(currentCard);
     w.page().mainFrame().addToJavaScriptWindowObject("callback", callback);
     #Script functions move up / move down / delete / open
     getIRSchedulerDialogScript = """       
     var cardList = new Array();
     """
     index = 0;
     for cardData in cardDataList:
         index+=1;
         getIRSchedulerDialogScript += "card = new Object();";
         getIRSchedulerDialogScript += "card.id = " + str(cardData['id']) + ";";
         getIRSchedulerDialogScript += "card.title = '" + str(cardData['title']) + "';";
         getIRSchedulerDialogScript += "card.isCurrent = " + str(cardData['isCurrent']) + ";";
         getIRSchedulerDialogScript += "card.checkbox = document.createElement('input');";
         getIRSchedulerDialogScript += "card.checkbox.type = 'checkbox';";
         if(cardData['isCurrent'] == 'true'): getIRSchedulerDialogScript += "card.checkbox.setAttribute('checked', 'true');";
         getIRSchedulerDialogScript += "cardList[cardList.length] = card;";
     
     getIRSchedulerDialogScript += """
     function buildCardData() {
         var container = document.getElementById('cardList');
         container.innerHTML = '';
         var list = document.createElement('div');
         list.setAttribute('style','overflow:auto;');
         var table = document.createElement('table');
         list.appendChild(table);
         container.appendChild(list);
         var row;
         var col;
         var cardData;
         for(var i = 0; i < cardList.length; i++) {
             row = document.createElement('tr');
             row.setAttribute('id','row' + i);
             cardData = cardList[i];
             
             col = document.createElement('td');
             col.setAttribute('style','width:4em;');
             col.innerHTML = '' + i;
             row.appendChild(col);
             
             col = document.createElement('td');
             col.setAttribute('style','width:10em;');
             col.innerHTML = '' + cardData.id;
             row.appendChild(col);
             
             col = document.createElement('td');
             col.setAttribute('style','width:30em;');
             col.innerHTML = '' + cardData.title;
             row.appendChild(col);
             
             col = document.createElement('td');
             col.setAttribute('style','width:2em;');
             col.appendChild(cardData.checkbox);
             row.appendChild(col);
             
             table.appendChild(row);
         }
     }
     
     function reposition(origIndex, newIndex, isTopOfRange) {
         if(newIndex < 0 || newIndex > (cardList.length-1)) return -1;
         if(cardList[newIndex].checkbox.checked) return -1;
         
         if(isTopOfRange) {
             document.getElementById('newPos').value = newIndex;
         }
         var removedCards = cardList.splice(origIndex,1);
         cardList.splice(newIndex, 0, removedCards[0]);
         return newIndex;
     }
     
     function moveSelectedUp() {
         var topOfRange = -1;
         for(var i = 0; i < cardList.length; i++) {
             if(cardList[i].checkbox.checked) {
                 if(topOfRange == -1) topOfRange = i;
                 if(i == topOfRange) {
                     if(document.getElementById('anchor').checked) continue; //Don't move end of range if anchored.
                     else reposition(i, i - 1, true);
                 } else reposition(i, i - 1, false);
             }
         }
         buildCardData();
     }
     
     function moveSelectedDown() {
         var topOfRange = -1;
         var bottomOfRange = -1
         for(var i = 0; i < cardList.length; i++) {
             if(cardList[i].checkbox.checked) {
                 if(topOfRange == -1) topOfRange = i;
                 bottomOfRange = i;
             }
         }
         for(var i = cardList.length-1; i > -1; i--) {
             if(cardList[i].checkbox.checked) {
                 if(i == bottomOfRange && document.getElementById('anchor').checked) {
                     continue; //Don't move end of range if anchored.
                 }
                 if(i == topOfRange) reposition(i, i + 1, true);
                 else reposition(i, i + 1, false);
             }
         }
         buildCardData();
     }
     
     function selectAll() {
         for(var i = 0; i < cardList.length; i++) {
             cardList[i].checkbox.checked = true;
         }
     }
     
     function selectNone() {
         for(var i = 0; i < cardList.length; i++) {
             cardList[i].checkbox.checked = false;
         }
     }
     
     function directMove() {
         var newIndex = document.getElementById('newPos').value;
         var topOfRange = -1;
         origIndex = -1;
         for(var i = 0; i < cardList.length; i++) {
             if(cardList[i].checkbox.checked) {
                 if(topOfRange == -1) topOfRange = i;
                 if(origIndex == -1) {
                     origIndex = i;
                     sizeOfMove = (newIndex - origIndex);
                 }
             }
         }
         if(sizeOfMove < 0) {
             for(var i = 0; i < cardList.length; i++) {
                 if(cardList[i].checkbox.checked) {
                     if(i == topOfRange) reposition(i, i + sizeOfMove, true);
                     else reposition(i, i + sizeOfMove, false);
                 }
             }
         } else {
             for(var i = cardList.length-1; i > -1; i--) {
                 if(cardList[i].checkbox.checked) {
                     if(i == topOfRange) reposition(i, i + sizeOfMove, true);
                     else reposition(i, i + sizeOfMove, false);
                 }
             }
         }
         buildCardData();
     }
     
     function updatePositions() {
         var cids = new Array();
         for(var i=0; i < cardList.length; i++) {
             cids[cids.length] = parseInt(cardList[i].id);
         }
         callback.updatePositions(cids);
     };
     """;
     
     #Incremental Reading list as a list of nested <div> tags (like a table, but more flexible)
     #position,title,series id, sequence number,card id (hidden)
     newPosField = "<span style='font-weight:bold'>Card Position: </span><input type='text' id='newPos' size='5' value='0' />&nbsp;<span style='font-weight:bold'>of " + str(len(cardDataList)) + "</span>&nbsp;&nbsp;";
     newPosField += "<input type='button' value='Apply' onclick='directMove()' />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-weight:bold'>Pin Top/Bottom? </span><input type='checkbox' id='anchor'/>";
     
     upDownButtons = "<input type='button' value='Move Up' onclick='moveSelectedUp()'/><input type='button' value='Move Down' onclick='moveSelectedDown()'/>";
     upDownButtons += "<input type='button' value='Select All' onclick='selectAll()'/><input type='button' value='Select None' onclick='selectNone()'/>";
     
     html = "<html><head><script>" + getIRSchedulerDialogScript + "</script></head><body onLoad='buildCardData()'>";
     html += "<p>" + newPosField;
     html += "<p>" + upDownButtons;
     html += "<div id='cardList'></div>";
     html += "</body></html>";
     w.stdHtml(html);
     bb = QDialogButtonBox(QDialogButtonBox.Close|QDialogButtonBox.Save)
     bb.connect(bb, SIGNAL("accepted()"), d, SLOT("accept()"))
     bb.connect(bb, SIGNAL("rejected()"), d, SLOT("reject()"))
     bb.setOrientation(QtCore.Qt.Horizontal);
     l.addWidget(bb)
     d.setLayout(l)
     d.setWindowModality(Qt.WindowModal)
     d.resize(500, 500)
     choice = d.exec_();
     if(choice == 1):
         w.eval("updatePositions()");
     else:
         if(currentCard != None): self.repositionCard(currentCard, -1);