Adds: search widget

This commit is contained in:
Olivier Keshavjee 2015-06-30 15:38:14 +02:00
parent 719f6e6fe0
commit 9404a4b92e
9 changed files with 347 additions and 35 deletions

View file

@ -59,9 +59,10 @@ class outlineModel(QAbstractItemModel):
"Returns a list of IDs of all items whose POV is ``POV``."
return self.rootItem.findItemsByPOV(POV)
def findItemsContaining(self, text, column):
"Returns a list of IDs of all items containing ``text`` in column ``column``."
return self.rootItem.findItemsContaining(text, column)
def findItemsContaining(self, text, columns, caseSensitive=False):
"""Returns a list of IDs of all items containing ``text``
in columns ``columns`` (being a list of int)."""
return self.rootItem.findItemsContaining(text, columns, mainWindow(), caseSensitive)
def getIndexByID(self, ID):
"Returns the index of item whose ID is ``ID``. If none, returns QModelIndex()."
@ -764,15 +765,34 @@ class outlineItem():
return lst
def findItemsContaining(self, text, column):
def findItemsContaining(self, text, columns, mainWindow, caseSensitive=False):
"""Returns a list if IDs of all subitems
containing ``text`` in column ``column``.
containing ``text`` in columns ``columns``
(being a list of int).
"""
lst = []
if text in self.data(column):
lst.append(self.ID())
text = text.lower() if not caseSensitive else text
for c in columns:
if c == Outline.POV.value:
searchIn = mainWindow.mdlPersos.getPersoNameByID(self.POV())
elif c == Outline.status.value:
searchIn = mainWindow.mdlStatus.item(toInt(self.status()), 0).text()
elif c == Outline.label.value:
searchIn = mainWindow.mdlLabels.item(toInt(self.label()), 0).text()
else:
searchIn = self.data(c)
searchIn = searchIn.lower() if not caseSensitive else searchIn
if text in searchIn:
if not self.ID() in lst:
lst.append(self.ID())
for c in self.children():
lst.extend(c.findItemsContaining(text, column))
lst.extend(c.findItemsContaining(text, columns, mainWindow, caseSensitive))
return lst

View file

@ -46,7 +46,7 @@ class persosModel(QStandardItemModel):
index = self.getIndexFromID(ID)
if index.isValid():
return self.name(index.row())
return None
return ""
def getIndexFromID(self, ID):
for i in range(self.rowCount()):

View file

@ -149,7 +149,7 @@ def infoForRef(ref):
# List scences where character is referenced
listRefs = ""
lst = oM.findItemsContaining(ref, Outline.notes.value)
lst = oM.findItemsContaining(ref, [Outline.notes.value])
for t in lst:
idx = oM.getIndexByID(t)
listRefs += "<li><a href='{link}'>{text}</a>".format(

View file

@ -15,7 +15,7 @@ class cheatSheet(QWidget, Ui_cheatSheet):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
self.splitter.setStretchFactor(0, 3)
self.splitter.setStretchFactor(0, 5)
self.splitter.setStretchFactor(1, 70)
self.txtFilter.textChanged.connect(self.updateListFromData)

View file

@ -844,7 +844,6 @@ class Ui_MainWindow(object):
self.groupBox_3.setFlat(True)
self.groupBox_3.setObjectName("groupBox_3")
self.verticalLayout_15 = QtWidgets.QVBoxLayout(self.groupBox_3)
self.verticalLayout_15.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_15.setObjectName("verticalLayout_15")
self.cheatSheet = cheatSheet(self.groupBox_3)
font = QtGui.QFont()
@ -854,6 +853,23 @@ class Ui_MainWindow(object):
self.cheatSheet.setObjectName("cheatSheet")
self.verticalLayout_15.addWidget(self.cheatSheet)
self.verticalLayout_21.addWidget(self.groupBox_3)
self.groupBox_4 = collapsibleGroupBox2(self.tab_18)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.groupBox_4.setFont(font)
self.groupBox_4.setFlat(True)
self.groupBox_4.setObjectName("groupBox_4")
self.verticalLayout_31 = QtWidgets.QVBoxLayout(self.groupBox_4)
self.verticalLayout_31.setObjectName("verticalLayout_31")
self.widget = search(self.groupBox_4)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.widget.setFont(font)
self.widget.setObjectName("widget")
self.verticalLayout_31.addWidget(self.widget)
self.verticalLayout_21.addWidget(self.groupBox_4)
self.tabRedacInfos.addTab(self.tab_18, "")
self.verticalLayout_16.addWidget(self.splitterRedac)
self.tabMain.addTab(self.lytTabRedac, "")
@ -1029,7 +1045,7 @@ class Ui_MainWindow(object):
self.stack.setCurrentIndex(1)
self.tabMain.setCurrentIndex(6)
self.tabSummary.setCurrentIndex(0)
self.tabPersos.setCurrentIndex(3)
self.tabPersos.setCurrentIndex(0)
self.tabPlot.setCurrentIndex(0)
self.comboBox_2.setCurrentIndex(0)
self.stkPlotSummary.setCurrentIndex(0)
@ -1113,6 +1129,7 @@ class Ui_MainWindow(object):
self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabOutline), _translate("MainWindow", "Outline"))
self.tabRedacInfos.setTabText(self.tabRedacInfos.indexOf(self.tab_17), _translate("MainWindow", "Metadata"))
self.groupBox_3.setTitle(_translate("MainWindow", "Cheat sheet"))
self.groupBox_4.setTitle(_translate("MainWindow", "Search"))
self.tabRedacInfos.setTabText(self.tabRedacInfos.indexOf(self.tab_18), _translate("MainWindow", "Tools"))
self.tabMain.setTabText(self.tabMain.indexOf(self.lytTabRedac), _translate("MainWindow", "Redaction"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_9), _translate("MainWindow", "FlatData"))
@ -1152,16 +1169,17 @@ class Ui_MainWindow(object):
self.actSettings.setShortcut(_translate("MainWindow", "F8"))
self.actCloseProject.setText(_translate("MainWindow", "Close project"))
from ui.views.treeView import treeView
from ui.editors.mainEditor import mainEditor
from ui.views.persoTreeView import persoTreeView
from ui.sldImportance import sldImportance
from ui.cheatSheet import cheatSheet
from ui.views.basicItemView import basicItemView
from ui.views.metadataView import metadataView
from ui.search import search
from ui.views.outlineView import outlineView
from ui.collapsibleGroupBox2 import collapsibleGroupBox2
from ui.views.metadataView import metadataView
from ui.views.lineEditView import lineEditView
from ui.views.persoTreeView import persoTreeView
from ui.sldImportance import sldImportance
from ui.views.basicItemView import basicItemView
from ui.views.treeView import treeView
from ui.cheatSheet import cheatSheet
from ui.views.plotTreeView import plotTreeView
from ui.views.textEditView import textEditView
from ui.welcome import welcome
from ui.views.textEditView import textEditView
from ui.views.lineEditView import lineEditView

View file

@ -717,7 +717,7 @@
</widget>
<widget class="QTabWidget" name="tabPersos">
<property name="currentIndex">
<number>3</number>
<number>0</number>
</property>
<widget class="QWidget" name="infos">
<attribute name="title">
@ -1628,9 +1628,6 @@
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="cheatSheet" name="cheatSheet" native="true">
<property name="font">
@ -1644,6 +1641,34 @@
</layout>
</widget>
</item>
<item>
<widget class="collapsibleGroupBox2" name="groupBox_4">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Search</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_31">
<item>
<widget class="search" name="widget" native="true">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
@ -2045,6 +2070,12 @@
<header>ui.collapsibleGroupBox2.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>search</class>
<extends>QWidget</extends>
<header>ui.search.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
@ -2055,8 +2086,8 @@
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>787</y>
<x>342</x>
<y>760</y>
</hint>
<hint type="destinationlabel">
<x>860</x>
@ -2087,12 +2118,12 @@
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>1088</x>
<y>770</y>
<x>1136</x>
<y>768</y>
</hint>
<hint type="destinationlabel">
<x>1053</x>
<y>731</y>
<x>1137</x>
<y>729</y>
</hint>
</hints>
</connection>
@ -2135,12 +2166,12 @@
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>742</x>
<y>762</y>
<x>446</x>
<y>127</y>
</hint>
<hint type="destinationlabel">
<x>742</x>
<y>749</y>
<x>446</x>
<y>120</y>
</hint>
</hints>
</connection>

150
src/ui/search.py Normal file
View file

@ -0,0 +1,150 @@
#!/usr/bin/env python
#--!-- coding: utf8 --!--
from qt import *
from enums import *
from models.outlineModel import *
from ui.search_ui import *
from functions import *
from models.references import *
class search(QWidget, Ui_search):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
self.options = {
"All": True,
"Title": True,
"Text": True,
"Summary": False,
"Notes": False,
"POV": False,
"Status": False,
"Label": False,
"CS": True
}
self.text.returnPressed.connect(self.search)
self.generateOptionMenu()
self.delegate = listResultDelegate(self)
self.result.setItemDelegate(self.delegate)
self.result.itemActivated.connect(self.openItem)
def generateOptionMenu(self):
self.menu = QMenu(self)
a = QAction(self.tr("Search in:"), self.menu)
a.setEnabled(False)
self.menu.addAction(a)
for i, d in [
(self.tr("All"), "All"),
(self.tr("Title"), "Title"),
(self.tr("Text"), "Text"),
(self.tr("Summary"), "Summary"),
(self.tr("Notes"), "Notes"),
(self.tr("POV"), "POV"),
(self.tr("Status"), "Status"),
(self.tr("Label"), "Label"),
]:
a = QAction(i, self.menu)
a.setCheckable(True)
a.setChecked(self.options[d])
a.setData(d)
a.triggered.connect(self.updateOptions)
self.menu.addAction(a)
self.menu.addSeparator()
a = QAction(self.tr("Options:"), self.menu)
a.setEnabled(False)
self.menu.addAction(a)
for i, d in [
(self.tr("Case sensitive"), "CS"),
]:
a = QAction(i, self.menu)
a.setCheckable(True)
a.setChecked(self.options[d])
a.setData(d)
a.triggered.connect(self.updateOptions)
self.menu.addAction(a)
self.menu.addSeparator()
self.btnOptions.setMenu(self.menu)
def updateOptions(self):
a = self.sender()
self.options[a.data()] = a.isChecked()
def search(self):
text = self.text.text()
# Chosing the right columns
lstColumns = [
("Title", Outline.title.value),
("Text", Outline.text.value),
("Summary", Outline.summarySentance.value),
("Summary", Outline.summaryFull.value),
("Notes", Outline.notes.value),
("POV", Outline.POV.value),
("Status", Outline.status.value),
("Label", Outline.label.value),
]
columns = [c[1] for c in lstColumns if self.options[c[0]] or self.options["All"]]
# Setting override cursor
qApp.setOverrideCursor(Qt.WaitCursor)
# Searching
model = mainWindow().mdlOutline
results = model.findItemsContaining(text, columns, self.options["CS"])
# Showing results
self.result.clear()
for r in results:
index = model.getIndexByID(r)
if not index.isValid():
continue
item = index.internalPointer()
i = QListWidgetItem(item.title(), self.result)
i.setData(Qt.UserRole, r)
i.setData(Qt.UserRole + 1, item.path())
self.result.addItem(i)
# Removing override cursor
qApp.restoreOverrideCursor()
def openItem(self, item):
mw = mainWindow()
index = mw.mdlOutline.getIndexByID(item.data(Qt.UserRole))
mw.mainEditor.setCurrentModelIndex(index, newTab=True)
class listResultDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index):
extra = index.data(Qt.UserRole+1)
if not extra:
return QStyledItemDelegate.paint(self, painter, option, index)
else:
if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.color(QPalette.Highlight))
title = index.data()
extra = " - {}".format(extra)
painter.drawText(option.rect.adjusted(2, 1, 0, 0), Qt.AlignLeft, title)
fm = QFontMetrics(option.font)
w = fm.width(title)
r = QRect(option.rect)
r.setLeft(r.left() + w)
painter.save()
if option.state & QStyle.State_Selected:
painter.setPen(Qt.white)
else:
painter.setPen(Qt.gray)
painter.drawText(r.adjusted(2, 1, 0, 0), Qt.AlignLeft, extra)
painter.restore()

42
src/ui/search_ui.py Normal file
View file

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'src/ui/search_ui.ui'
#
# Created by: PyQt5 UI code generator 5.4.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_search(object):
def setupUi(self, search):
search.setObjectName("search")
search.resize(400, 300)
self.verticalLayout = QtWidgets.QVBoxLayout(search)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.text = QtWidgets.QLineEdit(search)
self.text.setProperty("clearButtonEnabled", True)
self.text.setObjectName("text")
self.horizontalLayout.addWidget(self.text)
self.btnOptions = QtWidgets.QPushButton(search)
self.btnOptions.setText("")
icon = QtGui.QIcon.fromTheme("edit-find")
self.btnOptions.setIcon(icon)
self.btnOptions.setCheckable(True)
self.btnOptions.setObjectName("btnOptions")
self.horizontalLayout.addWidget(self.btnOptions)
self.verticalLayout.addLayout(self.horizontalLayout)
self.result = QtWidgets.QListWidget(search)
self.result.setObjectName("result")
self.verticalLayout.addWidget(self.result)
self.retranslateUi(search)
QtCore.QMetaObject.connectSlotsByName(search)
def retranslateUi(self, search):
_translate = QtCore.QCoreApplication.translate
search.setWindowTitle(_translate("search", "Form"))

51
src/ui/search_ui.ui Normal file
View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>search</class>
<widget class="QWidget" name="search">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="text">
<property name="clearButtonEnabled" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnOptions">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="edit-find"/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="result"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>