diff --git a/chrome/content/zotero/bindings/tagselector.xml b/chrome/content/zotero/bindings/tagselector.xml index b37ec3d0c..54919e112 100644 --- a/chrome/content/zotero/bindings/tagselector.xml +++ b/chrome/content/zotero/bindings/tagselector.xml @@ -151,6 +151,7 @@ } Zotero.debug('Refreshing tags selector'); + var empty = true; var tagsToggleBox = this.id('tags-toggle'); if (fetch || this._dirty) { @@ -201,6 +202,7 @@ //Zotero.debug(2); labels[i].setAttribute('inScope', true); labels[i].setAttribute('hidden', false); + empty = false; } else { //Zotero.debug(3); @@ -220,8 +222,38 @@ } labels[i].setAttribute('hidden', false); + empty = false; } } + + this.updateNumSelected(); + this.id('tags-toggle').setAttribute('collapsed', empty); + this.id('no-tags-box').setAttribute('collapsed', !empty); + ]]> + + + + + + + @@ -233,25 +265,20 @@ + + @@ -462,29 +492,56 @@ - - - - - - - + + + + + + + + + + + + - - + + + + + --> + + + + + + + + + + + + + + + + + + + diff --git a/chrome/content/zotero/xpcom/data_access.js b/chrome/content/zotero/xpcom/data_access.js index cf618108e..9ddd16745 100644 --- a/chrome/content/zotero/xpcom/data_access.js +++ b/chrome/content/zotero/xpcom/data_access.js @@ -1188,12 +1188,8 @@ Zotero.Item.prototype.getNotes = function(){ * Return true if a note item is an abstract, false otherwise */ Zotero.Item.prototype.isAbstract = function() { - if (this.isAttachment()) { - return false; - } - if (!this.isNote()) { - throw ("isAbstract() can only be called on note items"); + return false; } if (!this.getID()) { @@ -1640,6 +1636,7 @@ Zotero.Item.prototype.addTagByID = function(tagID) { Zotero.DB.commitTransaction(); Zotero.Notifier.trigger('modify', 'item', this.getID()); + Zotero.Notifier.trigger('add', 'item-tag', this.getID() + '-' + tagID); return true; } @@ -1683,6 +1680,8 @@ Zotero.Item.prototype.replaceTag = function(oldTagID, newTag){ var id = this.addTag(newTag); Zotero.DB.commitTransaction(); Zotero.Notifier.trigger('modify', 'item', this.getID()); + Zotero.Notifier.trigger('remove', 'item-tag', this.getID() + '-' + oldTagID); + Zotero.Notifier.trigger('add', 'item-tag', this.getID() + '-' + id); return id; } @@ -1697,6 +1696,7 @@ Zotero.Item.prototype.removeTag = function(tagID){ Zotero.Tags.purge(); Zotero.DB.commitTransaction(); Zotero.Notifier.trigger('modify', 'item', this.getID()); + Zotero.Notifier.trigger('remove', 'item-tag', this.getID() + '-' + tagID); } Zotero.Item.prototype.removeAllTags = function(){ @@ -1705,10 +1705,18 @@ Zotero.Item.prototype.removeAllTags = function(){ } Zotero.DB.beginTransaction(); + var tagIDs = this.getTagIDs(); Zotero.DB.query("DELETE FROM itemTags WHERE itemID=?", this.getID()); Zotero.Tags.purge(); Zotero.DB.commitTransaction(); Zotero.Notifier.trigger('modify', 'item', this.getID()); + + if (tagIDs) { + for (var i in tagIDs) { + tagIDs[i] = this.getID() + '-' + tagIDs[i]; + } + Zotero.Notifier.trigger('remove', 'item-tag', tagIDs); + } } @@ -2647,7 +2655,7 @@ Zotero.Collection.prototype.addItem = function(itemID){ Zotero.Notifier.trigger('modify', 'collection', this.getID()); } - Zotero.Notifier.trigger('add', 'item', itemID); + Zotero.Notifier.trigger('add', 'collection-item', this.getID() + '-' + itemID); } @@ -2688,7 +2696,7 @@ Zotero.Collection.prototype.removeItem = function(itemID){ Zotero.Notifier.trigger('modify', 'collection', this.getID()); } - Zotero.Notifier.trigger('remove', 'item', itemID); + Zotero.Notifier.trigger('remove', 'collection-item', this.getID() + '-' + itemID); } @@ -3251,6 +3259,47 @@ Zotero.Tags = new function(){ Zotero.debug('Renaming tag', 4); Zotero.DB.beginTransaction(); + + // Check if the new tag already exists + var sql = "SELECT tagID FROM tags WHERE tag=?"; + var existingTagID = Zotero.DB.valueQuery(sql, tag); + if (existingTagID) { + var itemIDs = this.getTagItems(tagID); + var existingItemIDs = this.getTagItems(existingTagID); + + // Would be easier to just call removeTag(tagID) and addTag(existingID) + // here, but this is considerably more efficient + var sql = "UPDATE OR REPLACE itemTags SET tagID=? WHERE tagID=?"; + Zotero.DB.query(sql, [existingTagID, tagID]); + + // Manual purge of old tag + var sql = "DELETE FROM tags WHERE tagID=?"; + Zotero.DB.query(sql, tagID); + delete _tags[_tagsByID[tagID]]; + delete _tagsByID[tagID]; + Zotero.Notifier.trigger('delete', 'tag', tagID); + + // Simulate tag removal on items that used old tag + var itemTags = []; + for (var i in itemIDs) { + itemTags.push(itemIDs[i] + '-' + tagID); + } + Zotero.Notifier.trigger('remove', 'item-tag', itemTags); + + // And send tag add for new tag (except for those that already had it) + var itemTags = []; + for (var i in itemIDs) { + if (existingItemIDs.indexOf(itemIDs[i]) == -1) { + itemTags.push(itemIDs[i] + '-' + existingTagID); + } + } + Zotero.Notifier.trigger('add', 'item-tag', itemTags); + + Zotero.Notifier.trigger('modify', 'item', itemIDs); + Zotero.DB.commitTransaction(); + return; + } + var sql = "UPDATE tags SET tag=? WHERE tagID=?"; Zotero.DB.query(sql, [{string: tag}, {int: tagID}]); @@ -3270,15 +3319,21 @@ Zotero.Tags = new function(){ Zotero.DB.beginTransaction(); var sql = "SELECT itemID FROM itemTags WHERE tagID=?"; - var items = Zotero.DB.columnQuery(sql, tagID); + var itemIDs = Zotero.DB.columnQuery(sql, tagID); - if (!items) { + if (!itemIDs) { return; } var sql = "DELETE FROM itemTags WHERE tagID=?"; Zotero.DB.query(sql, tagID); - Zotero.Notifier.trigger('modify', 'item', items) + + Zotero.Notifier.trigger('modify', 'item', itemIDs) + var itemTags = []; + for (var i in itemIDs) { + itemTags.push(itemIDs[i] + '-' + tagID); + } + Zotero.Notifier.trigger('remove', 'item-tag', itemTags); this.purge(); Zotero.DB.commitTransaction(); diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index 2db1d8a52..10c85b7ac 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -110,7 +110,7 @@ Zotero.ItemTreeView.prototype.refresh = function() */ Zotero.ItemTreeView.prototype.notify = function(action, type, ids) { - if (type != 'item'){ + if (type != 'item' && type != 'collection-item'){ return; } @@ -136,12 +136,13 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids) var rows = new Array(); for(var i=0, len=ids.length; i + - - - - + + + + diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties index aa93f772e..05cea5c63 100644 --- a/chrome/locale/en-US/zotero/zotero.properties +++ b/chrome/locale/en-US/zotero/zotero.properties @@ -21,6 +21,9 @@ pane.tagSelector.rename.title = Please enter a new name for this tag. pane.tagSelector.rename.message = The tag will be changed in all associated items. pane.tagSelector.delete.title = Are you sure you want to delete this tag? pane.tagSelector.delete.message = The tag will be removed from all items. +pane.tagSelector.numSelected.none = 0 tags selected +pane.tagSelector.numSelected.singular = %S tag selected +pane.tagSelector.numSelected.plural = %S tags selected pane.items.delete = Are you sure you want to delete the selected item? pane.items.delete.multiple = Are you sure you want to delete the selected items? diff --git a/chrome/skin/default/zotero/bindings/tagselector.css b/chrome/skin/default/zotero/bindings/tagselector.css index 84161b612..0f602e04c 100644 --- a/chrome/skin/default/zotero/bindings/tagselector.css +++ b/chrome/skin/default/zotero/bindings/tagselector.css @@ -1,9 +1,3 @@ -/* Don't focus filter textbox if pane isn't open */ -zoterotagselector[collapsed=true] tags-search -{ - -moz-user-focus: ignore; -} - groupbox { overflow: auto; @@ -21,20 +15,20 @@ checkbox margin: .75em 0 .4em; } -label +#tags-toggle label { margin-right: .2em; padding: .15em .25em; -moz-user-focus: ignore; } -label[selected="true"] +#tags-toggle label[selected="true"] { background: #a9c6f0 !important; } /* Visible out-of-scope tags should be grey */ -label[inScope="false"] +#tags-toggle label[inScope="false"] { color: #666 !important; } @@ -46,15 +40,15 @@ label.zotero-clicky[inScope="false"]:active background: inherit !important; } -label[draggedOver="true"] +#tags-toggle label[draggedOver="true"] { color: white !important; background: #666; } -hbox +groupbox > hbox { - -moz-box-align: baseline; + -moz-box-align: center; -moz-box-pack: center; } @@ -66,6 +60,12 @@ hbox list-style-image: url('chrome://zotero/skin/search-cancel.png'); } +groupbox > hbox > hbox +{ + -moz-box-flex: 1; + -moz-box-align: center; +} + /* Bottom buttons */ toolbarbutton.zotero-clicky { @@ -73,3 +73,8 @@ toolbarbutton.zotero-clicky padding:1px; height:1em; } + +textbox +{ + margin: 3px 0 1px; +}