diff --git a/src/js/app.js b/src/js/app.js index 6fa651fe..101fc4e0 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -99,6 +99,9 @@ this.localStorageService = new pskl.service.LocalStorageService(this.piskelController); this.localStorageService.init(); + this.desktopStorageService = new pskl.service.DesktopStorageService(this.piskelController); + this.desktopStorageService.init(); + this.imageUploadService = new pskl.service.ImageUploadService(); this.imageUploadService.init(); diff --git a/src/js/controller/settings/ImportController.js b/src/js/controller/settings/ImportController.js index d3aaae8e..0dc8f628 100644 --- a/src/js/controller/settings/ImportController.js +++ b/src/js/controller/settings/ImportController.js @@ -52,18 +52,7 @@ ns.ImportController.prototype.openPiskelDesktop_ = function (evt) { this.closeDrawer_(); - pskl.utils.FileUtilsDesktop.chooseFileDialog(function(filename){ - var chosenFilename = filename; - pskl.utils.FileUtilsDesktop.readFile(chosenFilename, function(content){ - pskl.utils.PiskelFileUtils.decodePiskelFile(content, function (piskel, descriptor, fps) { - piskel.setDescriptor(descriptor); - // store save path so we can resave without opening the save dialog - piskel.savePath = chosenFilename; - pskl.app.piskelController.setPiskel(piskel); - pskl.app.animationController.setFPS(fps); - }); - }); - }); + pskl.app.desktopStorageService.openPiskel(); }; ns.ImportController.prototype.onOpenPiskelClick_ = function (evt) { diff --git a/src/js/controller/settings/ResizeController.js b/src/js/controller/settings/ResizeController.js index b10f2443..1a09d4fb 100644 --- a/src/js/controller/settings/ResizeController.js +++ b/src/js/controller/settings/ResizeController.js @@ -31,7 +31,8 @@ var resizedLayers = this.piskelController.getLayers().map(this.resizeLayer_.bind(this)); var piskel = pskl.model.Piskel.fromLayers(resizedLayers, this.piskelController.getPiskel().getDescriptor()); - + // propagate savepath to new Piskel + piskel.savePath = pskl.app.piskelController.getSavePath(); pskl.app.piskelController.setPiskel(piskel, true); $.publish(Events.CLOSE_SETTINGS_DRAWER); }; diff --git a/src/js/controller/settings/SaveController.js b/src/js/controller/settings/SaveController.js index d32b82df..2bbe59aa 100644 --- a/src/js/controller/settings/SaveController.js +++ b/src/js/controller/settings/SaveController.js @@ -25,24 +25,14 @@ this.isPublicCheckbox = $('input[name=save-public-checkbox]'); this.isPublicCheckbox.prop('checked', descriptor.isPublic); - - // prevent default behaviour of ctrl-s is there a way to do this - // with the pre-existing system? Should I use alt-s instead? - $(document).bind('keydown', 'ctrl+s', function(e) { - e.preventDefault(); - return false; - }); + this.saveFileButton = $('#save-file-button'); //Environment dependent configuration: if (pskl.utils.Environment.detectNodeWebkit()) { // running in Node-Webkit... - pskl.app.shortcutService.addShortcut('ctrl+s', this.saveFileDesktop_.bind(this)); - this.saveFileButton = $('#save-file-button'); this.saveFileButton.click(this.saveFileDesktop_.bind(this)); } else { // running in browser... - pskl.app.shortcutService.addShortcut('ctrl+s', this.saveFileBrowser_.bind(this)); - this.saveFileButton = $('#save-file-button'); this.saveFileButton.click(this.saveFileBrowser_.bind(this)); } @@ -163,23 +153,7 @@ }; ns.SaveController.prototype.saveFileDesktop_ = function () { - this.beforeSaving_(); - var serialized = pskl.app.piskelController.serialize(); - var savePath = pskl.app.piskelController.getSavePath(); - // if we already have a filename, just save the file (using nodejs 'fs' api) - if (savePath) { - pskl.utils.FileUtilsDesktop.saveToFile(serialized, savePath, function () { - this.onSaveSuccess_(); - this.afterSaving_(); - }.bind(this)); - } else { - // "save as" = open a save dialog, and store the returned save path - pskl.utils.FileUtilsDesktop.saveAs(serialized, null, function (selectedSavePath) { - this.onSaveSuccess_(); - this.afterSaving_(); - pskl.app.piskelController.setSavePath(selectedSavePath); - }.bind(this)); - } + pskl.app.desktopStorageService.saveFile(); } ns.SaveController.prototype.getName = function () { diff --git a/src/js/service/DesktopStorageService.js b/src/js/service/DesktopStorageService.js new file mode 100644 index 00000000..c26a1e70 --- /dev/null +++ b/src/js/service/DesktopStorageService.js @@ -0,0 +1,70 @@ +(function () { + var ns = $.namespace('pskl.service'); + + ns.DesktopStorageService = function(piskelController) { + this.piskelController = piskelController || pskl.app.piskelController; + this.hideNotificationTimeoutID = 0; + }; + + ns.DesktopStorageService.prototype.init = function (){ + // activate keyboard shortcuts if this is the desktop version + if (pskl.utils.Environment.detectNodeWebkit()) { + pskl.app.shortcutService.addShortcut('ctrl+o', this.openPiskel.bind(this)); + pskl.app.shortcutService.addShortcut('ctrl+s', this.save.bind(this)); + pskl.app.shortcutService.addShortcut('ctrl+shift+s', this.savePiskelAs.bind(this)); + } + }; + + ns.DesktopStorageService.prototype.save = function () { + var savePath = this.piskelController.getSavePath(); + // if we already have a filename, just save the file (using nodejs 'fs' api) + if (savePath) { + this.savePiskel(savePath); + } else { + this.savePiskelAs(savePath); + } + }; + + ns.DesktopStorageService.prototype.savePiskel = function (savePath) { + var serialized = this.piskelController.serialize(); + pskl.utils.FileUtilsDesktop.saveToFile(serialized, savePath, function () { + this.onSaveSuccess_(); + }.bind(this)); + }; + + ns.DesktopStorageService.prototype.openPiskel = function () { + pskl.utils.FileUtilsDesktop.chooseFileDialog(function(filename){ + var chosenFilename = filename; + pskl.utils.FileUtilsDesktop.readFile(chosenFilename, function(content){ + pskl.utils.PiskelFileUtils.decodePiskelFile(content, function (piskel, descriptor, fps) { + piskel.setDescriptor(descriptor); + // store save path so we can re-save without opening the save dialog + piskel.savePath = chosenFilename; + pskl.app.piskelController.setPiskel(piskel); + pskl.app.animationController.setFPS(fps); + }); + }); + }); + }; + + ns.DesktopStorageService.prototype.savePiskelAs = function (savePath) { + var serialized = this.piskelController.serialize(); + // TODO: if there is already a file path, use it for the dialog's + // working directory and filename + pskl.utils.FileUtilsDesktop.saveAs(serialized, null, 'piskel', function (selectedSavePath) { + this.onSaveSuccess_(); + this.piskelController.setSavePath(selectedSavePath); + }.bind(this)); + } + + ns.DesktopStorageService.prototype.onSaveSuccess_ = function () { + $.publish(Events.CLOSE_SETTINGS_DRAWER); + $.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]); + $.publish(Events.PISKEL_SAVED); + // clear the old time out, if any. + window.clearTimeout(this.hideNotificationTimeoutID); + this.hideNotificationTimeoutID = + window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000); + }; + +})(); diff --git a/src/js/utils/FileUtilsDesktop.js b/src/js/utils/FileUtilsDesktop.js index 298ca37f..2f596e74 100644 --- a/src/js/utils/FileUtilsDesktop.js +++ b/src/js/utils/FileUtilsDesktop.js @@ -20,10 +20,13 @@ /** * * @param content - * @param defaultFileName + * @param defaultFileName - file name to pre-populate the dialog + * @param extension - if supplied, the selected extension will guaranteed to be on the filename - + * NOTE: there is a possible danger here... If the extension is added to a fileName, but there + * is already another file of the same name *with* the extension, it will get overwritten. * @param callback */ - saveAs: function (content, defaultFileName, callback) { + saveAs: function (content, defaultFileName, extension, callback) { // NodeWebkit has no js api for opening the save dialog. // Instead, it adds two new attributes to the anchor tag: nwdirectory and nwsaveas // (see: https://github.com/nwjs/nw.js/wiki/File-dialogs ) @@ -31,7 +34,16 @@ var tagString = ''; var $chooser = $(tagString); $chooser.change(function(e) { - var filename = $(this).val(); + var filename = $(this).val(); + if (typeof extension == 'string') { + if (extension[0] !== '.') { + extension = "." + extension; + } + var hasExtension = (filename.substring(filename.length - extension.length) === extension); + if (!hasExtension) { + filename += extension; + } + } pskl.utils.FileUtilsDesktop.saveToFile(content, filename, function(){ callback(filename); }); diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index 4fed59c7..cb069e6c 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -127,6 +127,7 @@ "js/service/LocalStorageService.js", "js/service/GithubStorageService.js", "js/service/AppEngineStorageService.js", + "js/service/DesktopStorageService.js", "js/service/BackupService.js", "js/service/BeforeUnloadService.js", "js/service/HistoryService.js",