diff --git a/src/models/outlineModel.py b/src/models/outlineModel.py
index 53c889c1..0d2ef54a 100644
--- a/src/models/outlineModel.py
+++ b/src/models/outlineModel.py
@@ -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
\ No newline at end of file
diff --git a/src/models/persosModel.py b/src/models/persosModel.py
index 270485bf..6fc8e400 100644
--- a/src/models/persosModel.py
+++ b/src/models/persosModel.py
@@ -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()):
diff --git a/src/models/references.py b/src/models/references.py
index c6b55e6d..3b9543c9 100644
--- a/src/models/references.py
+++ b/src/models/references.py
@@ -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 += "
{text}".format(
diff --git a/src/ui/cheatSheet.py b/src/ui/cheatSheet.py
index 6b393a2e..8bd0feaf 100644
--- a/src/ui/cheatSheet.py
+++ b/src/ui/cheatSheet.py
@@ -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)
diff --git a/src/ui/mainWindow.py b/src/ui/mainWindow.py
index 4206bb6a..60deaaca 100644
--- a/src/ui/mainWindow.py
+++ b/src/ui/mainWindow.py
@@ -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
diff --git a/src/ui/mainWindow.ui b/src/ui/mainWindow.ui
index aa56cd58..5e89f523 100644
--- a/src/ui/mainWindow.ui
+++ b/src/ui/mainWindow.ui
@@ -717,7 +717,7 @@
- 3
+ 0
@@ -1628,9 +1628,6 @@
true
-
- 0
-
-
@@ -1644,6 +1641,34 @@
+ -
+
+
+
+ 75
+ true
+
+
+
+ Search
+
+
+ true
+
+
+
-
+
+
+
+ 50
+ false
+
+
+
+
+
+
+
@@ -2045,6 +2070,12 @@
ui.collapsibleGroupBox2.h
1
+
+ search
+ QWidget
+
+ 1
+
@@ -2055,8 +2086,8 @@
setVisible(bool)
- 325
- 787
+ 342
+ 760
860
@@ -2087,12 +2118,12 @@
setVisible(bool)
- 1088
- 770
+ 1136
+ 768
- 1053
- 731
+ 1137
+ 729
@@ -2135,12 +2166,12 @@
setVisible(bool)
- 742
- 762
+ 446
+ 127
- 742
- 749
+ 446
+ 120
diff --git a/src/ui/search.py b/src/ui/search.py
new file mode 100644
index 00000000..9858541c
--- /dev/null
+++ b/src/ui/search.py
@@ -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()
\ No newline at end of file
diff --git a/src/ui/search_ui.py b/src/ui/search_ui.py
new file mode 100644
index 00000000..cfc0f8c9
--- /dev/null
+++ b/src/ui/search_ui.py
@@ -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"))
+
diff --git a/src/ui/search_ui.ui b/src/ui/search_ui.ui
new file mode 100644
index 00000000..e594f9ab
--- /dev/null
+++ b/src/ui/search_ui.ui
@@ -0,0 +1,51 @@
+
+
+ search
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Form
+
+
+
+ 0
+
+ -
+
+
-
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ -
+
+
+
+
+
+
+