mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add box-based search interface tab to advanced search.
This commit is contained in:
parent
f550395add
commit
b6df943eb3
@ -1,17 +1,68 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
import re
|
import re
|
||||||
from PyQt4.QtGui import QDialog
|
from PyQt4.QtGui import QDialog, QDialogButtonBox
|
||||||
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from calibre.gui2.dialogs.search_ui import Ui_Dialog
|
from calibre.gui2.dialogs.search_ui import Ui_Dialog
|
||||||
from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH
|
from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH
|
||||||
|
|
||||||
class SearchDialog(QDialog, Ui_Dialog):
|
class SearchDialog(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, parent, db, box_values, current_tab):
|
||||||
QDialog.__init__(self, *args)
|
QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.mc = ''
|
self.mc = ''
|
||||||
|
searchables = sorted(db.field_metadata.searchable_fields(),
|
||||||
|
lambda x, y: cmp(x if x[0] != '#' else x[1:],
|
||||||
|
y if y[0] != '#' else y[1:]))
|
||||||
|
self.general_combo.addItems(searchables)
|
||||||
|
|
||||||
|
if (box_values):
|
||||||
|
for k,v in box_values.items():
|
||||||
|
if k == 'general_index':
|
||||||
|
continue
|
||||||
|
getattr(self, k).setText(v)
|
||||||
|
self.general_combo.setCurrentIndex(
|
||||||
|
self.general_combo.findText(box_values['general_index']))
|
||||||
|
self.box_last_values = box_values
|
||||||
|
|
||||||
|
self.buttonBox.accepted.connect(self.advanced_search_button_pushed)
|
||||||
|
self.tab_2_button_box.accepted.connect(self.box_search_accepted)
|
||||||
|
self.tab_2_button_box.rejected.connect(self.box_search_rejected)
|
||||||
|
self.clear_button.clicked.connect(self.clear_button_pushed)
|
||||||
|
self.adv_search_used = False
|
||||||
|
self.box_search_used = False
|
||||||
|
|
||||||
|
self.tabWidget.setCurrentIndex(current_tab)
|
||||||
|
self.tabWidget.currentChanged[int].connect(self.tab_changed)
|
||||||
|
self.tab_changed(current_tab)
|
||||||
|
|
||||||
|
def tab_changed(self, idx):
|
||||||
|
if idx == 1:
|
||||||
|
self.tab_2_button_box.button(QDialogButtonBox.Ok).setDefault(True)
|
||||||
|
else:
|
||||||
|
self.buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
|
||||||
|
|
||||||
|
def advanced_search_button_pushed(self):
|
||||||
|
self.adv_search_used = True
|
||||||
|
self.current_tab = 0
|
||||||
|
QDialog.accept(self)
|
||||||
|
|
||||||
|
def box_search_accepted(self):
|
||||||
|
self.box_search_used = True
|
||||||
|
self.current_tab = 1
|
||||||
|
QDialog.accept(self)
|
||||||
|
|
||||||
|
def box_search_rejected(self):
|
||||||
|
QDialog.reject(self)
|
||||||
|
|
||||||
|
def clear_button_pushed(self):
|
||||||
|
self.title_box.setText('')
|
||||||
|
self.authors_box.setText('')
|
||||||
|
self.series_box.setText('')
|
||||||
|
self.tags_box.setText('')
|
||||||
|
self.general_box.setText('')
|
||||||
|
|
||||||
def tokens(self, raw):
|
def tokens(self, raw):
|
||||||
phrases = re.findall(r'\s*".*?"\s*', raw)
|
phrases = re.findall(r'\s*".*?"\s*', raw)
|
||||||
@ -21,6 +72,12 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
return ['"' + self.mc + t + '"' for t in phrases + [r.strip() for r in raw.split()]]
|
return ['"' + self.mc + t + '"' for t in phrases + [r.strip() for r in raw.split()]]
|
||||||
|
|
||||||
def search_string(self):
|
def search_string(self):
|
||||||
|
if self.adv_search_used:
|
||||||
|
return self.adv_search_string()
|
||||||
|
else:
|
||||||
|
return self.box_search_string()
|
||||||
|
|
||||||
|
def adv_search_string(self):
|
||||||
mk = self.matchkind.currentIndex()
|
mk = self.matchkind.currentIndex()
|
||||||
if mk == CONTAINS_MATCH:
|
if mk == CONTAINS_MATCH:
|
||||||
self.mc = ''
|
self.mc = ''
|
||||||
@ -56,3 +113,34 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
tok = '"%s"'%tok
|
tok = '"%s"'%tok
|
||||||
return tok
|
return tok
|
||||||
|
|
||||||
|
def box_search_string(self):
|
||||||
|
ans = []
|
||||||
|
self.box_last_values = {}
|
||||||
|
title = unicode(self.title_box.text()).strip()
|
||||||
|
self.box_last_values['title_box'] = title
|
||||||
|
if title:
|
||||||
|
ans.append('title:"' + title + '"')
|
||||||
|
author = unicode(self.authors_box.text()).strip()
|
||||||
|
self.box_last_values['authors_box'] = author
|
||||||
|
if author:
|
||||||
|
ans.append('author:"' + author + '"')
|
||||||
|
series = unicode(self.series_box.text()).strip()
|
||||||
|
self.box_last_values['series_box'] = series
|
||||||
|
if series:
|
||||||
|
ans.append('series:"' + series + '"')
|
||||||
|
self.mc = '='
|
||||||
|
tags = unicode(self.tags_box.text())
|
||||||
|
self.box_last_values['tags_box'] = tags
|
||||||
|
tags = self.tokens(tags)
|
||||||
|
if tags:
|
||||||
|
tags = ['tags:' + t for t in tags]
|
||||||
|
ans.append('(' + ' or '.join(tags) + ')')
|
||||||
|
general = unicode(self.general_box.text())
|
||||||
|
self.box_last_values['general_box'] = general
|
||||||
|
general_index = unicode(self.general_combo.currentText())
|
||||||
|
self.box_last_values['general_index'] = general_index
|
||||||
|
if general:
|
||||||
|
ans.append(unicode(self.general_combo.currentText()) + ':"' + general + '"')
|
||||||
|
if ans:
|
||||||
|
return ' and '.join(ans)
|
||||||
|
return ''
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>Dialog</class>
|
<class>Dialog</class>
|
||||||
<widget class="QDialog" name="Dialog">
|
<widget class="QDialog" name="Dialog">
|
||||||
@ -5,18 +6,28 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>667</width>
|
<width>686</width>
|
||||||
<height>391</height>
|
<height>360</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Advanced Search</string>
|
<string>Advanced Search</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="../../../../resources/images.qrc" >
|
<iconset>
|
||||||
<normaloff>:/images/search.png</normaloff>:/images/search.png</iconset>
|
<normaloff>:/images/search.png</normaloff>:/images/search.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>A&dvanced Search</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -100,9 +111,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
@ -150,7 +158,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string> </string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>matchkind</cstring>
|
<cstring>matchkind</cstring>
|
||||||
@ -169,13 +177,16 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>See the <a href="http://calibre-ebook.com/user_manual/gui.html#the-search-interface">User Manual</a> for more help</string>
|
<string>See the <a href="http://calibre-ebook.com/user_manual/gui.html#the-search-interface">User Manual</a> for more help</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="openExternalLinks">
|
<property name="openExternalLinks">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -186,10 +197,156 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Titl&e/Author/Series ...</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Title:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>title_box</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="title_box">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter the title.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Author</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>authors_box</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Series</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>series_box</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ta&gs</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>tags_box</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="authors_box">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter an author's name. Only one author can be used.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="series_box">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter a series name, without an index. Only one series name can be used.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="tags_box">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter tags separated by spaces</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="general_box"/>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QComboBox" name="general_combo"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clear_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="tab_2_button_box">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>all</tabstop>
|
||||||
|
<tabstop>phrase</tabstop>
|
||||||
|
<tabstop>any</tabstop>
|
||||||
|
<tabstop>none</tabstop>
|
||||||
|
<tabstop>matchkind</tabstop>
|
||||||
|
<tabstop>buttonBox</tabstop>
|
||||||
|
<tabstop>title_box</tabstop>
|
||||||
|
<tabstop>authors_box</tabstop>
|
||||||
|
<tabstop>series_box</tabstop>
|
||||||
|
<tabstop>tags_box</tabstop>
|
||||||
|
<tabstop>general_combo</tabstop>
|
||||||
|
<tabstop>general_box</tabstop>
|
||||||
|
<tabstop>clear_button</tabstop>
|
||||||
|
<tabstop>tab_2_button_box</tabstop>
|
||||||
|
<tabstop>tabWidget</tabstop>
|
||||||
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../../../resources/images.qrc" />
|
<include location="../../../CBH_Data/calibre_development/calibre/resources/images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
|
@ -167,6 +167,7 @@ class SearchBar(QWidget): # {{{
|
|||||||
x.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
x.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||||
|
|
||||||
parent.advanced_search_button = x = QToolButton(self)
|
parent.advanced_search_button = x = QToolButton(self)
|
||||||
|
parent.advanced_search_button.setShortcut(_("Ctrl+s"))
|
||||||
x.setIcon(QIcon(I('search.png')))
|
x.setIcon(QIcon(I('search.png')))
|
||||||
l.addWidget(x)
|
l.addWidget(x)
|
||||||
x.setToolTip(_("Advanced search"))
|
x.setToolTip(_("Advanced search"))
|
||||||
|
@ -381,6 +381,8 @@ class SearchBoxMixin(object):
|
|||||||
unicode(self.search.toolTip())))
|
unicode(self.search.toolTip())))
|
||||||
self.advanced_search_button.setStatusTip(self.advanced_search_button.toolTip())
|
self.advanced_search_button.setStatusTip(self.advanced_search_button.toolTip())
|
||||||
self.clear_button.setStatusTip(self.clear_button.toolTip())
|
self.clear_button.setStatusTip(self.clear_button.toolTip())
|
||||||
|
self.search_last_values = None
|
||||||
|
self.search_current_tab = 0
|
||||||
|
|
||||||
def search_box_cleared(self):
|
def search_box_cleared(self):
|
||||||
self.tags_view.clear()
|
self.tags_view.clear()
|
||||||
@ -392,9 +394,12 @@ class SearchBoxMixin(object):
|
|||||||
self.tags_view.clear()
|
self.tags_view.clear()
|
||||||
|
|
||||||
def do_advanced_search(self, *args):
|
def do_advanced_search(self, *args):
|
||||||
d = SearchDialog(self)
|
d = SearchDialog(self, self.library_view.model().db,
|
||||||
|
self.search_last_values, self.search_current_tab)
|
||||||
if d.exec_() == QDialog.Accepted:
|
if d.exec_() == QDialog.Accepted:
|
||||||
self.search.set_search_string(d.search_string())
|
self.search.set_search_string(d.search_string())
|
||||||
|
self.search_last_values = d.box_last_values
|
||||||
|
self.search_current_tab = d.current_tab
|
||||||
|
|
||||||
class SavedSearchBoxMixin(object):
|
class SavedSearchBoxMixin(object):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user