diff --git a/src/libprs500/gui2/dialogs/tag_editor.py b/src/libprs500/gui2/dialogs/tag_editor.py
index 2a503b2222..55cf45f3b0 100644
--- a/src/libprs500/gui2/dialogs/tag_editor.py
+++ b/src/libprs500/gui2/dialogs/tag_editor.py
@@ -13,10 +13,11 @@
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from PyQt4.QtCore import SIGNAL, Qt
-from PyQt4.QtGui import QDialog
+from PyQt4.QtGui import QDialog, QMessageBox
from libprs500.gui2.dialogs.tag_editor_ui import Ui_TagEditor
from libprs500.gui2 import qstring_to_unicode
+from libprs500.gui2 import question_dialog
class TagEditor(QDialog, Ui_TagEditor):
@@ -45,12 +46,34 @@ class TagEditor(QDialog, Ui_TagEditor):
if tag not in tags:
self.available_tags.addItem(tag)
- self.connect(self.apply_button, SIGNAL('clicked()'), self.apply_tags)
+ self.connect(self.apply_button, SIGNAL('clicked()'), self.apply_tags)
self.connect(self.unapply_button, SIGNAL('clicked()'), self.unapply_tags)
self.connect(self.add_tag_button, SIGNAL('clicked()'), self.add_tag)
- self.connect(self.add_tag_input, SIGNAL('returnPressed()'), self.add_tag)
+ self.connect(self.delete_button, SIGNAL('clicked()'), self.delete_tags)
+ self.connect(self.add_tag_input, SIGNAL('returnPressed()'), self.add_tag)
self.connect(self.available_tags, SIGNAL('itemActivated(QListWidgetItem*)'), self.apply_tags)
- self.connect(self.applied_tags, SIGNAL('itemActivated(QListWidgetItem*)'), self.unapply_tags)
+ self.connect(self.applied_tags, SIGNAL('itemActivated(QListWidgetItem*)'), self.unapply_tags)
+
+
+ def delete_tags(self, item=None):
+ confirms, deletes = [], []
+ items = self.available_tags.selectedItems() if item is None else [item]
+ for item in items:
+ if self.db.is_tag_used(qstring_to_unicode(item.text())):
+ confirms.append(item)
+ else:
+ deletes.append(item)
+ if confirms:
+ ct = ', '.join([qstring_to_unicode(item.text()) for item in confirms])
+ d = question_dialog(self, 'Are your sure?',
+ '
The following tags are used by one or more books. Are you certain you want to delete them?
'+ct)
+ if d.exec_() == QMessageBox.Yes:
+ deletes += confirms
+
+ for item in deletes:
+ self.db.delete_tag(qstring_to_unicode(item.text()))
+ self.available_tags.takeItem(self.available_tags.row(item))
+
def apply_tags(self, item=None):
items = self.available_tags.selectedItems() if item is None else [item]
diff --git a/src/libprs500/gui2/dialogs/tag_editor.ui b/src/libprs500/gui2/dialogs/tag_editor.ui
index 7c09a70952..4f9953e1e7 100644
--- a/src/libprs500/gui2/dialogs/tag_editor.ui
+++ b/src/libprs500/gui2/dialogs/tag_editor.ui
@@ -17,35 +17,48 @@
-
-
+
-
-
+
-
-
-
-
-
-
- A&vailable tags
-
-
- available_tags
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
+
+ A&vailable tags
+
+
+ available_tags
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Delete tag from database. This will unapply the tag from all books and then remove it from the database.
+
+
+ ...
+
+
+ :/images/trash.svg
+
+
-
@@ -62,136 +75,136 @@
+
+
+ -
+
-
-
-
-
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Apply tag to current book
-
-
- ...
-
-
- :/images/forward.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
-
-
-
-
-
-
-
-
-
- A&pplied tags
-
-
- applied_tags
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- true
-
-
- QAbstractItemView::MultiSelection
-
-
-
-
+
+
+ Apply tag to current book
+
+
+ ...
+
+
+ :/images/forward.svg
+
+
-
-
-
-
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Unapply (remove) tag from current book
-
-
- ...
-
-
- :/images/list_remove.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
- -
+
-
+
+
-
+
+
-
+
+
+ A&pplied tags
+
+
+ applied_tags
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+ QAbstractItemView::MultiSelection
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Unapply (remove) tag from current book
+
+
+ ...
+
+
+ :/images/list_remove.svg
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
-
@@ -251,7 +264,7 @@
- -
+
-
Qt::Horizontal
diff --git a/src/libprs500/library/database.py b/src/libprs500/library/database.py
index 247f0e400e..816aa0d16e 100644
--- a/src/libprs500/library/database.py
+++ b/src/libprs500/library/database.py
@@ -377,7 +377,7 @@ class LibraryDatabase(object):
BEFORE DELETE ON tags
BEGIN
SELECT CASE
- WHEN (SELECT COUNT(id) FROM books_tags_link WHERE book=OLD.book) > 0
+ WHEN (SELECT COUNT(id) FROM books_tags_link WHERE tag=OLD.book) > 0
THEN RAISE(ABORT, 'Foreign key violation: tag is still referenced')
END;
END;
@@ -722,7 +722,23 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
''')
conn.execute('pragma user_version=5')
conn.commit()
-
+
+ @staticmethod
+ def upgrade_version5(conn):
+ conn.executescript(\
+ '''
+ DROP TRIGGER fkc_delete_books_tags_link;
+ CREATE TRIGGER fkc_delete_books_tags_link
+ BEFORE DELETE ON tags
+ BEGIN
+ SELECT CASE
+ WHEN (SELECT COUNT(id) FROM books_tags_link WHERE tag=OLD.id) > 0
+ THEN RAISE(ABORT, 'Foreign key violation: tag is still referenced')
+ END;
+ END;
+ ''')
+ conn.execute('pragma user_version=6')
+ conn.commit()
def __del__(self):
global _lock_file
@@ -747,6 +763,8 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
LibraryDatabase.upgrade_version3(self.conn)
if self.user_version == 4: # Upgrade to 5
LibraryDatabase.upgrade_version4(self.conn)
+ if self.user_version == 5: # Upgrade to 6
+ LibraryDatabase.upgrade_version5(self.conn)
def close(self):
global _lock_file
@@ -1049,6 +1067,24 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
self.conn.execute('INSERT INTO comments(book,text) VALUES (?,?)', (id, text))
self.conn.commit()
+ def is_tag_used(self, tag):
+ id = self.conn.execute('SELECT id FROM tags WHERE name=?', (tag,)).fetchone()
+ if not id:
+ return False
+ return bool(self.conn.execute('SELECT tag FROM books_tags_link WHERE tag=?',(id[0],)).fetchone())
+
+ def delete_tag(self, tag):
+ id = self.conn.execute('SELECT id FROM tags WHERE name=?', (tag,)).fetchone()
+ if id:
+ id = id[0]
+ self.conn.execute('DELETE FROM books_tags_link WHERE tag=?', (id,))
+ self.conn.execute('DELETE FROM tags WHERE id=?', (id,))
+ self.conn.commit()
+
+ def delete_tags(self, tags):
+ for tag in tags:
+ self.delete_tag(tag)
+
def set_tags(self, id, tags, append=False):
'''
@param tags: list of strings