Example #1
0
        def listItems(item, rect, level=0):
            delta = 0
            for child in item.children():
                w = itemWidth(child)

                if child.isFolder():
                    parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title())
                    parent.setToolTip(references.tooltip(references.textReference(child.ID())))
                    listItems(child, parent, level + 1)

                else:
                    rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title())
                    rectChild.setToolTip(references.tooltip(references.textReference(child.ID())))
                    
                    # Find tracked references in that scene (or parent folders)
                    for ID, ref, name in trackedItems:

                        result = []
                        c = child
                        while c:
                            result += references.findReferencesTo(ref, c, recursive=False)
                            c = c.parent()

                        if result:
                            ref2 = result[0]
                            
                            # Create a RefCircle with the reference
                            c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2)
                            
                            # Store it, with the position of that item, to display it on the line later on
                            refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos())))

                delta += w
Example #2
0
 def __init__(self, x, y, diameter, parent=None, ID=None):
     QGraphicsEllipseItem.__init__(self, x, y, diameter, diameter, parent)
     self.setBrush(Qt.white)
     self._ref = references.textReference(ID)
     self.setToolTip(references.tooltip(self._ref))
     self.setPen(QPen(Qt.black, 2))
     self.setAcceptHoverEvents(True)
Example #3
0
        def listItems(item, rect, level=0):
            delta = 0
            for child in item.children():
                w = itemWidth(child)

                if child.isFolder():
                    parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title())
                    parent.setToolTip(references.tooltip(references.textReference(child.ID())))
                    listItems(child, parent, level + 1)

                else:
                    rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title())
                    rectChild.setToolTip(references.tooltip(references.textReference(child.ID())))
                    
                    # Find tracked references in that scene (or parent folders)
                    for ref in trackedItems:

                        result = []

                        # Tests if POV
                        scenePOV = False  # Will hold true of character is POV of the current text, not containing folder
                        if references.type(ref) == references.CharacterLetter:
                            ID = references.ID(ref)
                            c = child
                            while c:
                                if c.POV() == ID:
                                    result.append(c.ID())
                                    if c == child: scenePOV = True
                                c = c.parent()

                        # Search in notes/references
                        c = child
                        while c:
                            result += references.findReferencesTo(ref, c, recursive=False)
                            c = c.parent()

                        if result:
                            ref2 = result[0]
                            
                            # Create a RefCircle with the reference
                            c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2, important=scenePOV)
                            
                            # Store it, with the position of that item, to display it on the line later on
                            refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos())))

                delta += w
Example #4
0
        def listItems(item, rect, level=0):
            delta = 0
            for child in item.children():
                w = itemWidth(child)

                if child.isFolder():
                    parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title())
                    parent.setToolTip(references.tooltip(references.textReference(child.ID())))
                    listItems(child, parent, level + 1)

                else:
                    rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title())
                    rectChild.setToolTip(references.tooltip(references.textReference(child.ID())))
                    
                    # Find tracked references in that scene (or parent folders)
                    for ref in trackedItems:

                        result = []

                        # Tests if POV
                        scenePOV = False  # Will hold true of character is POV of the current text, not containing folder
                        if references.type(ref) == references.CharacterLetter:
                            ID = references.ID(ref)
                            c = child
                            while c:
                                if c.POV() == ID:
                                    result.append(c.ID())
                                    if c == child: scenePOV = True
                                c = c.parent()

                        # Search in notes/references
                        c = child
                        while c:
                            result += references.findReferencesTo(ref, c, recursive=False)
                            c = c.parent()

                        if result:
                            ref2 = result[0]
                            
                            # Create a RefCircle with the reference
                            c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2, important=scenePOV)
                            
                            # Store it, with the position of that item, to display it on the line later on
                            refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos())))

                delta += w
Example #5
0
 def __init__(self, x, y, diameter, parent=None, ID=None, important=False):
     QGraphicsEllipseItem.__init__(self, x, y, diameter, diameter, parent)
     self.setBrush(Qt.white)
     self._ref = references.textReference(ID)
     self.setToolTip(references.tooltip(self._ref))
     self.setPen(QPen(Qt.black, 2))
     self.setAcceptHoverEvents(True)
     if important:
         self.setBrush(Qt.black)
    def mouseMoveEvent(self, event):
        textEditView.mouseMoveEvent(self, event)

        onRef = [r for r in self.refRects if r.contains(event.pos())]

        if not onRef:
            qApp.restoreOverrideCursor()
            QToolTip.hideText()
            return

        cursor = self.cursorForPosition(event.pos())
        ref = self.refUnderCursor(cursor)
        if ref:
            if not qApp.overrideCursor():
                qApp.setOverrideCursor(Qt.PointingHandCursor)
            QToolTip.showText(self.mapToGlobal(event.pos()), Ref.tooltip(ref))
Example #7
0
    def mouseMoveEvent(self, event):
        MDEditView.mouseMoveEvent(self, event)

        onRef = [r for r in self.refRects if r.contains(event.pos())]

        if not onRef:
            qApp.restoreOverrideCursor()
            QToolTip.hideText()
            return

        cursor = self.cursorForPosition(event.pos())
        ref = self.refUnderCursor(cursor)
        if ref:
            if not qApp.overrideCursor():
                qApp.setOverrideCursor(Qt.PointingHandCursor)
            QToolTip.showText(self.mapToGlobal(event.pos()), Ref.tooltip(ref))
Example #8
0
    def mouseMoveEvent(self, event):
        """
        When mouse moves, we show tooltip when appropriate.
        """
        self.beginTooltipMoveEvent()
        MDEditView.mouseMoveEvent(self, event)
        self.endTooltipMoveEvent()

        onRef = [r for r in self.refRects if r.contains(event.pos())]

        if not onRef:
            qApp.restoreOverrideCursor()
            self.hideTooltip()
            return

        cursor = self.cursorForPosition(event.pos())
        ref = self.refUnderCursor(cursor)
        if ref:
            if not qApp.overrideCursor():
                qApp.setOverrideCursor(Qt.PointingHandCursor)

            self.showTooltip(self.mapToGlobal(event.pos()), Ref.tooltip(ref))
 def linkHovered(self, link):
     if link:
         QToolTip.showText(QCursor.pos(), Ref.tooltip(link))
Example #10
0
def test_references(MWSampleProject):
    """
    Tests references using sample project.
    """
    from manuskript.models import references as Ref
    MW = MWSampleProject

    # References
    ref1 = Ref.plotReference("42", searchable=True)
    ref2 = Ref.plotReference("42")
    assert ref1 in ref2

    ref1 = Ref.characterReference("42", searchable=True)
    ref2 = Ref.characterReference("42")
    assert ref1 in ref2

    ref1 = Ref.textReference("42", searchable=True)
    ref2 = Ref.textReference("42")
    assert ref1 in ref2

    ref1 = Ref.worldReference("42", searchable=True)
    ref2 = Ref.worldReference("42")
    assert ref1 in ref2

    # Plots
    mdlPlots = MW.mdlPlots
    plotsImp = mdlPlots.getPlotsByImportance()
    plots = []
    [plots.extend(i) for i in plotsImp]
    assert len(plots) == 3
    plotID = plots[0]
    assert "\n" in Ref.infos(Ref.plotReference(plotID))
    assert "Not a ref" in Ref.infos("<invalid>")
    assert "Unknown" in Ref.infos(Ref.plotReference("999"))
    assert Ref.shortInfos(Ref.plotReference(plotID)) is not None
    assert Ref.shortInfos(Ref.plotReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # Character
    mdlChar = MW.mdlCharacter
    IDs = [mdlChar.ID(r) for r in range(mdlChar.rowCount())]
    assert len(IDs) == 6  # Peter, Paul, Philip, Stephen, Barnabas, Herod
    charID = IDs[0]
    assert "\n" in Ref.infos(Ref.characterReference(charID))
    assert "Unknown" in Ref.infos(Ref.characterReference("999"))
    assert Ref.shortInfos(Ref.characterReference(charID)) is not None
    assert Ref.shortInfos(Ref.characterReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # Texts
    mdlOutline = MW.mdlOutline
    assert mdlOutline.rowCount() == 3  # Jerusalem, Samaria, Extremities
    root = mdlOutline.rootItem
    textID = root.child(0).ID()

    assert "\n" in Ref.infos(Ref.textReference(textID))
    assert "Unknown" in Ref.infos(Ref.textReference("999"))
    assert Ref.shortInfos(Ref.textReference(textID)) is not None
    assert Ref.shortInfos(Ref.textReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # World
    mdlWorld = MW.mdlWorld
    assert mdlWorld.rowCount() == 3  # Places, Culture, Travel
    worldID = mdlWorld.itemID(mdlWorld.item(2).child(1))

    assert "\n" in Ref.infos(Ref.worldReference(worldID))
    assert "Unknown" in Ref.infos(Ref.worldReference("999"))
    assert Ref.shortInfos(Ref.worldReference(worldID)) is not None
    assert Ref.shortInfos(Ref.worldReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    refs = [
        Ref.plotReference(plotID),
        Ref.characterReference(charID),
        Ref.textReference(textID),
        Ref.worldReference(worldID),
    ]

    # Titles
    for ref in refs:
        assert Ref.title(ref) is not None
    assert Ref.title("<invalid>") is None
    assert Ref.title(Ref.plotReference("999")) is None

    # Other stuff
    assert Ref.type(Ref.plotReference(plotID)) == Ref.PlotLetter
    assert Ref.ID(Ref.textReference(textID)) == textID
    assert "Unknown" in Ref.tooltip(Ref.worldReference("999"))
    assert "Not a ref" in Ref.tooltip("<invalid>")
    for ref in refs:
        assert Ref.tooltip(ref) is not None

    # Links
    assert Ref.refToLink("<invalid>") is None
    assert Ref.refToLink(Ref.plotReference("999")) == Ref.plotReference("999")
    assert Ref.refToLink(
        Ref.characterReference("999")) == Ref.characterReference("999")
    assert Ref.refToLink(Ref.textReference("999")) == Ref.textReference("999")
    assert Ref.refToLink(
        Ref.worldReference("999")) == Ref.worldReference("999")
    for ref in refs:
        assert "<a href" in Ref.refToLink(ref)

    # Open
    assert Ref.open("<invalid>") is None
    assert Ref.open(Ref.plotReference("999")) == False
    assert Ref.open(Ref.characterReference("999")) == False
    assert Ref.open(Ref.textReference("999")) == False
    assert Ref.open(Ref.worldReference("999")) == False
    for ref in refs:
        assert Ref.open(ref) == True
    assert Ref.open(Ref.EmptyRef.format("Z", 14, "")) == False
Example #11
0
 def linkHovered(self, link):
     if link:
         QToolTip.showText(QCursor.pos(), Ref.tooltip(link))
Example #12
0
    def refresh(self):
        if not self._mdlPlots or not self._mdlOutline or not self._mdlCharacter:
            return

        if not self.isVisible():
            return

        LINE_HEIGHT = 18
        SPACING = 3
        TEXT_WIDTH = self.sldTxtSize.value()
        CIRCLE_WIDTH = 10
        LEVEL_HEIGHT = 12

        s = self.scene
        s.clear()

        # Get Max Level (max depth)
        root = self._mdlOutline.rootItem

        def maxLevel(item, level=0, max=0):
            if level > max:
                max = level
            for c in item.children():
                m = maxLevel(c, level + 1)
                if m > max:
                    max = m
            return max

        MAX_LEVEL = maxLevel(root)

        # Get the list of tracked items (array of references)
        trackedItems = []

        if self.actPlots.isChecked():
            trackedItems += self.plotReferences()

        if self.actCharacters.isChecked():
            trackedItems += self.charactersReferences()

        ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING)

        fm = QFontMetrics(s.font())
        max_name = 0
        for ref in trackedItems:
            name = references.title(ref)
            max_name = max(fm.width(name), max_name)

        TITLE_WIDTH = max_name + 2 * SPACING

        # Add Folders and Texts
        outline = OutlineRect(0, 0, 0,
                              ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT)
        s.addItem(outline)
        outline.setPos(TITLE_WIDTH + SPACING, 0)

        refCircles = [
        ]  # a list of all references, to be added later on the lines

        # A Function to add a rect with centered elided text
        def addRectText(x, w, parent, text="", level=0, tooltip=""):
            deltaH = LEVEL_HEIGHT if level else 0
            r = OutlineRect(0,
                            0,
                            w,
                            parent.rect().height() - deltaH,
                            parent,
                            title=text)
            r.setPos(x, deltaH)

            txt = QGraphicsSimpleTextItem(text, r)
            f = txt.font()
            f.setPointSize(8)
            fm = QFontMetricsF(f)
            elidedText = fm.elidedText(text, Qt.ElideMiddle, w)
            txt.setFont(f)
            txt.setText(elidedText)
            txt.setPos(r.boundingRect().center() - txt.boundingRect().center())
            txt.setY(0)
            return r

        # A function to returns an item's width, by counting its children
        def itemWidth(item):
            if item.isFolder():
                r = 0
                for c in item.children():
                    r += itemWidth(c)
                return r or TEXT_WIDTH
            else:
                return TEXT_WIDTH

        def listItems(item, rect, level=0):
            delta = 0
            for child in item.children():
                w = itemWidth(child)

                if child.isFolder():
                    parent = addRectText(delta,
                                         w,
                                         rect,
                                         child.title(),
                                         level,
                                         tooltip=child.title())
                    parent.setToolTip(
                        references.tooltip(references.textReference(
                            child.ID())))
                    listItems(child, parent, level + 1)

                else:
                    rectChild = addRectText(delta,
                                            TEXT_WIDTH,
                                            rect,
                                            "",
                                            level,
                                            tooltip=child.title())
                    rectChild.setToolTip(
                        references.tooltip(references.textReference(
                            child.ID())))

                    # Find tracked references in that scene (or parent folders)
                    for ref in trackedItems:

                        result = []

                        # Tests if POV
                        scenePOV = False  # Will hold true of character is POV of the current text, not containing folder
                        if references.type(ref) == references.CharacterLetter:
                            ID = references.ID(ref)
                            c = child
                            while c:
                                if c.POV() == ID:
                                    result.append(c.ID())
                                    if c == child: scenePOV = True
                                c = c.parent()

                        # Search in notes/references
                        c = child
                        while c:
                            result += references.findReferencesTo(
                                ref, c, recursive=False)
                            c = c.parent()

                        if result:
                            ref2 = result[0]

                            # Create a RefCircle with the reference
                            c = RefCircle(TEXT_WIDTH / 2,
                                          -CIRCLE_WIDTH / 2,
                                          CIRCLE_WIDTH,
                                          ID=ref2,
                                          important=scenePOV)

                            # Store it, with the position of that item, to display it on the line later on
                            refCircles.append(
                                (ref, c,
                                 rect.mapToItem(outline, rectChild.pos())))

                delta += w

        listItems(root, outline)

        OUTLINE_WIDTH = itemWidth(root)

        # Add Tracked items
        i = 0
        itemsRect = s.addRect(0, 0, 0, 0)
        itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING)

        # Set of colors for plots (as long as they don't have their own colors)
        colors = [
            "#D97777",
            "#AE5F8C",
            "#D9A377",
            "#FFC2C2",
            "#FFDEC2",
            "#D2A0BC",
            "#7B0F0F",
            "#7B400F",
            "#620C3D",
            "#AA3939",
            "#AA6C39",
            "#882D61",
            "#4C0000",
            "#4C2200",
            "#3D0022",
        ]

        for ref in trackedItems:
            if references.type(ref) == references.CharacterLetter:
                color = self._mdlCharacter.getCharacterByID(
                    references.ID(ref)).color()
            else:
                color = QColor(colors[i % len(colors)])

            # Rect
            r = QGraphicsRectItem(0, 0, TITLE_WIDTH, LINE_HEIGHT, itemsRect)
            r.setPen(QPen(Qt.NoPen))
            r.setBrush(QBrush(color))
            r.setPos(0, i * LINE_HEIGHT + i * SPACING)
            r.setToolTip(references.tooltip(ref))
            i += 1

            # Text
            name = references.title(ref)
            txt = QGraphicsSimpleTextItem(name, r)
            txt.setPos(r.boundingRect().center() - txt.boundingRect().center())

            # Line
            line = PlotLine(0, 0, OUTLINE_WIDTH + SPACING, 0)
            line.setPos(TITLE_WIDTH, r.mapToScene(r.rect().center()).y())
            s.addItem(line)
            line.setPen(QPen(color, 5))
            line.setToolTip(references.tooltip(ref))

            # We add the circles / references to text, on the line
            for ref2, circle, pos in refCircles:
                if ref2 == ref:
                    circle.setParentItem(line)
                    circle.setPos(pos.x(), 0)

        # self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio
        self.view.setSceneRect(0, 0, 0, 0)
Example #13
0
    def refresh(self):
        if not self._mdlPlots or not self._mdlOutline or not self._mdlCharacter:
            return

        if not self.isVisible():
            return

        LINE_HEIGHT = 18
        SPACING = 3
        TEXT_WIDTH = self.sldTxtSize.value()
        CIRCLE_WIDTH = 10
        LEVEL_HEIGHT = 12

        s = self.scene
        s.clear()

        # Get Max Level (max depth)
        root = self._mdlOutline.rootItem
        def maxLevel(item, level=0, max=0):
            if level > max:
                max = level
            for c in item.children():
                m = maxLevel(c, level + 1)
                if m > max:
                    max = m
            return max

        MAX_LEVEL = maxLevel(root)

        # Get the list of tracked items (array of references)
        trackedItems = []

        if self.actPlots.isChecked():
            trackedItems += self.plotReferences()

        if self.actCharacters.isChecked():
            trackedItems += self.charactersReferences()

        ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING )

        fm = QFontMetrics(s.font())
        max_name = 0
        for ref in trackedItems:
            name = references.title(ref)
            max_name = max(fm.width(name), max_name)

        TITLE_WIDTH = max_name + 2 * SPACING

        # Add Folders and Texts
        outline = OutlineRect(0, 0, 0, ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT)
        s.addItem(outline)
        outline.setPos(TITLE_WIDTH + SPACING, 0)

        refCircles = [] # a list of all references, to be added later on the lines

        # A Function to add a rect with centered elided text
        def addRectText(x, w, parent, text="", level=0, tooltip=""):
            deltaH = LEVEL_HEIGHT if level else 0
            r = OutlineRect(0, 0, w, parent.rect().height()-deltaH, parent, title=text)
            r.setPos(x, deltaH)

            txt = QGraphicsSimpleTextItem(text, r)
            f = txt.font()
            f.setPointSize(8)
            fm = QFontMetricsF(f)
            elidedText = fm.elidedText(text, Qt.ElideMiddle, w)
            txt.setFont(f)
            txt.setText(elidedText)
            txt.setPos(r.boundingRect().center() - txt.boundingRect().center())
            txt.setY(0)
            return r

        # A function to returns an item's width, by counting its children
        def itemWidth(item):
            if item.isFolder():
                r = 0
                for c in item.children():
                    r += itemWidth(c)
                return r or TEXT_WIDTH
            else:
                return TEXT_WIDTH

        def listItems(item, rect, level=0):
            delta = 0
            for child in item.children():
                w = itemWidth(child)

                if child.isFolder():
                    parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title())
                    parent.setToolTip(references.tooltip(references.textReference(child.ID())))
                    listItems(child, parent, level + 1)

                else:
                    rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title())
                    rectChild.setToolTip(references.tooltip(references.textReference(child.ID())))
                    
                    # Find tracked references in that scene (or parent folders)
                    for ref in trackedItems:

                        result = []

                        # Tests if POV
                        scenePOV = False  # Will hold true of character is POV of the current text, not containing folder
                        if references.type(ref) == references.CharacterLetter:
                            ID = references.ID(ref)
                            c = child
                            while c:
                                if c.POV() == ID:
                                    result.append(c.ID())
                                    if c == child: scenePOV = True
                                c = c.parent()

                        # Search in notes/references
                        c = child
                        while c:
                            result += references.findReferencesTo(ref, c, recursive=False)
                            c = c.parent()

                        if result:
                            ref2 = result[0]
                            
                            # Create a RefCircle with the reference
                            c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2, important=scenePOV)
                            
                            # Store it, with the position of that item, to display it on the line later on
                            refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos())))

                delta += w

        listItems(root, outline)

        OUTLINE_WIDTH = itemWidth(root)

        # Add Tracked items
        i = 0
        itemsRect = s.addRect(0, 0, 0, 0)
        itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING)

        # Set of colors for plots (as long as they don't have their own colors)
        colors = [
            "#D97777", "#AE5F8C", "#D9A377", "#FFC2C2", "#FFDEC2", "#D2A0BC",
            "#7B0F0F", "#7B400F", "#620C3D", "#AA3939", "#AA6C39", "#882D61",
            "#4C0000", "#4C2200", "#3D0022",
        ]

        for ref in trackedItems:
            if references.type(ref) == references.CharacterLetter:
                color = self._mdlCharacter.getCharacterByID(references.ID(ref)).color()
            else:
                color = QColor(colors[i % len(colors)])

            # Rect
            r = QGraphicsRectItem(0, 0, TITLE_WIDTH, LINE_HEIGHT, itemsRect)
            r.setPen(QPen(Qt.NoPen))
            r.setBrush(QBrush(color))
            r.setPos(0, i * LINE_HEIGHT + i * SPACING)
            r.setToolTip(references.tooltip(ref))
            i += 1

            # Text
            name = references.title(ref)
            txt = QGraphicsSimpleTextItem(name, r)
            txt.setPos(r.boundingRect().center() - txt.boundingRect().center())

            # Line
            line = PlotLine(0, 0,
                            OUTLINE_WIDTH + SPACING, 0)
            line.setPos(TITLE_WIDTH, r.mapToScene(r.rect().center()).y())
            s.addItem(line)
            line.setPen(QPen(color, 5))
            line.setToolTip(references.tooltip(ref))

            # We add the circles / references to text, on the line
            for ref2, circle, pos in refCircles:
                if ref2 == ref:
                    circle.setParentItem(line)
                    circle.setPos(pos.x(), 0)

        # self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio
        self.view.setSceneRect(0, 0, 0, 0)
Example #14
0
def test_references(MWSampleProject):
    """
    Tests references using sample project.
    """
    from manuskript.models import references as Ref
    MW = MWSampleProject

    # References
    ref1 = Ref.plotReference("42", searchable=True)
    ref2 = Ref.plotReference("42")
    assert ref1 in ref2

    ref1 = Ref.characterReference("42", searchable=True)
    ref2 = Ref.characterReference("42")
    assert ref1 in ref2

    ref1 = Ref.textReference("42", searchable=True)
    ref2 = Ref.textReference("42")
    assert ref1 in ref2

    ref1 = Ref.worldReference("42", searchable=True)
    ref2 = Ref.worldReference("42")
    assert ref1 in ref2

    # Plots
    mdlPlots = MW.mdlPlots
    plotsImp = mdlPlots.getPlotsByImportance()
    plots = []
    [plots.extend(i) for i in plotsImp]
    assert len(plots) == 3
    plotID = plots[0]
    assert "\n" in Ref.infos(Ref.plotReference(plotID))
    assert "Not a ref" in Ref.infos("<invalid>")
    assert "Unknown" in Ref.infos(Ref.plotReference("999"))
    assert Ref.shortInfos(Ref.plotReference(plotID)) is not None
    assert Ref.shortInfos(Ref.plotReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # Character
    mdlChar = MW.mdlCharacter
    IDs = [mdlChar.ID(r) for r in range(mdlChar.rowCount())]
    assert len(IDs) == 6  # Peter, Paul, Philip, Stephen, Barnabas, Herod
    charID = IDs[0]
    assert "\n" in Ref.infos(Ref.characterReference(charID))
    assert "Unknown" in Ref.infos(Ref.characterReference("999"))
    assert Ref.shortInfos(Ref.characterReference(charID)) is not None
    assert Ref.shortInfos(Ref.characterReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # Texts
    mdlOutline = MW.mdlOutline
    assert mdlOutline.rowCount() == 3  # Jerusalem, Samaria, Extremities
    root = mdlOutline.rootItem
    textID = root.child(0).ID()

    assert "\n" in Ref.infos(Ref.textReference(textID))
    assert "Unknown" in Ref.infos(Ref.textReference("999"))
    assert Ref.shortInfos(Ref.textReference(textID)) is not None
    assert Ref.shortInfos(Ref.textReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    # World
    mdlWorld = MW.mdlWorld
    assert mdlWorld.rowCount() == 3  # Places, Culture, Travel
    worldID = mdlWorld.itemID(mdlWorld.item(2).child(1))

    assert "\n" in Ref.infos(Ref.worldReference(worldID))
    assert "Unknown" in Ref.infos(Ref.worldReference("999"))
    assert Ref.shortInfos(Ref.worldReference(worldID)) is not None
    assert Ref.shortInfos(Ref.worldReference("999")) == None
    assert Ref.shortInfos("<invalidref>") == -1

    refs = [Ref.plotReference(plotID),
            Ref.characterReference(charID),
            Ref.textReference(textID),
            Ref.worldReference(worldID),]

    # Titles
    for ref in refs:
        assert Ref.title(ref) is not None
    assert Ref.title("<invalid>") is None
    assert Ref.title(Ref.plotReference("999")) is None

    # Other stuff
    assert Ref.type(Ref.plotReference(plotID)) == Ref.PlotLetter
    assert Ref.ID(Ref.textReference(textID)) == textID
    assert "Unknown" in Ref.tooltip(Ref.worldReference("999"))
    assert "Not a ref" in Ref.tooltip("<invalid>")
    for ref in refs:
        assert Ref.tooltip(ref) is not None

    # Links
    assert Ref.refToLink("<invalid>") is None
    assert Ref.refToLink(Ref.plotReference("999")) == Ref.plotReference("999")
    assert Ref.refToLink(Ref.characterReference("999")) == Ref.characterReference("999")
    assert Ref.refToLink(Ref.textReference("999")) == Ref.textReference("999")
    assert Ref.refToLink(Ref.worldReference("999")) == Ref.worldReference("999")
    for ref in refs:
        assert "<a href" in Ref.refToLink(ref)

    # Open
    assert Ref.open("<invalid>") is None
    assert Ref.open(Ref.plotReference("999")) == False
    assert Ref.open(Ref.characterReference("999")) == False
    assert Ref.open(Ref.textReference("999")) == False
    assert Ref.open(Ref.worldReference("999")) == False
    for ref in refs:
        assert Ref.open(ref) == True
    assert Ref.open(Ref.EmptyRef.format("Z", 14, "")) == False