1) Add "Edit virtual library". This also solves the problem of no longer having tooltips because the user can "edit" to see the VL search

2) Remove remaining tooltips
3) Add "current search" as a VL
4) Limit VL and restriction names to 40 characters
This commit is contained in:
Charles Haley 2013-04-12 11:34:58 +02:00
parent 29ae6e346e
commit 554c937a76

View File

@ -44,15 +44,46 @@ class SelectNames(QDialog): # {{{
yield unicode(item.data(Qt.DisplayRole).toString()) yield unicode(item.data(Qt.DisplayRole).toString())
# }}} # }}}
MAX_VIRTUAL_LIBRARY_NAME_LENGTH = 40
def _build_full_search_string(gui):
search_templates = (
'',
'{cl}',
'{cr}',
'(({cl}) and ({cr}))',
'{sb}',
'(({cl}) and ({sb}))',
'(({cr}) and ({sb}))',
'(({cl}) and ({cr}) and ({sb}))'
)
sb = gui.search.current_text
db = gui.current_db
cr = db.data.get_search_restriction()
cl = db.data.get_base_restriction()
dex = 0
if sb:
dex += 4
if cr:
dex += 2
if cl:
dex += 1
template = search_templates[dex]
return template.format(cl=cl, cr=cr, sb=sb).strip()
class CreateVirtualLibrary(QDialog): # {{{ class CreateVirtualLibrary(QDialog): # {{{
def __init__(self, gui, existing_names): def __init__(self, gui, existing_names, editing=None):
QDialog.__init__(self, gui) QDialog.__init__(self, gui)
self.gui = gui self.gui = gui
self.existing_names = existing_names self.existing_names = existing_names
self.setWindowTitle(_('Create virtual library')) if editing:
self.setWindowTitle(_('Edit virtual library'))
else:
self.setWindowTitle(_('Create virtual library'))
self.setWindowIcon(QIcon(I('lt.png'))) self.setWindowIcon(QIcon(I('lt.png')))
gl = QGridLayout() gl = QGridLayout()
@ -60,15 +91,19 @@ class CreateVirtualLibrary(QDialog): # {{{
self.la1 = la1 = QLabel(_('Virtual library &name:')) self.la1 = la1 = QLabel(_('Virtual library &name:'))
gl.addWidget(la1, 0, 0) gl.addWidget(la1, 0, 0)
self.vl_name = QLineEdit() self.vl_name = QLineEdit()
self.vl_name.setMaxLength(MAX_VIRTUAL_LIBRARY_NAME_LENGTH)
la1.setBuddy(self.vl_name) la1.setBuddy(self.vl_name)
gl.addWidget(self.vl_name, 0, 1) gl.addWidget(self.vl_name, 0, 1)
self.editing = editing
if editing:
self.vl_name.setText(editing)
self.la2 = la2 = QLabel(_('&Search expression:')) self.la2 = la2 = QLabel(_('&Search expression:'))
gl.addWidget(la2, 1, 0) gl.addWidget(la2, 1, 0)
self.vl_text = QLineEdit() self.vl_text = QLineEdit()
la2.setBuddy(self.vl_text) la2.setBuddy(self.vl_text)
gl.addWidget(self.vl_text, 1, 1) gl.addWidget(self.vl_text, 1, 1)
self.vl_text.setText(self.build_full_search_string()) self.vl_text.setText(_build_full_search_string(self.gui))
self.sl = sl = QLabel('<p>'+_('Create a virtual library based on: ')+ self.sl = sl = QLabel('<p>'+_('Create a virtual library based on: ')+
('<a href="author.{0}">{0}</a>, ' ('<a href="author.{0}">{0}</a>, '
@ -102,6 +137,11 @@ class CreateVirtualLibrary(QDialog): # {{{
bb.rejected.connect(self.reject) bb.rejected.connect(self.reject)
gl.addWidget(bb, 4, 0, 1, 0) gl.addWidget(bb, 4, 0, 1, 0)
if editing:
db = self.gui.current_db
virt_libs = db.prefs.get('virtual_libraries', {})
self.vl_text.setText(virt_libs.get(editing, ''))
self.resize(self.sizeHint()+QSize(150, 25)) self.resize(self.sizeHint()+QSize(150, 25))
def link_activated(self, url): def link_activated(self, url):
@ -116,48 +156,28 @@ class CreateVirtualLibrary(QDialog): # {{{
self.vl_name.setText(d.names.next()) self.vl_name.setText(d.names.next())
self.vl_text.setText(' or '.join(search)) self.vl_text.setText(' or '.join(search))
def build_full_search_string(self):
search_templates = (
'',
'{cl}',
'{cr}',
'(({cl}) and ({cr}))',
'{sb}',
'(({cl}) and ({sb}))',
'(({cr}) and ({sb}))',
'(({cl}) and ({cr}) and ({sb}))'
)
sb = self.gui.search.current_text
db = self.gui.current_db
cr = db.data.get_search_restriction()
cl = db.data.get_base_restriction()
dex = 0
if sb:
dex += 4
if cr:
dex += 2
if cl:
dex += 1
template = search_templates[dex]
return template.format(cl=cl, cr=cr, sb=sb)
def accept(self): def accept(self):
n = unicode(self.vl_name.text()) n = unicode(self.vl_name.text()).strip()
if not n: if not n:
error_dialog(self.gui, _('No name'), error_dialog(self.gui, _('No name'),
_('You must provide a name for the new virtual library'), _('You must provide a name for the new virtual library'),
show=True) show=True)
return return
if n in self.existing_names: if n.startswith('*'):
error_dialog(self.gui, _('Invalid name'),
_('A virtual library name cannot begin with "*"'),
show=True)
return
if n in self.existing_names and n != self.editing:
if question_dialog(self.gui, _('Name already in use'), if question_dialog(self.gui, _('Name already in use'),
_('That name is already in use. Do you want to replace it ' _('That name is already in use. Do you want to replace it '
'with the new search?'), 'with the new search?'),
default_yes=False) == self.Rejected: default_yes=False) == self.Rejected:
return return
v = unicode(self.vl_text.text()) v = unicode(self.vl_text.text()).strip()
if not v: if not v:
error_dialog(self.gui, _('No search string'), error_dialog(self.gui, _('No search string'),
_('You must provide a search to define the new virtual library'), _('You must provide a search to define the new virtual library'),
@ -192,6 +212,8 @@ class SearchRestrictionMixin(object):
def __init__(self): def __init__(self):
self.checked = QIcon(I('ok.png')) self.checked = QIcon(I('ok.png'))
self.empty = QIcon() self.empty = QIcon()
self.search_based_vl_name = None
self.search_based_vl = None
self.virtual_library_menu = QMenu() self.virtual_library_menu = QMenu()
@ -211,32 +233,31 @@ class SearchRestrictionMixin(object):
virt_libs[name] = search virt_libs[name] = search
db.prefs.set('virtual_libraries', virt_libs) db.prefs.set('virtual_libraries', virt_libs)
def do_create(self): def do_create_edit(self, editing=None):
db = self.library_view.model().db db = self.library_view.model().db
virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs = db.prefs.get('virtual_libraries', {})
cd = CreateVirtualLibrary(self, virt_libs.keys()) cd = CreateVirtualLibrary(self, virt_libs.keys(), editing=editing)
if cd.exec_() == cd.Accepted: if cd.exec_() == cd.Accepted:
if editing:
self._remove_vl(editing, reapply=False)
self.add_virtual_library(db, cd.library_name, cd.library_search) self.add_virtual_library(db, cd.library_name, cd.library_search)
self.apply_virtual_library(cd.library_name) self.apply_virtual_library(cd.library_name)
def do_remove(self):
db = self.library_view.model().db
db.data.set_base_restriction("")
db.data.set_base_restriction_name("")
self._apply_search_restriction(db.data.get_search_restriction(),
db.data.get_search_restriction_name())
def virtual_library_clicked(self): def virtual_library_clicked(self):
m = self.virtual_library_menu m = self.virtual_library_menu
m.clear() m.clear()
a = m.addAction(_('Create Virtual Library')) a = m.addAction(_('Create Virtual Library'))
a.triggered.connect(self.do_create) a.triggered.connect(partial(self.do_create_edit, editing=None))
a.setToolTip(_('Create a new virtual library from the results of a search'))
self.edit_menu = a = QMenu()
a.setTitle(_('Edit Virtual Library'))
a.aboutToShow.connect(partial(self.build_virtual_library_list, remove=False))
m.addMenu(a)
self.rm_menu = a = QMenu() self.rm_menu = a = QMenu()
a.setTitle(_('Remove Virtual Library')) a.setTitle(_('Remove Virtual Library'))
a.aboutToShow.connect(self.build_virtual_library_list) a.aboutToShow.connect(partial(self.build_virtual_library_list, remove=True))
m.addMenu(a) m.addMenu(a)
m.addSeparator() m.addSeparator()
@ -259,10 +280,20 @@ class SearchRestrictionMixin(object):
a = m.addAction(self.empty, self.no_restriction) a = m.addAction(self.empty, self.no_restriction)
a.triggered.connect(partial(self.apply_virtual_library, library='')) a.triggered.connect(partial(self.apply_virtual_library, library=''))
a = m.addAction(self.empty, _('*current search'))
a.triggered.connect(partial(self.apply_virtual_library, library='*'))
if self.search_based_vl_name:
a = m.addAction(
self.checked if db.data.get_base_restriction_name().startswith('*')
else self.empty,
self.search_based_vl_name)
a.triggered.connect(partial(self.apply_virtual_library,
library=self.search_based_vl_name))
virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs = db.prefs.get('virtual_libraries', {})
for vl in sorted(virt_libs.keys(), key=sort_key): for vl in sorted(virt_libs.keys(), key=sort_key):
a = m.addAction(self.checked if vl == current_lib else self.empty, vl) a = m.addAction(self.checked if vl == current_lib else self.empty, vl)
a.setToolTip(virt_libs[vl])
a.triggered.connect(partial(self.apply_virtual_library, library=vl)) a.triggered.connect(partial(self.apply_virtual_library, library=vl))
p = QPoint(0, self.virtual_library.height()) p = QPoint(0, self.virtual_library.height())
@ -274,22 +305,41 @@ class SearchRestrictionMixin(object):
if not library: if not library:
db.data.set_base_restriction('') db.data.set_base_restriction('')
db.data.set_base_restriction_name('') db.data.set_base_restriction_name('')
elif library == '*':
if not _build_full_search_string(self):
error_dialog(self, _('No search'),
_('There is no current search to use'), show=True)
return
self.search_based_vl = _build_full_search_string(self)
db.data.set_base_restriction(self.search_based_vl)
self.search_based_vl_name = self._trim_restriction_name(
'*' + self.search_based_vl)
db.data.set_base_restriction_name(self.search_based_vl_name)
elif library == self.search_based_vl_name:
db.data.set_base_restriction(self.search_based_vl)
db.data.set_base_restriction_name(self.search_based_vl_name)
elif library in virt_libs: elif library in virt_libs:
db.data.set_base_restriction(virt_libs[library]) db.data.set_base_restriction(virt_libs[library])
db.data.set_base_restriction_name(library) db.data.set_base_restriction_name(library)
self._apply_search_restriction(db.data.get_search_restriction(), self._apply_search_restriction(db.data.get_search_restriction(),
db.data.get_search_restriction_name()) db.data.get_search_restriction_name())
def build_virtual_library_list(self): def build_virtual_library_list(self, remove=False):
db = self.library_view.model().db db = self.library_view.model().db
virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs = db.prefs.get('virtual_libraries', {})
m = self.rm_menu if remove:
m = self.rm_menu
else:
m = self.edit_menu
m.clear() m.clear()
def add_action(name, search): def add_action(name, search):
a = m.addAction(name) a = m.addAction(name)
a.setToolTip(search) if remove:
a.triggered.connect(partial(self.remove_vl_triggered, name=name)) a.triggered.connect(partial(self.remove_vl_triggered, name=name))
else:
a.triggered.connect(partial(self.do_create_edit, editing=name))
for n in sorted(virt_libs.keys(), key=sort_key): for n in sorted(virt_libs.keys(), key=sort_key):
add_action(n, virt_libs[n]) add_action(n, virt_libs[n])
@ -300,13 +350,19 @@ class SearchRestrictionMixin(object):
'the virtual library {0}').format(name), 'the virtual library {0}').format(name),
default_yes=False): default_yes=False):
return return
self._remove_vl(name, reapply=True)
def _remove_vl(self, name, reapply=True):
db = self.library_view.model().db db = self.library_view.model().db
virt_libs = db.prefs.get('virtual_libraries', {}) virt_libs = db.prefs.get('virtual_libraries', {})
virt_libs.pop(name, None) virt_libs.pop(name, None)
db.prefs.set('virtual_libraries', virt_libs) db.prefs.set('virtual_libraries', virt_libs)
if db.data.get_base_restriction_name() == name: if reapply and db.data.get_base_restriction_name() == name:
self.apply_virtual_library('') self.apply_virtual_library('')
def _trim_restriction_name(self, name):
return name[0:MAX_VIRTUAL_LIBRARY_NAME_LENGTH].strip()
def build_search_restriction_list(self): def build_search_restriction_list(self):
m = self.ar_menu m = self.ar_menu
m.clear() m.clear()
@ -324,6 +380,7 @@ class SearchRestrictionMixin(object):
def add_action(txt, index): def add_action(txt, index):
self.search_restriction.addItem(txt) self.search_restriction.addItem(txt)
txt = self._trim_restriction_name(txt)
if txt == current_restriction: if txt == current_restriction:
a = m.addAction(self.checked, txt if txt else self.no_restriction) a = m.addAction(self.checked, txt if txt else self.no_restriction)
else: else:
@ -332,7 +389,7 @@ class SearchRestrictionMixin(object):
action=a, index=index)) action=a, index=index))
add_action('', 0) add_action('', 0)
add_action('*current search', 1) add_action(_('*current search'), 1)
dex = 2 dex = 2
if current_restriction_text: if current_restriction_text:
add_action(current_restriction_text, 2) add_action(current_restriction_text, 2)
@ -372,7 +429,7 @@ class SearchRestrictionMixin(object):
else: else:
self.search_restriction.insertItem(2, s) self.search_restriction.insertItem(2, s)
self.search_restriction.setCurrentIndex(2) self.search_restriction.setCurrentIndex(2)
self._apply_search_restriction(search, s) self._apply_search_restriction(search, self._trim_restriction_name(s))
def apply_search_restriction(self, i): def apply_search_restriction(self, i):
if i == 1: if i == 1: