mirror of
https://github.com/Hopiu/linkchecker.git
synced 2026-05-03 20:34:43 +00:00
Use TreeView and a custom model to display data.
This commit is contained in:
parent
885ce223a4
commit
7b6f0e78ca
4 changed files with 189 additions and 92 deletions
|
|
@ -28,6 +28,7 @@ from .options import LinkCheckerOptions
|
|||
from .checker import CheckerThread
|
||||
from .contextmenu import ContextMenu
|
||||
from .editor import EditorWindow
|
||||
from .urlmodel import UrlItem, UrlItemModel
|
||||
from .. import configuration, checker, director, add_intern_pattern, \
|
||||
strformat, fileutil
|
||||
from ..containers import enum
|
||||
|
|
@ -82,8 +83,7 @@ class LinkCheckerMain (QtGui.QMainWindow, Ui_MainWindow):
|
|||
self.editor = EditorWindow(parent=self)
|
||||
# Note: we can't use QT assistant here because of the .exe packaging
|
||||
self.assistant = HelpWindow(self, self.get_qhcpath())
|
||||
# setup this widget
|
||||
self.init_treewidget()
|
||||
self.init_treeview()
|
||||
self.read_settings()
|
||||
self.connect_widgets()
|
||||
self.init_config()
|
||||
|
|
@ -120,13 +120,16 @@ class LinkCheckerMain (QtGui.QMainWindow, Ui_MainWindow):
|
|||
self.connect(self.checker, QtCore.SIGNAL("terminated()"), self.set_status_idle)
|
||||
self.connect(self.checker, QtCore.SIGNAL("log_url(PyQt_PyObject)"), self.log_url)
|
||||
|
||||
def init_treewidget (self):
|
||||
self.treeWidget.setColumnHidden(0, True)
|
||||
self.treeWidget.setColumnWidth(1, 200)
|
||||
self.treeWidget.setColumnWidth(2, 200)
|
||||
self.treeWidget.setColumnWidth(3, 150)
|
||||
self.treeWidget.setSortingEnabled(True)
|
||||
self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
|
||||
def init_treeview (self):
|
||||
self.model = UrlItemModel()
|
||||
self.treeView.setModel(self.model)
|
||||
self.treeView.setColumnHidden(0, True)
|
||||
self.treeView.setColumnWidth(1, 200)
|
||||
self.treeView.setColumnWidth(2, 200)
|
||||
self.treeView.setColumnWidth(3, 150)
|
||||
#self.setForeground(4, QtGui.QBrush(url_item.color))
|
||||
self.treeView.setSortingEnabled(True)
|
||||
self.treeView.sortByColumn(0, QtCore.Qt.AscendingOrder)
|
||||
self.num = 0
|
||||
|
||||
def get_status (self):
|
||||
|
|
@ -211,7 +214,7 @@ Version 2 or later.</p>
|
|||
def check (self):
|
||||
"""Check given URL."""
|
||||
self.controlButton.setEnabled(False)
|
||||
self.treeWidget.clear()
|
||||
self.model.clear()
|
||||
self.set_config()
|
||||
aggregate = director.get_aggregate(self.config)
|
||||
url = unicode(self.urlinput.text()).strip()
|
||||
|
|
@ -263,44 +266,16 @@ Version 2 or later.</p>
|
|||
|
||||
def log_url (self, url_data):
|
||||
"""Add URL data to tree widget."""
|
||||
num = u"%09d" % self.num
|
||||
if url_data.parent_url:
|
||||
parent = unicode(url_data.parent_url) + \
|
||||
(_(", line %d") % url_data.line) + \
|
||||
(_(", col %d") % url_data.column)
|
||||
else:
|
||||
parent = u""
|
||||
url = unicode(url_data.url)
|
||||
name = url_data.name
|
||||
if url_data.valid:
|
||||
if url_data.warnings:
|
||||
color = QtCore.Qt.darkYellow
|
||||
else:
|
||||
color = QtCore.Qt.darkGreen
|
||||
result = u"Valid"
|
||||
else:
|
||||
color = QtCore.Qt.darkRed
|
||||
result = u"Error"
|
||||
if url_data.result:
|
||||
result += u": %s" % url_data.result
|
||||
item = QtGui.QTreeWidgetItem((num, parent, url, name, result))
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
item.setForeground(4, QtGui.QBrush(color))
|
||||
item.setToolTip(2, url)
|
||||
item.setToolTip(3, name)
|
||||
if url_data.warnings:
|
||||
text = u"\n".join(url_data.warnings)
|
||||
item.setToolTip(4, strformat.wrap(text, 60))
|
||||
self.treeWidget.addTopLevelItem(item)
|
||||
self.model.addUrlItem(UrlItem(url_data, self.num))
|
||||
self.num += 1
|
||||
|
||||
def on_treeWidget_itemDoubleClicked (self, item, column):
|
||||
def on_treeView_itemDoubleClicked (self, item, column):
|
||||
"""View property page."""
|
||||
pass # XXX todo
|
||||
|
||||
def on_treeWidget_customContextMenuRequested (self, point):
|
||||
def on_treeView_customContextMenuRequested (self, point):
|
||||
"""Show item context menu."""
|
||||
item = self.treeWidget.itemAt(point)
|
||||
item = self.treeView.itemAt(point)
|
||||
if item is not None:
|
||||
self.contextmenu.enableFromItem(item)
|
||||
self.contextmenu.popup(QtGui.QCursor.pos())
|
||||
|
|
@ -308,7 +283,7 @@ Version 2 or later.</p>
|
|||
@QtCore.pyqtSignature("")
|
||||
def on_actionViewOnline_triggered (self):
|
||||
"""View item URL online."""
|
||||
item = self.treeWidget.currentItem()
|
||||
item = self.treeView.currentItem()
|
||||
if item is not None:
|
||||
url = str(item.text(2))
|
||||
webbrowser.open(url)
|
||||
|
|
@ -316,7 +291,7 @@ Version 2 or later.</p>
|
|||
@QtCore.pyqtSignature("")
|
||||
def on_actionViewParentOnline_triggered (self):
|
||||
"""View item parent URL online."""
|
||||
item = self.treeWidget.currentItem()
|
||||
item = self.treeView.currentItem()
|
||||
if item is not None:
|
||||
parenturl, line, col = get_parent_url(str(item.text(1)))
|
||||
webbrowser.open(parenturl)
|
||||
|
|
@ -324,7 +299,7 @@ Version 2 or later.</p>
|
|||
@QtCore.pyqtSignature("")
|
||||
def on_actionViewParentSource_triggered (self):
|
||||
"""View item parent URL source in local text editor (read-only)."""
|
||||
item = self.treeWidget.currentItem()
|
||||
item = self.treeView.currentItem()
|
||||
if item is not None:
|
||||
# XXX simplify this once a proper model is stored
|
||||
parenturl, line, col = get_parent_url(str(item.text(1)))
|
||||
|
|
@ -348,7 +323,7 @@ Version 2 or later.</p>
|
|||
@QtCore.pyqtSignature("")
|
||||
def on_actionCopyToClipboard_triggered (self):
|
||||
"""Copy item URL to clipboard."""
|
||||
item = self.treeWidget.currentItem()
|
||||
item = self.treeView.currentItem()
|
||||
if item is not None:
|
||||
url = str(item.text(2))
|
||||
clipboard = QtGui.QApplication.clipboard()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'ui/main.ui'
|
||||
#
|
||||
# Created: Thu Oct 14 21:04:29 2010
|
||||
# Created: Sat Nov 6 07:03:42 2010
|
||||
# by: PyQt4 UI code generator 4.7.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
|
@ -50,16 +50,16 @@ class Ui_MainWindow(object):
|
|||
self.controlButton.setObjectName("controlButton")
|
||||
self.horizontalLayout_3.addWidget(self.controlButton)
|
||||
self.gridLayout.addLayout(self.horizontalLayout_3, 0, 1, 1, 1)
|
||||
self.treeWidget = QtGui.QTreeWidget(self.centralwidget)
|
||||
self.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.treeWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.treeWidget.setAlternatingRowColors(True)
|
||||
self.treeWidget.setUniformRowHeights(True)
|
||||
self.treeWidget.setItemsExpandable(False)
|
||||
self.treeWidget.setAllColumnsShowFocus(True)
|
||||
self.treeWidget.setExpandsOnDoubleClick(False)
|
||||
self.treeWidget.setObjectName("treeWidget")
|
||||
self.gridLayout.addWidget(self.treeWidget, 1, 0, 1, 2)
|
||||
self.treeView = QtGui.QTreeView(self.centralwidget)
|
||||
self.treeView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.treeView.setAlternatingRowColors(True)
|
||||
self.treeView.setUniformRowHeights(True)
|
||||
self.treeView.setItemsExpandable(False)
|
||||
self.treeView.setSortingEnabled(True)
|
||||
self.treeView.setAllColumnsShowFocus(True)
|
||||
self.treeView.setExpandsOnDoubleClick(False)
|
||||
self.treeView.setObjectName("treeView")
|
||||
self.gridLayout.addWidget(self.treeView, 1, 0, 1, 2)
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtGui.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 638, 21))
|
||||
|
|
@ -115,12 +115,6 @@ class Ui_MainWindow(object):
|
|||
self.label.setText(_("URL"))
|
||||
self.controlButton.setToolTip(_("Start checking the given URL."))
|
||||
self.controlButton.setText(_("Start"))
|
||||
self.treeWidget.setSortingEnabled(True)
|
||||
self.treeWidget.headerItem().setText(0, _("#"))
|
||||
self.treeWidget.headerItem().setText(1, _("Parent"))
|
||||
self.treeWidget.headerItem().setText(2, _("Url"))
|
||||
self.treeWidget.headerItem().setText(3, _("Name"))
|
||||
self.treeWidget.headerItem().setText(4, _("Result"))
|
||||
self.menuLinkChecka.setTitle(_("File"))
|
||||
self.menuEdit.setTitle(_("Edit"))
|
||||
self.menuHelp.setTitle(_("Help"))
|
||||
|
|
|
|||
|
|
@ -82,10 +82,7 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
|
@ -107,31 +104,6 @@
|
|||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Parent</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Url</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Result</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
156
linkcheck/gui/urlmodel.py
Normal file
156
linkcheck/gui/urlmodel.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2010 Bastian Kleineidam
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from .. import strformat
|
||||
|
||||
|
||||
Headers = [u"#", _(u"Parent"), _(u"URL"), _(u"Name"), _(u"Result")]
|
||||
EmptyHeader = QtCore.QVariant()
|
||||
|
||||
class UrlItem (object):
|
||||
"""URL item model storing info to be displayed."""
|
||||
|
||||
def __init__ (self, url_data, number):
|
||||
# store plain data
|
||||
self.id = number
|
||||
self.url = url_data.url
|
||||
self.base_url = url_data.base_url
|
||||
self.name = url_data.name
|
||||
self.parent_url = url_data.parent_url
|
||||
self.base_ref = url_data.base_ref
|
||||
self.dltime = url_data.dltime
|
||||
self.dlsize = url_data.dlsize
|
||||
self.checktime = url_data.checktime
|
||||
self.info = url_data.info[:]
|
||||
self.warnings = url_data.warnings[:]
|
||||
self.valid = url_data.value
|
||||
self.result = url_data.result
|
||||
self.line = url_data.line
|
||||
self.column = url_data.column
|
||||
# format display and tooltips
|
||||
self.init_display()
|
||||
self.init_tooltips()
|
||||
|
||||
def init_display (self):
|
||||
# Parent URL
|
||||
if self.parent_url:
|
||||
parent = unicode(self.parent_url) + \
|
||||
(_(", line %d") % self.line) + \
|
||||
(_(", col %d") % self.column)
|
||||
else:
|
||||
parent = u""
|
||||
# Result
|
||||
if self.valid:
|
||||
if self.warnings:
|
||||
self.color = QtCore.Qt.darkYellow
|
||||
else:
|
||||
self.color = QtCore.Qt.darkGreen
|
||||
result = u"Valid"
|
||||
else:
|
||||
self.color = QtCore.Qt.darkRed
|
||||
result = u"Error"
|
||||
if self.result:
|
||||
result += u": %s" % self.result
|
||||
self.display.append(result)
|
||||
self.display = [
|
||||
# ID
|
||||
u"%09d" % self.number,
|
||||
# Parent URL
|
||||
parent,
|
||||
# URL
|
||||
unicode(self.url),
|
||||
# Name
|
||||
self.name,
|
||||
# Result
|
||||
result,
|
||||
]
|
||||
|
||||
def init_tooltips (self):
|
||||
# Result
|
||||
if self.warnings:
|
||||
result = strformat.wrap(u"\n".join(self.warnings), 60)
|
||||
else:
|
||||
result = u""
|
||||
self.tooltips = [
|
||||
# ID
|
||||
u"",
|
||||
# Parent URL
|
||||
u"",
|
||||
# URL
|
||||
unicode(self.url),
|
||||
# Name
|
||||
self.name,
|
||||
# Result
|
||||
result,
|
||||
]
|
||||
|
||||
|
||||
class UrlItemModel(QtCore.QAbstractItemModel):
|
||||
|
||||
def __init__ (self, parent=None):
|
||||
super(UrlItemModel, self).__init__(parent)
|
||||
# list of UrlItem objects
|
||||
self.urls = []
|
||||
|
||||
def rowCount (self, parent=QtCore.QModelIndex()):
|
||||
return len(self.urls)
|
||||
|
||||
def columnCount (self, parent=QtCore.QModelIndex()):
|
||||
return len(Headers)
|
||||
|
||||
def parent (self, child=QtCore.QModelIndex()):
|
||||
return QtCore.QModelIndex()
|
||||
|
||||
def index (self, row, column, parent=QtCore.QModelIndex()):
|
||||
return self.createIndex(row, column)
|
||||
|
||||
def data (self, index, role=QtCore.Qt.DisplayRole):
|
||||
V = QtCore.QVariant
|
||||
if not index.isValid or \
|
||||
not (0 <= index.row() < len(self.urls)):
|
||||
return V()
|
||||
urlitem = self.data[index.row()]
|
||||
column = index.column()
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
return V(urlitem.display[column])
|
||||
elif role == QtCore.Qt.ToolTipRole:
|
||||
return V(urlitem.tooltips[column])
|
||||
elif role == QtCore.Qt.TextColorRole and column == 4:
|
||||
return V(urlitem.color)
|
||||
else:
|
||||
return V()
|
||||
|
||||
def headerData (self, section, orientation, role):
|
||||
if orientation == QtCore.Qt.Horizontal and \
|
||||
role == QtCore.Qt.DisplayRole:
|
||||
return Headers[section]
|
||||
return EmptyHeader
|
||||
|
||||
def flags (self, index):
|
||||
if not index.isValid():
|
||||
return 0
|
||||
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
|
||||
|
||||
def clear (self):
|
||||
self.beginResetModel()
|
||||
self.urls = []
|
||||
self.endResetModel()
|
||||
|
||||
def addUrlItem (self, urlitem):
|
||||
self.urls.append(urlitem)
|
||||
return self.insertRows(self.rowCount())
|
||||
Loading…
Reference in a new issue