Skip to content

Commit

Permalink
Allow saving images
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucki committed Dec 12, 2022
1 parent 52567bc commit 4cc140e
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 47 deletions.
3 changes: 1 addition & 2 deletions [email protected]/adapter/baseAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
3 changes: 1 addition & 2 deletions [email protected]/adapter/localFolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 43 additions & 11 deletions [email protected]/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

/*
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion [email protected]/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -152,4 +153,4 @@ var HistoryController = class {
}
}

};
};
53 changes: 44 additions & 9 deletions [email protected]/prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -91,6 +87,7 @@ var RandomWallpaperSettings = class {
Gio.SettingsBindFlags.DEFAULT);

this._bindButtons();
this._bindHistorySection(window);

window.connect('close-request', () => {
this._saveSources();
Expand Down Expand Up @@ -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);
});
Expand All @@ -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();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@
<description>A mapping with available configured wallpaper sources as stringified JSON.</description>
</key>

<key type='s' name='favorites-folder'>
<default>""</default>
<summary>Favorites Folder</summary>
<description>Saved images will land in this folder.</description>
</key>

</schema>

<schema path="/org/gnome/shell/extensions/space-iflow-randomwallpaper/backend-connection/"
Expand Down
2 changes: 1 addition & 1 deletion [email protected]/ui/localFolder.blp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ template LocalFolderSettingsGroup : Adw.PreferencesGroup {
valign: center;

Adw.ButtonContent {
icon-name: "document-open-symbolic";
icon-name: "folder-open-symbolic";
}
}
}
Expand Down
48 changes: 30 additions & 18 deletions [email protected]/ui/pageGeneral.blp
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,6 @@ Adw.PreferencesPage page_general {
Adw.PreferencesGroup {
title: _("History");

Adw.ActionRow {
title: _("History length");
subtitle: _("The number of wallpapers that will be shown in the history and stored in the wallpaper folder of this extension.");

SpinButton {
valign: center;
numeric: true;

adjustment: Adjustment history_length {
lower: 1;
upper: 100;
value: 10;
step-increment: 1;
page-increment: 10;
};
}
}

header-suffix: Box {
spacing: 14;

Expand All @@ -100,6 +82,36 @@ Adw.PreferencesPage page_general {
]
}
};

Adw.ActionRow {
title: _("History length");
subtitle: _("The number of wallpapers that will be shown in the history and stored in the wallpaper folder of this extension.");

SpinButton {
valign: center;
numeric: true;

adjustment: Adjustment history_length {
lower: 1;
upper: 100;
value: 10;
step-increment: 1;
page-increment: 10;
};
}
}

Adw.EntryRow row_favorites_folder{
title: _("Save for later folder");

Button button_favorites_folder {
valign: center;

Adw.ButtonContent {
icon-name: "folder-open-symbolic";
}
}
}
}

Adw.PreferencesGroup {
Expand Down
50 changes: 47 additions & 3 deletions [email protected]/wallpaperController.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,31 @@ var WallpaperController = class {
}

this.currentWallpaper = this._getCurrentWallpaper();

// Initialize favorites folder
// TODO: There's probably a better place for this
let favoritesFolder = this._settings.get('favorites-folder', 'string');
if (favoritesFolder === "") {
const directoryPictures = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES);

if (directoryPictures === null) {
// Pictures not set up
const directoryDownloads = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD);

if (directoryDownloads === null) {
const xdg_data_home = GLib.get_user_data_dir();
favoritesFolder = Gio.File.new_for_path(xdg_data_home);
} else {
favoritesFolder = Gio.File.new_for_path(directoryDownloads);
}
} else {
favoritesFolder = Gio.File.new_for_path(directoryPictures);
}

favoritesFolder = favoritesFolder.get_child(Self.metadata['uuid']);

this._settings.set('favorites-folder', 'string', favoritesFolder.get_path());
}
}

_clearHistory() {
Expand Down Expand Up @@ -313,10 +338,29 @@ var WallpaperController = class {
return;
}

historyElement.path = path;
historyElement.id = historyId;
historyElement.name = String(historyId);
historyElement.id = `${historyElement.timestamp}_${historyElement.name}`; // timestamp ensures uniqueness

// Move file to unique naming
let sourceFile = Gio.File.new_for_path(path);
let targetFolder = sourceFile.get_parent();
let targetFile = targetFolder.get_child(historyElement.id);

try {
if (!sourceFile.move(targetFile, Gio.FileCopyFlags.NONE, null, null)) {
this.logger.warning('Failed copying unique image.');
return;
}
} catch (error) {
if (error === Gio.IOErrorEnum.EXISTS) {
this.logger.warning('Image already exists in location.');
return;
}
}

historyElement.path = targetFile.get_path();

this._setBackground(path, () => {
this._setBackground(historyElement.path, () => {
// insert file into history
this._historyController.insert(historyElement);
this.currentWallpaper = this._getCurrentWallpaper();
Expand Down

0 comments on commit 4cc140e

Please sign in to comment.