diff --git a/randomwallpaper@iflow.space/adapter/baseAdapter.js b/randomwallpaper@iflow.space/adapter/baseAdapter.js index 388c1ba3..7b0e69b6 100755 --- a/randomwallpaper@iflow.space/adapter/baseAdapter.js +++ b/randomwallpaper@iflow.space/adapter/baseAdapter.js @@ -48,8 +48,7 @@ var BaseAdapter = class { */ fetchFile(uri, callback) { //extract the name from the url and - let date = new Date(); - let name = date.getTime() + '_' + this.fileName(uri); // timestamp ensures uniqueness + let name = this.fileName(uri); let bowl = new SoupBowl.Bowl(); diff --git a/randomwallpaper@iflow.space/adapter/localFolder.js b/randomwallpaper@iflow.space/adapter/localFolder.js index 1a45bf44..f9b2585e 100644 --- a/randomwallpaper@iflow.space/adapter/localFolder.js +++ b/randomwallpaper@iflow.space/adapter/localFolder.js @@ -39,9 +39,8 @@ var LocalFolderAdapter = class extends BaseAdapter.BaseAdapter { } fetchFile(path, callback) { - let date = new Date(); let sourceFile = Gio.file_new_for_path(path); - let name = `${date.getTime()}_${sourceFile.get_basename()}` + let name = sourceFile.get_basename() let targetFile = Gio.file_new_for_path(this._wallpaperLocation + String(name)); // https://gjs.guide/guides/gio/file-operations.html#copying-and-moving-files diff --git a/randomwallpaper@iflow.space/elements.js b/randomwallpaper@iflow.space/elements.js index def35358..d150096a 100644 --- a/randomwallpaper@iflow.space/elements.js +++ b/randomwallpaper@iflow.space/elements.js @@ -4,23 +4,26 @@ const Util = imports.misc.util; const GdkPixbuf = imports.gi.GdkPixbuf; const Clutter = imports.gi.Clutter; const Cogl = imports.gi.Cogl; +const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; const GObject = imports.gi.GObject; const Self = imports.misc.extensionUtils.getCurrentExtension(); +const Settings = Self.imports.settings; const LoggerModule = Self.imports.logger; const Timer = Self.imports.timer; var HistoryElement = GObject.registerClass({ - GTypeName: 'HistoryElement', - }, class HistoryElement extends PopupMenu.PopupSubMenuMenuItem { - _init(historyEntry, index) { + GTypeName: 'HistoryElement', +}, class HistoryElement extends PopupMenu.PopupSubMenuMenuItem { + _init(historyEntry, index) { super._init("", false); this.logger = new LoggerModule.Logger('RWG3', 'HistoryElement'); this.historyEntry = null; this.setAsWallpaperItem = null; this.previewItem = null; this._previewActor = null; + this._settings = new Settings.Settings(); let timestamp = historyEntry.timestamp; let date = new Date(timestamp); @@ -97,17 +100,46 @@ var HistoryElement = GObject.registerClass({ this.menu.addMenuItem(new PopupMenu.PopupMenuItem('Unknown source.')); } + this.copyToFavorites = new PopupMenu.PopupMenuItem('Save for later'); + this.copyToFavorites.connect('activate', () => { + let sourceFile = Gio.File.new_for_path(this.historyEntry.path); + let targetFolder = Gio.File.new_for_path(this._settings.get('favorites-folder', 'string')); + let targetFile = targetFolder.get_child(historyEntry.name); + + try { + if (!targetFolder.make_directory_with_parents(null)) { + this.logger.warning('Could not create directories.'); + return; + } + } catch (error) { + if (error === Gio.IOErrorEnum.EXISTS) { } + } + + try { + if (!sourceFile.copy(targetFile, Gio.FileCopyFlags.NONE, null, null)) { + this.logger.warning('Failed copying image.'); + return; + } + } catch (error) { + if (error === Gio.IOErrorEnum.EXISTS) { + this.logger.warning('Image already exists in location.'); + return; + } + } + }); + this.menu.addMenuItem(this.copyToFavorites); + this.setAsWallpaperItem = new PopupMenu.PopupMenuItem('Set As Wallpaper'); this.setAsWallpaperItem.connect('activate', () => { this.emit('activate', null); // Fixme: not sure what the second parameter should be. null seems to work fine for now. }); if (index !== 0) { - this.menu.addMenuItem(new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false})); // theme independent spacing + this.menu.addMenuItem(new PopupMenu.PopupBaseMenuItem({ can_focus: false, reactive: false })); // theme independent spacing this.menu.addMenuItem(this.setAsWallpaperItem); } - this.previewItem = new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false}); + this.previewItem = new PopupMenu.PopupBaseMenuItem({ can_focus: false, reactive: false }); this.menu.addMenuItem(this.previewItem); /* @@ -133,7 +165,7 @@ var HistoryElement = GObject.registerClass({ height, pixbuf.get_rowstride() ); - this._previewActor = new Clutter.Actor({height: height, width: width}); + this._previewActor = new Clutter.Actor({ height: height, width: width }); this._previewActor.set_content(image); this.previewItem.actor.add_actor(this._previewActor); @@ -147,12 +179,12 @@ var HistoryElement = GObject.registerClass({ setIndex(index) { this.prefixLabel.set_text(String(index)); } - } +} ); var CurrentImageElement = GObject.registerClass({ - GTypeName: 'CurrentImageElement', - }, class CurrentImageElement extends HistoryElement { + GTypeName: 'CurrentImageElement', +}, class CurrentImageElement extends HistoryElement { _init(historyElement) { super._init(historyElement, 0); @@ -170,8 +202,8 @@ var CurrentImageElement = GObject.registerClass({ * The remaining time will only be displayed if the af-feature is activated. */ var NewWallpaperElement = GObject.registerClass({ - GTypeName: 'NewWallpaperElement', - }, class NewWallpaperElement extends PopupMenu.PopupBaseMenuItem { + GTypeName: 'NewWallpaperElement', +}, class NewWallpaperElement extends PopupMenu.PopupBaseMenuItem { _init(params) { super._init(params); diff --git a/randomwallpaper@iflow.space/history.js b/randomwallpaper@iflow.space/history.js index 9aaa73ed..58a656ea 100644 --- a/randomwallpaper@iflow.space/history.js +++ b/randomwallpaper@iflow.space/history.js @@ -10,6 +10,7 @@ var HistoryEntry = class { constructor(author, source, url) { this.id = null; + this.name = null; this.path = null; this.source = null; this.timestamp = new Date().getTime(); @@ -152,4 +153,4 @@ var HistoryController = class { } } -}; \ No newline at end of file +}; diff --git a/randomwallpaper@iflow.space/prefs.js b/randomwallpaper@iflow.space/prefs.js index dbe05fc6..b3c67957 100644 --- a/randomwallpaper@iflow.space/prefs.js +++ b/randomwallpaper@iflow.space/prefs.js @@ -57,10 +57,6 @@ var RandomWallpaperSettings = class { this._loadSources(); - this._settings.bind('history-length', - this._builder.get_object('history_length'), - 'value', - Gio.SettingsBindFlags.DEFAULT); this._settings.bind('minutes', this._builder.get_object('duration_minutes'), 'value', @@ -91,6 +87,7 @@ var RandomWallpaperSettings = class { Gio.SettingsBindFlags.DEFAULT); this._bindButtons(); + this._bindHistorySection(window); window.connect('close-request', () => { this._saveSources(); @@ -128,6 +125,28 @@ var RandomWallpaperSettings = class { this._backendConnection.set('request-new-wallpaper', 'boolean', true); }); + this._builder.get_object('button_new_source').connect('clicked', () => { + let source_row = new SourceRow.SourceRow(); + this.available_rows[source_row.id] = source_row; + this._builder.get_object('sources_list').add(source_row); + + this._bindSourceRow(source_row); + }); + } + + _bindHistorySection(window) { + let entryRow = this._builder.get_object('row_favorites_folder'); + entryRow.text = this._settings.get_string('favorites-folder'); + + this._settings.bind('history-length', + this._builder.get_object('history_length'), + 'value', + Gio.SettingsBindFlags.DEFAULT); + this._settings.bind('favorites-folder', + entryRow, + 'text', + Gio.SettingsBindFlags.DEFAULT); + this._builder.get_object('clear_history').connect('clicked', () => { this._backendConnection.set('clear-history', 'boolean', true); }); @@ -136,12 +155,28 @@ var RandomWallpaperSettings = class { this._backendConnection.set('open-folder', 'boolean', true); }); - this._builder.get_object('button_new_source').connect('clicked', () => { - let source_row = new SourceRow.SourceRow(); - this.available_rows[source_row.id] = source_row; - this._builder.get_object('sources_list').add(source_row); + this._builder.get_object('button_favorites_folder').connect('clicked', () => { + // For GTK 4.10+ + // Gtk.FileDialog(); + + // https://stackoverflow.com/a/54487948 + this._saveDialog = new Gtk.FileChooserNative({ + title: 'Choose a Wallpaper Folder', + action: Gtk.FileChooserAction.SELECT_FOLDER, + accept_label: 'Open', + cancel_label: 'Cancel', + transient_for: window, + modal: true, + }); - this._bindSourceRow(source_row); + this._saveDialog.connect('response', (dialog, response_id) => { + if (response_id === Gtk.ResponseType.ACCEPT) { + entryRow.text = this._saveDialog.get_file().get_path(); + } + this._saveDialog.destroy(); + }); + + this._saveDialog.show(); }); } diff --git a/randomwallpaper@iflow.space/schemas/org.gnome.shell.extensions.space.iflow.randomwallpaper.gschema.xml b/randomwallpaper@iflow.space/schemas/org.gnome.shell.extensions.space.iflow.randomwallpaper.gschema.xml index a6f81715..b1e3011d 100644 --- a/randomwallpaper@iflow.space/schemas/org.gnome.shell.extensions.space.iflow.randomwallpaper.gschema.xml +++ b/randomwallpaper@iflow.space/schemas/org.gnome.shell.extensions.space.iflow.randomwallpaper.gschema.xml @@ -80,6 +80,12 @@ A mapping with available configured wallpaper sources as stringified JSON. + + "" + Favorites Folder + Saved images will land in this folder. + + { + this._setBackground(historyElement.path, () => { // insert file into history this._historyController.insert(historyElement); this.currentWallpaper = this._getCurrentWallpaper();