From 55244b5cf7b8ed653cd1cdfc62ecde1f296bcfe5 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Wed, 3 Jan 2007 11:16:36 +0000 Subject: [PATCH] Closes #418, Context menu option to rename attached files New methods, Item.renameAttachmentFile(newName, force) -- _force_ forces overwrite of an existing file For the moment, implemented in the UI via a checkbox in the attachment title rename dialog (accessible by clicking on the title in the right pane) to rename the associated file as well -- this might be replaced by the upcoming keep-filenames-in-sync-with-attachment-titles feature, but it's probably fine for Beta 3. Also new: - Zotero.Attachments.getPath(file, linkMode) to get a relative or persistent path as appropriate given the link mode --- chrome/content/zotero/overlay.js | 42 ++++++++++++++++++-- chrome/content/zotero/xpcom/attachments.js | 25 +++++++----- chrome/content/zotero/xpcom/data_access.js | 40 +++++++++++++++++++ chrome/locale/en-US/zotero/zotero.properties | 3 ++ 4 files changed, 96 insertions(+), 14 deletions(-) diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index e07dc21fb..99f34ce50 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -438,10 +438,44 @@ var ZoteroPane = new function() // For the time being, use a silly little popup label.className = 'zotero-clicky'; label.onclick = function(event){ - var newTitle = prompt(Zotero.getString('itemFields.title') + ':', val); - if (newTitle && newTitle != val) - { - item.ref.setField('title', newTitle); + var nsIPS = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] + .getService(Components.interfaces.nsIPromptService); + + var newTitle = { value: val }; + var checkState = { value: false }; + + while (true) { + var result = nsIPS.prompt(window, + Zotero.getString('pane.item.attachments.rename.title'), + '', newTitle, + Zotero.getString('pane.item.attachments.rename.renameAssociatedFile'), + checkState); + + if (!result || !newTitle.value) { + return; + } + + if (checkState.value) { + var renamed = item.ref.renameAttachmentFile(newTitle.value); + if (renamed == -1) { + var confirmed = confirm(newTitle.value + ' exists. Overwrite existing file?'); + if (confirmed) { + item.ref.renameAttachmentFile(newTitle.value, true); + break; + } + continue; + } + else if (renamed == -2 || !renamed) { + alert(Zotero.getString('pane.item.attachments.rename.error')); + return; + } + } + + break; + } + + if (newTitle.value != val) { + item.ref.setField('title', newTitle.value); item.ref.save(); } } diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js index 06da05cd7..83a69c542 100644 --- a/chrome/content/zotero/xpcom/attachments.js +++ b/chrome/content/zotero/xpcom/attachments.js @@ -33,6 +33,7 @@ Zotero.Attachments = new function(){ this.linkFromURL = linkFromURL; this.linkFromDocument = linkFromDocument; this.importFromDocument = importFromDocument; + this.getPath = getPath; var self = this; @@ -491,6 +492,18 @@ Zotero.Attachments = new function(){ } + function getPath(file, linkMode) { + if (linkMode == self.LINK_MODE_IMPORTED_URL || + linkMode == self.LINK_MODE_IMPORTED_FILE) { + var storageDir = Zotero.getStorageDirectory(); + storageDir.QueryInterface(Components.interfaces.nsILocalFile); + return file.getRelativeDescriptor(storageDir); + } + + return file.persistentDescriptor; + } + + function _getFileNameFromURL(url, mimeType){ var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"] .createInstance(Components.interfaces.nsIURL); @@ -533,16 +546,8 @@ Zotero.Attachments = new function(){ * Returns the itemID of the new attachment **/ function _addToDB(file, url, title, linkMode, mimeType, charsetID, sourceItemID, itemID){ - if (file){ - if (linkMode==self.LINK_MODE_IMPORTED_URL || - linkMode==self.LINK_MODE_IMPORTED_FILE){ - var storageDir = Zotero.getStorageDirectory(); - storageDir.QueryInterface(Components.interfaces.nsILocalFile); - var path = file.getRelativeDescriptor(storageDir); - } - else { - var path = file.persistentDescriptor; - } + if (file) { + var path = getPath(file, linkMode); } Zotero.DB.beginTransaction(); diff --git a/chrome/content/zotero/xpcom/data_access.js b/chrome/content/zotero/xpcom/data_access.js index c0130bdf4..cf618108e 100644 --- a/chrome/content/zotero/xpcom/data_access.js +++ b/chrome/content/zotero/xpcom/data_access.js @@ -1423,6 +1423,46 @@ Zotero.Item.prototype.getFile = function(row){ } +/* + * Rename file associated with an attachment + * + * -1 Destination file exists -- use _force_ to overwrite + * -2 Error renaming + * false Attachment file not found or other error + */ +Zotero.Item.prototype.renameAttachmentFile = function(newName, force) { + var file = this.getFile(); + if (!file) { + return false; + } + + try { + var dest = file.parent; + dest.append(newName); + + if (force) { + dest.remove(null); + } + else if (dest.exists()) { + return -1; + } + + file.moveTo(file.parent, newName); + + var linkMode = this.getAttachmentLinkMode(); + var path = Zotero.Attachments.getPath(file, linkMode); + + var sql = "UPDATE itemAttachments SET path=? WHERE itemID=?"; + Zotero.DB.query(sql, [path, this.getID()]); + + return true; + } + catch (e) { + return -2; + } +} + + /* * Return a file:/// URL path to files and snapshots */ diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties index 4d2d5dd74..aa93f772e 100644 --- a/chrome/locale/en-US/zotero/zotero.properties +++ b/chrome/locale/en-US/zotero/zotero.properties @@ -51,6 +51,9 @@ pane.item.notes.delete.confirm = Are you sure you want to delete this note? pane.item.notes.count.zero = %S notes: pane.item.notes.count.singular = %S note: pane.item.notes.count.plural = %S notes: +pane.item.attachments.rename.title = New title: +pane.item.attachments.rename.renameAssociatedFile = Rename associated file +pane.item.attachments.rename.error = An error occurred while renaming the file. pane.item.attachments.view.link = View Page pane.item.attachments.view.snapshot = View Snapshot pane.item.attachments.view.file = View File