File: outputview.py

package info (click to toggle)
treeline 3.1.5-1.1
  • links: PTS
  • area: main
  • in suites: trixie
  • size: 6,508 kB
  • sloc: python: 20,489; javascript: 998; makefile: 54
file content (153 lines) | stat: -rw-r--r-- 6,076 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python3

#******************************************************************************
# outputview.py, provides a class for the data output view
#
# TreeLine, an information storage program
# Copyright (C) 2017, Douglas W. Bell
#
# This is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License, either Version 2 or any later
# version.  This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY.  See the included LICENSE file for details.
#******************************************************************************

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QTextBrowser, QTextEdit
import treeoutput
import urltools
import dataeditors
import globalref


class OutputView(QTextBrowser):
    """Class override for the data output view.
    
    Sets view defaults and updates the content.
    """
    def __init__(self, treeView, isChildView=True, parent=None):
        """Initialize the output view.

        Arguments:
            treeView - the tree view, needed for the current selection model
            isChildView -- shows selected nodes if false, child nodes if true
            parent -- the parent main window
        """
        super().__init__(parent)
        self.treeView = treeView
        self.isChildView = isChildView
        self.hideChildView = not globalref.genOptions['InitShowChildPane']
        self.showDescendants = globalref.genOptions['InitShowDescendants']
        self.setFocusPolicy(Qt.NoFocus)

    def updateContents(self):
        """Reload the view's content if the view is shown.

        Avoids update if view is not visible or has zero height or width.
        """
        selSpots = self.treeView.selectionModel().selectedSpots()
        if self.isChildView:
            if (len(selSpots) > 1 or self.hideChildView or
                (selSpots and not selSpots[0].nodeRef.childList)):
                self.hide()
                return
            if not selSpots:
                # use top node childList from tree structure
                selSpots = [globalref.mainControl.activeControl.structure.
                            structSpot()]
        elif not selSpots:
            self.hide()
            return
        self.show()
        if not self.isVisible() or self.height() == 0 or self.width() == 0:
            return
        if self.isChildView:
            if self.showDescendants:
                outputGroup = treeoutput.OutputGroup(selSpots, False, True)
                if outputGroup.hasPrefixes():
                    outputGroup.combineAllSiblings()
                outputGroup.addBlanksBetween()
                outputGroup.addAbsoluteIndents()
            else:
                outputGroup = treeoutput.OutputGroup(selSpots[0].childSpots())
                outputGroup.addBlanksBetween()
                outputGroup.addSiblingPrefixes()
        else:
            outputGroup = treeoutput.OutputGroup(selSpots)
            outputGroup.addBlanksBetween()
            outputGroup.addSiblingPrefixes()
        self.setHtml('\n'.join(outputGroup.getLines()))
        self.setSearchPaths([str(globalref.mainControl.defaultPathObj(True))])

    def setSource(self, url):
        """Called when a user clicks on a URL link.

        Selects an internal link or opens an external browser.
        Arguments:
            url -- the QUrl that is clicked
        """
        name = url.toString()
        if name.startswith('#'):
            if not self.treeView.selectionModel().selectNodeById(name[1:]):
                super().setSource(url)
        else:
            if urltools.isRelative(name):    # check for relative path
                defaultPath = globalref.mainControl.defaultPathObj(True)
                name = urltools.toAbsolute(name, str(defaultPath))
            dataeditors.openExtUrl(name)

    def hasSelectedText(self):
        """Return True if text is selected.
        """
        return self.textCursor().hasSelection()

    def highlightSearch(self, wordList=None, regExpList=None):
        """Highlight any found search terms.

        Arguments:
            wordList -- list of words to highlight
            regExpList -- a list of regular expression objects to highlight
        """
        backColor = self.palette().brush(QPalette.Active,
                                         QPalette.Highlight)
        foreColor = self.palette().brush(QPalette.Active,
                                         QPalette.HighlightedText)
        if wordList is None:
            wordList = []
        if regExpList is None:
            regExpList = []
        for regExp in regExpList:
            for match in regExp.finditer(self.toPlainText()):
                matchText = match.group()
                if matchText not in wordList:
                    wordList.append(matchText)
        selections = []
        for word in wordList:
            while self.find(word):
                extraSel = QTextEdit.ExtraSelection()
                extraSel.cursor = self.textCursor()
                extraSel.format.setBackground(backColor)
                extraSel.format.setForeground(foreColor)
                selections.append(extraSel)
        cursor = QTextCursor(self.document())
        self.setTextCursor(cursor)  # reset main cursor/selection
        self.setExtraSelections(selections)

    def contextMenuEvent(self, event):
        """Add a popup menu for select all and copy actions.

        Arguments:
            event -- the menu event
        """
        menu = self.createStandardContextMenu()
        menu.removeAction(menu.actions()[1]) #remove copy link location
        menu.exec_(event.globalPos())

    def resizeEvent(self, event):
        """Update view if was collaped by splitter.
        """
        if ((event.oldSize().height() == 0 and event.size().height()) or
            (event.oldSize().width() == 0 and event.size().width())):
            self.updateContents()
        return super().resizeEvent(event)