예제 #1
0
class AboutDialog(QDialog):
    def __init__(self, parent=None):
        super(AboutDialog, self).__init__(parent)
        self.setupUI()

        # Add button signal to greetings slot
        self.okButton.clicked.connect(self.hide)

        self.show()

    def setupUI(self):
        self.resize(431, 260)
        self.licenseText = QPlainTextEdit(self)
        self.licenseText.setObjectName(u"licenseText")
        self.licenseText.setEnabled(True)
        self.licenseText.setGeometry(QRect(10, 10, 411, 211))
        self.licenseText.setFrameShape(QFrame.StyledPanel)
        self.licenseText.setFrameShadow(QFrame.Sunken)
        self.licenseText.setUndoRedoEnabled(False)
        self.licenseText.setTextInteractionFlags(Qt.NoTextInteraction)
        self.okButton = QPushButton(self)
        self.okButton.setObjectName(u"okButton")
        self.okButton.setGeometry(QRect(350, 230, 75, 23))

        self.retranslateUi()

    # setupUi

    def retranslateUi(self):
        self.setWindowTitle(
            QCoreApplication.translate("about", u"About MAEsure", None))
        self.licenseText.setPlainText(
            QCoreApplication.translate(
                "about",
                u"MAEsure is a program to measure the surface energy of MAEs via contact angle\n"
                "Copyright (C) 2021  Raphael Kriegl\n"
                "\n"
                "This program is free software: you can redistribute it and/or modify\n"
                "it under the terms of the GNU General Public License as published by\n"
                "the Free Software Foundation, either version 3 of the License, or\n"
                "(at your option) any later version.\n"
                "\n"
                "This program is distributed in the hope that it will be useful,\n"
                "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
                "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
                "GNU General Public License for more details.\n"
                "\n"
                "You should have received a copy of the GNU General Public License\n"
                "along with this program.  If not, see <https://www.gnu.org/licenses/>.",
                None))
        self.licenseText.setPlaceholderText("")
        self.okButton.setText(QCoreApplication.translate("about", u"OK", None))
예제 #2
0
class Snippets(QDialog):

    def __init__(self, parent=None):
        super(Snippets, self).__init__(parent)
        # Create widgets
        self.setWindowModality(Qt.ApplicationModal)
        self.title = QLabel(self.tr("Snippet Editor"))
        self.saveButton = QPushButton(self.tr("Save"))
        self.closeButton = QPushButton(self.tr("Close"))
        self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey"))
        self.setWindowTitle(self.title.text())
        self.newFolderButton = QPushButton("New Folder")
        self.deleteSnippetButton = QPushButton("Delete")
        self.newSnippetButton = QPushButton("New Snippet")
        self.edit = QPlainTextEdit()
        self.edit.setPlaceholderText("python code")
        self.resetting = False
        self.columns = 3

        self.keySequenceEdit = QKeySequenceEdit(self)
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel = QLabel("")
        self.currentFileLabel = QLabel()
        self.currentFile = ""
        self.snippetDescription = QLineEdit()
        self.snippetDescription.setPlaceholderText("optional description")

        #Set Editbox Size
        font = getMonospaceFont(self)
        self.edit.setFont(font)
        font = QFontMetrics(font)
        self.edit.setTabStopWidth(4 * font.width(' ')); #TODO, replace with settings API

        #Files
        self.files = QFileSystemModel()
        self.files.setRootPath(snippetPath)
        self.files.setNameFilters(["*.py"])

        #Tree
        self.tree = QTreeView()
        self.tree.setModel(self.files)
        self.tree.setSortingEnabled(True)
        self.tree.hideColumn(2)
        self.tree.sortByColumn(0, Qt.AscendingOrder)
        self.tree.setRootIndex(self.files.index(snippetPath))
        for x in range(self.columns):
            #self.tree.resizeColumnToContents(x)
            self.tree.header().setSectionResizeMode(x, QHeaderView.ResizeToContents) 
        treeLayout = QVBoxLayout()
        treeLayout.addWidget(self.tree)
        treeButtons = QHBoxLayout()
        treeButtons.addWidget(self.newFolderButton)
        treeButtons.addWidget(self.newSnippetButton)
        treeButtons.addWidget(self.deleteSnippetButton)
        treeLayout.addLayout(treeButtons)
        treeWidget = QWidget()
        treeWidget.setLayout(treeLayout)

        # Create layout and add widgets
        buttons = QHBoxLayout()
        buttons.addWidget(self.clearHotkeyButton)
        buttons.addWidget(self.keySequenceEdit)
        buttons.addWidget(self.currentHotkeyLabel)
        buttons.addWidget(self.closeButton)
        buttons.addWidget(self.saveButton)

        description = QHBoxLayout()
        description.addWidget(QLabel(self.tr("Description: ")))
        description.addWidget(self.snippetDescription)

        vlayoutWidget = QWidget()
        vlayout = QVBoxLayout()
        vlayout.addLayout(description)
        vlayout.addWidget(self.edit)
        vlayout.addLayout(buttons)
        vlayoutWidget.setLayout(vlayout)

        hsplitter = QSplitter()
        hsplitter.addWidget(treeWidget)
        hsplitter.addWidget(vlayoutWidget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(hsplitter)

        self.showNormal() #Fixes bug that maximized windows are "stuck"
        self.settings = QSettings("Vector35", "Snippet Editor")
        if self.settings.contains("ui/snippeteditor/geometry"):
            self.restoreGeometry(self.settings.value("ui/snippeteditor/geometry"))
        else:
            self.edit.setMinimumWidth(80 * font.averageCharWidth())
            self.edit.setMinimumHeight(30 * font.lineSpacing())

        # Set dialog layout
        self.setLayout(hlayout)

        # Add signals
        self.saveButton.clicked.connect(self.save)
        self.closeButton.clicked.connect(self.close)
        self.clearHotkeyButton.clicked.connect(self.clearHotkey)
        self.tree.selectionModel().selectionChanged.connect(self.selectFile)
        self.newSnippetButton.clicked.connect(self.newFileDialog)
        self.deleteSnippetButton.clicked.connect(self.deleteSnippet)
        self.newFolderButton.clicked.connect(self.newFolder)

        if self.settings.contains("ui/snippeteditor/selected"):
            selectedName = self.settings.value("ui/snippeteditor/selected")
            self.tree.selectionModel().select(self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
            if self.tree.selectionModel().hasSelection():
                self.selectFile(self.tree.selectionModel().selection(), None)
                self.edit.setFocus()
                cursor = self.edit.textCursor()
                cursor.setPosition(self.edit.document().characterCount()-1)
                self.edit.setTextCursor(cursor)
            else:
                self.readOnly(True)
        else:
            self.readOnly(True)


    @staticmethod
    def registerAllSnippets():
        for action in list(filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())):
            if action == "Snippets\\Snippet Editor...":
                continue
            UIActionHandler.globalActions().unbindAction(action)
            Menu.mainMenu("Tools").removeAction(action)
            UIAction.unregisterAction(action)

        for snippet in includeWalk(snippetPath, ".py"):
            snippetKeys = None
            (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet)
            if not snippetDescription:
                actionText = "Snippets\\" + os.path.basename(snippet).rstrip(".py")
            else:
                actionText = "Snippets\\" + snippetDescription
            if snippetCode:
                if snippetKeys == None:
                    UIAction.registerAction(actionText)
                else:
                    UIAction.registerAction(actionText, snippetKeys)
                UIActionHandler.globalActions().bindAction(actionText, UIAction(makeSnippetFunction(snippetCode)))
                Menu.mainMenu("Tools").addAction(actionText, actionText)

    def clearSelection(self):
        self.keySequenceEdit.clear()
        self.currentHotkey = QKeySequence()
        self.currentHotkeyLabel.setText("")
        self.currentFileLabel.setText("")
        self.snippetDescription.setText("")
        self.edit.setPlainText("")
        self.currentFile = ""

    def reject(self):
        self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry())

        if self.snippetChanged():
            question = QMessageBox.question(self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?"))
            if question != QMessageBox.StandardButton.Yes:
                return
        self.accept()

    def newFolder(self):
        (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: "))
        if ok and folderName:
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                QDir(selection).mkdir(folderName)
            else:
                QDir(snippetPath).mkdir(folderName)    

    def selectFile(self, new, old):
        if (self.resetting):
            self.resetting = False
            return
        newSelection = self.files.filePath(new.indexes()[0])
        self.settings.setValue("ui/snippeteditor/selected", newSelection)
        if QFileInfo(newSelection).isDir():
            self.readOnly(True)
            self.tree.clearSelection()
            self.currentFile = ""
            return

        if old and old.length() > 0:
            oldSelection = self.files.filePath(old.indexes()[0])
            if not QFileInfo(oldSelection).isDir() and self.snippetChanged():
                question = QMessageBox.question(self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?"))
                if question != QMessageBox.StandardButton.Yes:
                    self.resetting = True
                    self.tree.selectionModel().select(old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
                    return False

        self.currentFile = newSelection
        self.loadSnippet()

    def loadSnippet(self):
        self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName())
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        self.snippetDescription.setText(snippetDescription) if snippetDescription else self.snippetDescription.setText("")
        self.keySequenceEdit.setKeySequence(snippetKeys) if snippetKeys else self.keySequenceEdit.setKeySequence(QKeySequence(""))
        self.edit.setPlainText(snippetCode) if snippetCode else self.edit.setPlainText("")
        self.readOnly(False)

    def newFileDialog(self):
        (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: "))
        if ok and snippetName:
            if not snippetName.endswith(".py"):
                snippetName += ".py"
            index = self.tree.selectionModel().currentIndex()
            selection = self.files.filePath(index)
            if QFileInfo(selection).isDir():
                path = os.path.join(selection, snippetName)
            else:
                path = os.path.join(snippetPath, snippetName)
                self.readOnly(False)
            open(path, "w").close()
            self.tree.setCurrentIndex(self.files.index(path))
            log_debug("Snippet %s created." % snippetName)

    def readOnly(self, flag):
        self.keySequenceEdit.setEnabled(not flag)
        self.snippetDescription.setReadOnly(flag)
        self.edit.setReadOnly(flag)
        if flag:
            self.snippetDescription.setDisabled(True)
            self.edit.setDisabled(True)
        else:
            self.snippetDescription.setEnabled(True)
            self.edit.setEnabled(True)

    def deleteSnippet(self):
        selection = self.tree.selectedIndexes()[::self.columns][0] #treeview returns each selected element in the row
        snippetName = self.files.fileName(selection)
        question = QMessageBox.question(self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName)
        if (question == QMessageBox.StandardButton.Yes):
            log_debug("Deleting snippet %s." % snippetName)
            self.clearSelection()
            self.files.remove(selection)
            self.registerAllSnippets()

    def snippetChanged(self):
        if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()):
            return False
        (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile)
        if snippetKeys == None and not self.keySequenceEdit.keySequence().isEmpty():
            return True
        if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence().toString():
            return True
        return self.edit.toPlainText() != snippetCode or \
               self.snippetDescription.text() != snippetDescription

    def save(self):
        log_debug("Saving snippet %s" % self.currentFile)
        outputSnippet = open(self.currentFile, "w")
        outputSnippet.write("#" + self.snippetDescription.text() + "\n")
        outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n")
        outputSnippet.write(self.edit.toPlainText())
        outputSnippet.close()
        self.registerAllSnippets()

    def clearHotkey(self):
        self.keySequenceEdit.clear()
예제 #3
0
파일: editor.py 프로젝트: nitrotm/3dtagger
class Editor(QWidget):
    changed = Signal()

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

        self.path = Path(__file__).parent / 'shaders'
        self.project = None
        self.programName = None
        self.vertexShader = ''
        self.fragmentShader = ''

        self.colorEditor = QLineEdit()
        self.colorEditor.setEnabled(False)
        self.colorEditor.textChanged.connect(self.updateColorHex)
        self.updateColor((0.5, 0.5, 0.5, 1.0))

        self.pickButton = QPushButton('Pick')
        self.pickButton.setEnabled(False)
        self.pickButton.clicked.connect(self.pickColor)

        colorContainer = QWidget()
        colorContainer.setLayout(QHBoxLayout())
        colorContainer.layout().setMargin(0)
        colorContainer.layout().addWidget(self.colorEditor)
        colorContainer.layout().addWidget(self.pickButton)

        self.displayRatioSlider = QSlider(Qt.Horizontal)
        self.displayRatioSlider.setRange(0, 1000)
        self.displayRatioSlider.setEnabled(False)
        self.displayRatioSlider.setSingleStep(1)
        self.displayRatioSlider.setPageStep(10)
        self.displayRatioSlider.valueChanged.connect(self.updateDisplayRatio)

        self.pointSizeSlider = QSlider(Qt.Horizontal)
        self.pointSizeSlider.setRange(0, 500)
        self.pointSizeSlider.setEnabled(False)
        self.pointSizeSlider.setSingleStep(1)
        self.pointSizeSlider.setPageStep(10)
        self.pointSizeSlider.valueChanged.connect(self.updatePointSize)

        self.distanceSlider = QSlider(Qt.Horizontal)
        self.distanceSlider.setRange(0, 1000)
        self.distanceSlider.setEnabled(False)
        self.distanceSlider.setSingleStep(1)
        self.distanceSlider.setPageStep(10)
        self.distanceSlider.valueChanged.connect(self.updateDistanceRange)

        self.vertexEditor = QPlainTextEdit()
        self.vertexEditor.setStyleSheet(
            "QPlainTextEdit { background: #393939; color: #b6dede; font: 1rem 'monospace'; }"
        )
        self.vertexEditor.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.vertexEditor.setWordWrapMode(QTextOption.NoWrap)
        self.vertexEditor.setTabStopWidth(2)
        self.vertexEditor.setTabChangesFocus(False)
        self.vertexEditor.setCenterOnScroll(True)
        self.vertexEditor.setEnabled(False)
        self.vertexEditor.textChanged.connect(self.saveVertex)

        self.fragmentEditor = QPlainTextEdit()
        self.fragmentEditor.setStyleSheet(
            "QPlainTextEdit { background: #393939; color: #b6dede; font: 1rem 'monospace'; }"
        )
        self.fragmentEditor.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.fragmentEditor.setWordWrapMode(QTextOption.NoWrap)
        self.fragmentEditor.setTabStopWidth(2)
        self.fragmentEditor.setTabChangesFocus(False)
        self.fragmentEditor.setCenterOnScroll(True)
        self.fragmentEditor.setEnabled(False)
        self.fragmentEditor.textChanged.connect(self.saveFragment)

        self.setLayout(QVBoxLayout())
        self.layout().addWidget(QLabel("Display (%):"))
        self.layout().addWidget(self.displayRatioSlider)
        self.layout().addWidget(QLabel("Mask Point size (px):"))
        self.layout().addWidget(self.pointSizeSlider)
        self.layout().addWidget(QLabel("Mask Distance range:"))
        self.layout().addWidget(self.distanceSlider)
        self.layout().addWidget(QLabel("Clear color:"))
        self.layout().addWidget(colorContainer)
        self.layout().addWidget(QLabel("Vertex shader:"))
        self.layout().addWidget(self.vertexEditor)
        self.layout().addWidget(QLabel("Fragment shader:"))
        self.layout().addWidget(self.fragmentEditor)

    def setProject(self, project):
        self.project = project
        if project:
            self.displayRatioSlider.setValue(project.displayRatio * 1000)
            self.displayRatioSlider.setEnabled(True)
            self.pointSizeSlider.setValue(project.maskPointSize * 10)
            self.pointSizeSlider.setEnabled(True)
            self.distanceSlider.setValue(project.maskDistanceRange[1] * 10)
            self.distanceSlider.setEnabled(True)
            self.updateColor(project.clearColor)
            self.loadShader(project.cloudShaderName)
            self.colorEditor.setEnabled(True)
            self.pickButton.setEnabled(True)
            self.vertexEditor.setEnabled(True)
            self.fragmentEditor.setEnabled(True)
        else:
            self.displayRatioSlider.setValue(1000)
            self.displayRatioSlider.setEnabled(False)
            self.pointSizeSlider.setValue(10)
            self.pointSizeSlider.setEnabled(False)
            self.distanceSlider.setValue(10)
            self.distanceSlider.setEnabled(False)
            self.updateColor((0.5, 0.5, 0.5, 1.0))
            self.clearShader()
            self.colorEditor.setEnabled(False)
            self.pickButton.setEnabled(False)
            self.vertexEditor.setEnabled(False)
            self.fragmentEditor.setEnabled(False)

    def parseColorHex(self, value):
        m = re.compile('#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})'
                       ).match(value)
        if not m:
            return None
        return (min(max(int(m.group(1), base=16), 0), 255) / 255.0,
                min(max(int(m.group(2), base=16), 0), 255) / 255.0,
                min(max(int(m.group(3), base=16), 0), 255) / 255.0,
                min(max(int(m.group(4), base=16), 0), 255) / 255.0)

    def pickColor(self):
        color = QColor()
        color.setRgbF(*self.parseColorHex(self.colorEditor.text()))
        color = QColorDialog.getColor(color,
                                      parent=self,
                                      title="Background Color",
                                      options=QColorDialog.ShowAlphaChannel)
        if not color.isValid():
            return
        self.updateColor(
            (color.redF(), color.greenF(), color.blueF(), color.alphaF()))

    def updateColorHex(self, value):
        self.updateColor(self.parseColorHex(value))

    def updateColor(self, color):
        def formatChannel(value):
            return "%02x" % int(min(max(value * 255.0, 0.0), 255.0))

        bg = "#%s%s%s" % (formatChannel(color[0]), formatChannel(
            color[1]), formatChannel(color[2]))
        fg = "#ffffff" if sum(color) / 3 < 0.5 else "#000000"
        self.colorEditor.setStyleSheet(
            "QLineEdit { color: %s; background: %s; }" % (fg, bg))
        text = bg + formatChannel(color[3])
        if self.colorEditor.text() != text:
            self.colorEditor.setText(text)
        if self.project:
            self.project.setClearColor(color)
        # self.changed.emit()

    def updateDisplayRatio(self, value):
        if self.project:
            self.project.setDisplayRatio(value / 1000.0)
        # self.changed.emit()

    def updatePointSize(self, value):
        if self.project:
            self.project.setMaskPointSize(value / 10.0)
        # self.changed.emit()

    def updateDistanceRange(self, value):
        if self.project:
            self.project.setMaskDistanceRange(value / 10.0)
        # self.changed.emit()

    def clearShader(self):
        self.programName = None
        self.vertexShader = ''
        self.fragmentShader = ''
        self.vertexEditor.setPlainText('')
        self.fragmentEditor.setPlainText('')

    def loadShader(self, name):
        self.programName = name
        self.vertexShader = ''
        self.fragmentShader = ''
        try:
            with io.open(self.path / (self.programName + '.vs'), 'r') as f:
                self.vertexShader = f.read()
        except Exception as e:
            print(e)
        try:
            with io.open(self.path / (self.programName + '.fs'), 'r') as f:
                self.fragmentShader = f.read()
        except Exception as e:
            print(e)
        self.vertexEditor.setPlainText(self.vertexShader)
        self.fragmentEditor.setPlainText(self.fragmentShader)

    def saveVertex(self):
        value = self.vertexEditor.toPlainText()
        if not self.programName or self.vertexShader == value:
            return
        with io.open(self.path / (self.programName + '.vs'), 'w') as f:
            f.write(value)
        self.vertexShader = value
        self.changed.emit()

    def saveFragment(self):
        value = self.fragmentEditor.toPlainText()
        if not self.programName or self.fragmentShader == value:
            return
        with io.open(self.path / (self.programName + '.fs'), 'w') as f:
            f.write(value)
        self.fragmentShader = value
        self.changed.emit()
예제 #4
0
class BibTeXWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self._source = None
        self._table = None
        self._id = -1
        self._inspire_id = None
        self._doi = None
        self._bibtex_string = ""

        self._fetcher = Fetcher()
        self._fetcher.BatchReady.connect(self._HandleBatchReady)
        self._fetcher.FetchingFinished.connect(self._HandleFetchingCompleted)

        self._text_edit = QPlainTextEdit()
        font = QFont("Monospace")
        self._text_edit.setFont(font)
        self._text_edit.setTextInteractionFlags(
            Qt.TextInteractionFlag.TextSelectableByKeyboard
            | Qt.TextInteractionFlag.TextSelectableByMouse)
        self._text_edit.setEnabled(False)

        self._dowload_inspire = QToolButton()
        self._dowload_inspire.setIcon(QIcon(icons.INSPIRE))
        self._dowload_inspire.clicked.connect(self._FetchINSPIRE)
        self._dowload_inspire.setEnabled(False)

        self._dowload_doi = QToolButton()
        self._dowload_doi.setIcon(QIcon(icons.DOI))
        self._dowload_doi.clicked.connect(self._FetchDOI)
        self._dowload_doi.setEnabled(False)

        self._SetupUI()

    def _SetupUI(self):
        tool_widget = QWidget()
        tool_layout = QHBoxLayout()
        tool_layout.setContentsMargins(0, 0, 0, 0)
        tool_layout.addWidget(self._dowload_inspire)
        tool_layout.addWidget(self._dowload_doi)
        tool_layout.addStretch(1)
        tool_widget.setLayout(tool_layout)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._text_edit)
        layout.addWidget(tool_widget)
        self.setLayout(layout)

    def SetTable(self, database_table):
        if self._table == database_table:
            return

        if self._table is not None:
            self._table.Cleared.disconnect(self.Clear)

        self._table = database_table
        self._table.Cleared.connect(self.Clear)

    def Clear(self):
        self._text_edit.clear()
        self._text_edit.setEnabled(False)
        self._dowload_inspire.setEnabled(False)
        self._dowload_doi.setEnabled(False)

    def DisplayItem(self, id_):
        # NOTE: What if the item gets updated?

        if self._id == id_:
            return

        self._id = id_
        self._fetcher.Stop()
        self.Clear()

        if self._id == -1:
            return

        record = self._table.GetRow(self._id, ("inspire_id", "dois"))
        self._inspire_id = record["inspire_id"]
        self._doi = None if record["dois"] == [] else record["dois"][0]
        has_inspire_id = self._inspire_id is not None
        has_doi = self._doi is not None

        self._text_edit.setEnabled(has_inspire_id | has_doi)
        self._dowload_inspire.setEnabled(has_inspire_id)
        self._dowload_doi.setEnabled(has_doi)

    def _FetchINSPIRE(self):
        self._fetcher.Fetch(InspireBibTeXPlugin,
                            "recid:" + str(self._inspire_id),
                            batch_size=2)

    def _FetchDOI(self):
        self._fetcher.Fetch(DOIBibTeXPlugin, self._doi)

    def _HandleBatchReady(self, batch):
        self._bibtex_string = batch[0]

    def _HandleFetchingCompleted(self, records_number):
        self._text_edit.setPlainText(self._bibtex_string)