diff --git a/area.js b/area.js
index 0a65586..0b3ad26 100644
--- a/area.js
+++ b/area.js
@@ -20,7 +20,6 @@
* along with this program. If not, see .
*/
-const ByteArray = imports.byteArray;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
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 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.
// It creates and manages a DrawingElement for each "brushstroke".
// It handles pointer/mouse/(touch?) events and some keyboard events.
@@ -1092,7 +1054,7 @@ var DrawingArea = new Lang.Class({
}
content += "\n";
- 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 path = GLib.build_filenamev([dir, filename]);
if (GLib.file_test(path, GLib.FileTest.EXISTS))
@@ -1120,34 +1082,25 @@ var DrawingArea = new Lang.Class({
this._stopDrawing();
}
- let dir = GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir']]);
- if (!GLib.file_test(dir, GLib.FileTest.EXISTS))
- GLib.mkdir_with_parents(dir, 0o700);
- let path = GLib.build_filenamev([dir, `${name}.json`]);
-
+ let json = new Files.Json({ name });
let oldContents;
if (name == Me.metadata['persistent-file-name']) {
- if (GLib.file_test(path, GLib.FileTest.EXISTS)) {
- oldContents = GLib.file_get_contents(path)[1];
- if (oldContents instanceof Uint8Array)
- oldContents = ByteArray.toString(oldContents);
- }
-
+ let oldContents = json.contents;
// do not create a file to write just an empty array
if (!oldContents && this.elements.length == 0)
return;
}
// 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]`;
if (name == Me.metadata['persistent-file-name'] && contents == oldContents)
return;
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
- GLib.file_set_contents(path, contents);
+ json.contents = contents;
if (notify)
this.emit('show-osd', 'document-save-symbolic', name, "", -1, false);
if (name != Me.metadata['persistent-file-name']) {
@@ -1162,7 +1115,7 @@ var DrawingArea = new Lang.Class({
},
saveAsJson: function() {
- this._saveAsJson(getDateString(), true);
+ this._saveAsJson(Files.getDateString(), true);
},
savePersistent: function() {
@@ -1188,16 +1141,10 @@ var DrawingArea = new Lang.Class({
this.elements = [];
this.currentElement = null;
- let dir = GLib.get_user_data_dir();
- let path = GLib.build_filenamev([dir, Me.metadata['data-dir'], `${name}.json`]);
+ let contents = (new Files.Json({ name })).contents;
+ 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 => {
if (object.image)
object.image = new Files.Image(object.image);
@@ -1222,7 +1169,7 @@ var DrawingArea = new Lang.Class({
},
loadNextJson: function() {
- let names = getJsonFiles().map(file => file.name);
+ let names = Files.getJsons().map(json => json.name);
if (!names.length)
return;
@@ -1232,7 +1179,7 @@ var DrawingArea = new Lang.Class({
},
loadPreviousJson: function() {
- let names = getJsonFiles().map(file => file.name);
+ let names = Files.getJsons().map(json => json.name);
if (!names.length)
return;
diff --git a/files.js b/files.js
index ec55aa7..c7bef27 100644
--- a/files.js
+++ b/files.js
@@ -20,6 +20,7 @@
* along with this program. If not, see .
*/
+const ByteArray = imports.byteArray;
const Gdk = imports.gi.Gdk;
const GdkPixbuf = imports.gi.GdkPixbuf;
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 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({
Name: 'DrawOnYourScreenImage',
@@ -130,3 +132,92 @@ var getImages = function() {
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")}`;
+};
diff --git a/menu.js b/menu.js
index a8ccba0..0a09f03 100644
--- a/menu.js
+++ b/menu.js
@@ -39,6 +39,7 @@ const Me = ExtensionUtils.getCurrentExtension();
const Area = Me.imports.area;
const Elements = Me.imports.elements;
const Extension = Me.imports.extension;
+const Files = Me.imports.files;
const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
const GS_VERSION = Config.PACKAGE_VERSION;
@@ -438,10 +439,10 @@ var DrawingMenu = new Lang.Class({
_populateOpenDrawingSubMenu: function() {
this.openDrawingSubMenu.removeAll();
- let jsonFiles = Area.getJsonFiles();
- jsonFiles.forEach(file => {
- let item = this.openDrawingSubMenu.addAction(`${file.displayName}`, () => {
- this.area.loadJson(file.name);
+ let jsons = Files.getJsons();
+ jsons.forEach(json => {
+ let item = this.openDrawingSubMenu.addAction(`${String(json)}`, () => {
+ this.area.loadJson(json.name);
this._updateDrawingNameMenuItem();
this._updateSaveDrawingSubMenuItemSensitivity();
});
@@ -460,7 +461,7 @@ var DrawingMenu = new Lang.Class({
getActor(item).add_child(deleteButton);
deleteButton.connect('clicked', () => {
- file.delete();
+ json.delete();
item.destroy();
});
});
@@ -494,7 +495,7 @@ var DrawingMenu = new Lang.Class({
_populateSaveDrawingSubMenu: function() {
this.saveDrawingSubMenu.removeAll();
- let saveEntry = new DrawingMenuEntry({ initialTextGetter: Area.getDateString,
+ let saveEntry = new DrawingMenuEntry({ initialTextGetter: Files.getDateString,
entryActivateCallback: (text) => {
this.area.saveAsJsonWithName(text);
this.saveDrawingSubMenu.toggle();