put json file stuff in files.js

In the same way than image files.
This commit is contained in:
abakkk 2020-08-05 02:00:20 +02:00
parent e686f03082
commit 11b90ecc0a
3 changed files with 109 additions and 70 deletions

75
area.js
View File

@ -20,7 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
const ByteArray = imports.byteArray;
const Cairo = imports.cairo; const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
@ -57,43 +56,6 @@ var ToolNames = Object.assign({}, ShapeNames, ManipulationNames);
var FontGenericNames = { 0: 'Theme', 1: 'Sans-Serif', 2: 'Serif', 3: 'Monospace', 4: 'Cursive', 5: 'Fantasy' }; var FontGenericNames = { 0: 'Theme', 1: 'Sans-Serif', 2: 'Serif', 3: 'Monospace', 4: 'Cursive', 5: 'Fantasy' };
var getDateString = function() {
let date = GLib.DateTime.new_now_local();
return `${date.format("%F")} ${date.format("%X")}`;
};
var getJsonFiles = function() {
let directory = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir']]));
let enumerator;
try {
enumerator = directory.enumerate_children('standard::name,standard::display-name,standard::content-type,time::modified', Gio.FileQueryInfoFlags.NONE, null);
} catch(e) {
return [];
}
let jsonFiles = [];
let fileInfo = enumerator.next_file(null);
while (fileInfo) {
if (fileInfo.get_content_type().indexOf('json') != -1 && fileInfo.get_name() != `${Me.metadata['persistent-file-name']}.json`) {
let file = enumerator.get_child(fileInfo);
jsonFiles.push({ name: fileInfo.get_name().slice(0, -5),
displayName: fileInfo.get_display_name().slice(0, -5),
// fileInfo.get_modification_date_time: Gio 2.62+
modificationUnixTime: fileInfo.get_attribute_uint64('time::modified'),
delete: () => file.delete(null) });
}
fileInfo = enumerator.next_file(null);
}
enumerator.close(null);
jsonFiles.sort((a, b) => {
return b.modificationUnixTime - a.modificationUnixTime;
});
return jsonFiles;
};
// DrawingArea is the widget in which we draw, thanks to Cairo. // DrawingArea is the widget in which we draw, thanks to Cairo.
// It creates and manages a DrawingElement for each "brushstroke". // It creates and manages a DrawingElement for each "brushstroke".
// It handles pointer/mouse/(touch?) events and some keyboard events. // It handles pointer/mouse/(touch?) events and some keyboard events.
@ -1092,7 +1054,7 @@ var DrawingArea = new Lang.Class({
} }
content += "\n</svg>"; content += "\n</svg>";
let filename = `${Me.metadata['svg-file-name']} ${getDateString()}.svg`; let filename = `${Me.metadata['svg-file-name']} ${Files.getDateString()}.svg`;
let dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES); let dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES);
let path = GLib.build_filenamev([dir, filename]); let path = GLib.build_filenamev([dir, filename]);
if (GLib.file_test(path, GLib.FileTest.EXISTS)) if (GLib.file_test(path, GLib.FileTest.EXISTS))
@ -1120,34 +1082,25 @@ var DrawingArea = new Lang.Class({
this._stopDrawing(); this._stopDrawing();
} }
let dir = GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir']]); let json = new Files.Json({ name });
if (!GLib.file_test(dir, GLib.FileTest.EXISTS))
GLib.mkdir_with_parents(dir, 0o700);
let path = GLib.build_filenamev([dir, `${name}.json`]);
let oldContents; let oldContents;
if (name == Me.metadata['persistent-file-name']) { if (name == Me.metadata['persistent-file-name']) {
if (GLib.file_test(path, GLib.FileTest.EXISTS)) { let oldContents = json.contents;
oldContents = GLib.file_get_contents(path)[1];
if (oldContents instanceof Uint8Array)
oldContents = ByteArray.toString(oldContents);
}
// do not create a file to write just an empty array // do not create a file to write just an empty array
if (!oldContents && this.elements.length == 0) if (!oldContents && this.elements.length == 0)
return; return;
} }
// do not use "content = JSON.stringify(this.elements, null, 2);", neither "content = JSON.stringify(this.elements);" // do not use "content = JSON.stringify(this.elements, null, 2);", neither "content = JSON.stringify(this.elements);"
// because of compromise between disk usage and human readability // do compromise between disk usage and human readability
let contents = `[\n ` + new Array(...this.elements.map(element => JSON.stringify(element))).join(`,\n\n `) + `\n]`; let contents = `[\n ` + new Array(...this.elements.map(element => JSON.stringify(element))).join(`,\n\n `) + `\n]`;
if (name == Me.metadata['persistent-file-name'] && contents == oldContents) if (name == Me.metadata['persistent-file-name'] && contents == oldContents)
return; return;
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
GLib.file_set_contents(path, contents); json.contents = contents;
if (notify) if (notify)
this.emit('show-osd', 'document-save-symbolic', name, "", -1, false); this.emit('show-osd', 'document-save-symbolic', name, "", -1, false);
if (name != Me.metadata['persistent-file-name']) { if (name != Me.metadata['persistent-file-name']) {
@ -1162,7 +1115,7 @@ var DrawingArea = new Lang.Class({
}, },
saveAsJson: function() { saveAsJson: function() {
this._saveAsJson(getDateString(), true); this._saveAsJson(Files.getDateString(), true);
}, },
savePersistent: function() { savePersistent: function() {
@ -1188,16 +1141,10 @@ var DrawingArea = new Lang.Class({
this.elements = []; this.elements = [];
this.currentElement = null; this.currentElement = null;
let dir = GLib.get_user_data_dir(); let contents = (new Files.Json({ name })).contents;
let path = GLib.build_filenamev([dir, Me.metadata['data-dir'], `${name}.json`]); if (!contents)
return;
if (!GLib.file_test(path, GLib.FileTest.EXISTS))
return;
let [success, contents] = GLib.file_get_contents(path);
if (!success)
return;
if (contents instanceof Uint8Array)
contents = ByteArray.toString(contents);
this.elements.push(...JSON.parse(contents).map(object => { this.elements.push(...JSON.parse(contents).map(object => {
if (object.image) if (object.image)
object.image = new Files.Image(object.image); object.image = new Files.Image(object.image);
@ -1222,7 +1169,7 @@ var DrawingArea = new Lang.Class({
}, },
loadNextJson: function() { loadNextJson: function() {
let names = getJsonFiles().map(file => file.name); let names = Files.getJsons().map(json => json.name);
if (!names.length) if (!names.length)
return; return;
@ -1232,7 +1179,7 @@ var DrawingArea = new Lang.Class({
}, },
loadPreviousJson: function() { loadPreviousJson: function() {
let names = getJsonFiles().map(file => file.name); let names = Files.getJsons().map(json => json.name);
if (!names.length) if (!names.length)
return; return;

View File

@ -20,6 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
const ByteArray = imports.byteArray;
const Gdk = imports.gi.Gdk; const Gdk = imports.gi.Gdk;
const GdkPixbuf = imports.gi.GdkPixbuf; const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
@ -31,6 +32,7 @@ const Me = ExtensionUtils.getCurrentExtension();
const EXAMPLE_IMAGES = Me.dir.get_child('data').get_child('images'); const EXAMPLE_IMAGES = Me.dir.get_child('data').get_child('images');
const USER_IMAGES = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], 'images'])); const USER_IMAGES = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], 'images']));
// wrapper around an image file
var Image = new Lang.Class({ var Image = new Lang.Class({
Name: 'DrawOnYourScreenImage', Name: 'DrawOnYourScreenImage',
@ -130,3 +132,92 @@ var getImages = function() {
return images; return images;
}; };
// wrapper around a json file
var Json = new Lang.Class({
Name: 'DrawOnYourScreenJson',
_init: function(params) {
for (let key in params)
this[key] = params[key];
},
toString: function() {
return this.displayName || this.name;
},
delete: function() {
this.file.delete(null);
},
get file() {
if (!this._file && this.name)
this._file = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], `${this.name}.json`]));
return this._file || null;
},
set file(file) {
this._file = file;
},
get contents() {
let success_, contents;
try {
[success_, contents] = this.file.load_contents(null);
if (contents instanceof Uint8Array)
contents = ByteArray.toString(contents);
} catch(e) {
return null;
}
return contents;
},
set contents(contents) {
try {
this.file.replace_contents(contents, null, false, Gio.FileCreateFlags.NONE, null);
} catch(e) {
this.file.get_parent().make_directory_with_parents(null);
this.file.replace_contents(contents, null, false, Gio.FileCreateFlags.NONE, null);
}
}
});
var getJsons = function() {
let directory = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir']]));
let enumerator;
try {
enumerator = directory.enumerate_children('standard::name,standard::display-name,standard::content-type,time::modified', Gio.FileQueryInfoFlags.NONE, null);
} catch(e) {
return [];
}
let jsons = [];
let fileInfo = enumerator.next_file(null);
while (fileInfo) {
if (fileInfo.get_content_type().indexOf('json') != -1 && fileInfo.get_name() != `${Me.metadata['persistent-file-name']}.json`) {
let file = enumerator.get_child(fileInfo);
jsons.push(new Json({
file,
name: fileInfo.get_name().slice(0, -5),
displayName: fileInfo.get_display_name().slice(0, -5),
// fileInfo.get_modification_date_time: Gio 2.62+
modificationUnixTime: fileInfo.get_attribute_uint64('time::modified')
}));
}
fileInfo = enumerator.next_file(null);
}
enumerator.close(null);
jsons.sort((a, b) => {
return b.modificationUnixTime - a.modificationUnixTime;
});
return jsons;
};
var getDateString = function() {
let date = GLib.DateTime.new_now_local();
return `${date.format("%F")} ${date.format("%X")}`;
};

13
menu.js
View File

@ -39,6 +39,7 @@ const Me = ExtensionUtils.getCurrentExtension();
const Area = Me.imports.area; const Area = Me.imports.area;
const Elements = Me.imports.elements; const Elements = Me.imports.elements;
const Extension = Me.imports.extension; const Extension = Me.imports.extension;
const Files = Me.imports.files;
const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext; const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
const GS_VERSION = Config.PACKAGE_VERSION; const GS_VERSION = Config.PACKAGE_VERSION;
@ -438,10 +439,10 @@ var DrawingMenu = new Lang.Class({
_populateOpenDrawingSubMenu: function() { _populateOpenDrawingSubMenu: function() {
this.openDrawingSubMenu.removeAll(); this.openDrawingSubMenu.removeAll();
let jsonFiles = Area.getJsonFiles(); let jsons = Files.getJsons();
jsonFiles.forEach(file => { jsons.forEach(json => {
let item = this.openDrawingSubMenu.addAction(`<i>${file.displayName}</i>`, () => { let item = this.openDrawingSubMenu.addAction(`<i>${String(json)}</i>`, () => {
this.area.loadJson(file.name); this.area.loadJson(json.name);
this._updateDrawingNameMenuItem(); this._updateDrawingNameMenuItem();
this._updateSaveDrawingSubMenuItemSensitivity(); this._updateSaveDrawingSubMenuItemSensitivity();
}); });
@ -460,7 +461,7 @@ var DrawingMenu = new Lang.Class({
getActor(item).add_child(deleteButton); getActor(item).add_child(deleteButton);
deleteButton.connect('clicked', () => { deleteButton.connect('clicked', () => {
file.delete(); json.delete();
item.destroy(); item.destroy();
}); });
}); });
@ -494,7 +495,7 @@ var DrawingMenu = new Lang.Class({
_populateSaveDrawingSubMenu: function() { _populateSaveDrawingSubMenu: function() {
this.saveDrawingSubMenu.removeAll(); this.saveDrawingSubMenu.removeAll();
let saveEntry = new DrawingMenuEntry({ initialTextGetter: Area.getDateString, let saveEntry = new DrawingMenuEntry({ initialTextGetter: Files.getDateString,
entryActivateCallback: (text) => { entryActivateCallback: (text) => {
this.area.saveAsJsonWithName(text); this.area.saveAsJsonWithName(text);
this.saveDrawingSubMenu.toggle(); this.saveDrawingSubMenu.toggle();