Skip to content

Commit 592faba

Browse files
authored
Merge pull request #351 from evolus/development
PR for 3.0.4
2 parents 8e0f210 + fc16c86 commit 592faba

File tree

12 files changed

+275
-100
lines changed

12 files changed

+275
-100
lines changed

app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "Pencil",
33
"productName": "Pencil",
44
"description": "An open-source GUI prototyping tool that is available for ALL platforms.",
5-
"version": "3.0.3",
5+
"version": "3.0.4",
66
"author": {
77
"name": "Evolus",
88
"url": "http://evolus.vn",

app/pencil-core/common/EpgzHandler.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ EpgzHandler.prototype.loadDocument = function(filePath) {
1515
var thiz = this;
1616
return new Promise(function (resolve, reject) {
1717

18+
var wrappedRejectCalled = false;
1819
var wrappedReject = function (error) {
20+
if (wrappedRejectCalled) return;
21+
wrappedRejectCalled = true;
22+
console.log(error);
1923
var recoverable = fs.existsSync(path.join(Pencil.documentHandler.tempDir.name, "content.xml"));
2024
if (!recoverable) {
2125
reject(error);
@@ -38,7 +42,7 @@ EpgzHandler.prototype.loadDocument = function(filePath) {
3842
fs.createReadStream(filePath)
3943
.pipe(zlib.Gunzip())
4044
.on("error", wrappedReject)
41-
.pipe(tarfs.extract(Pencil.documentHandler.tempDir.name)
45+
.pipe(tarfs.extract(Pencil.documentHandler.tempDir.name, {readable: true, writable: true})
4246
.on("error", wrappedReject)
4347
.on("finish", function() {
4448
console.log("Successfully extracted.");

app/pencil-core/common/FileHandler.js

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,21 @@ FileHandler.prototype.parseDocument = function (filePath, callback) {
2525
thiz.controller.doc.properties[propNode.getAttribute("name")] = value;
2626
});
2727
Dom.workOn("./p:Pages/p:Page", dom.documentElement, function (pageNode) {
28-
var page = new Page(thiz.controller.doc);
28+
if (!pageNode) return;
2929
var pageFileName = pageNode.getAttribute("href");
30+
if (pageFileName == null) return;
31+
var pageFile = path.join(targetDir, pageFileName);
32+
if (!fs.existsSync(pageFile)) {
33+
return;
34+
}
35+
var page = new Page(thiz.controller.doc);
3036
page.pageFileName = pageFileName;
31-
page.tempFilePath = path.join(targetDir, pageFileName);
37+
page.tempFilePath = pageFile;
3238
thiz.controller.doc.pages.push(page);
3339
});
3440

3541
thiz.controller.doc.pages.forEach(function (page) {
36-
var pageFile = path.join(targetDir, page.pageFileName);
37-
if (!fs.existsSync(pageFile)) {
38-
if (callback) callback(new Error(Util.getMessage("page.specification.is.not.found.in.the.archive")));
39-
return;
40-
}
41-
42+
var pageFile = page.tempFilePath;
4243
var dom = Controller.parser.parseFromString(fs.readFileSync(pageFile, "utf8"), "text/xml");
4344
Dom.workOn("./p:Properties/p:Property", dom.documentElement, function (propNode) {
4445
var propName = propNode.getAttribute("name");
@@ -77,6 +78,8 @@ FileHandler.prototype.parseDocument = function (filePath, callback) {
7778
if (fs.existsSync(thumbPath)) {
7879
page.thumbPath = thumbPath;
7980
page.thumbCreated = new Date();
81+
} else {
82+
thiz.controller.invalidateBitmapFilePath(page);
8083
}
8184
page.canvas = null;
8285
}, thiz);
@@ -86,11 +89,15 @@ FileHandler.prototype.parseDocument = function (filePath, callback) {
8689
page.backgroundPage = this.controller.findPageById(page.backgroundPageId);
8790
thiz.controller.invalidateBitmapFilePath(page);
8891
}
89-
9092
if (page.parentPageId) {
9193
var parentPage = this.controller.findPageById(page.parentPageId);
92-
page.parentPage = parentPage;
93-
parentPage.children.push(page);
94+
if (parentPage){
95+
page.parentPage = parentPage;
96+
parentPage.children.push(page);
97+
} else {
98+
console.log("Remove parent page due to does not exist --> " + page.parentPageId);
99+
delete page.parentPageId;
100+
}
94101
}
95102
}, thiz);
96103

@@ -102,10 +109,15 @@ FileHandler.prototype.parseDocument = function (filePath, callback) {
102109
FontLoader.instance.setDocumentRepoDir(path.join(targetDir, "fonts"));
103110
FontLoader.instance.loadFonts(function () {
104111
thiz.controller.sayControllerStatusChanged();
112+
var activePage = null;
105113
if (thiz.controller.doc.properties.activeId) {
106-
thiz.controller.activatePage(thiz.controller.findPageById(thiz.controller.doc.properties.activeId));
107-
} else {
108-
if (thiz.controller.doc.pages.length > 0) thiz.controller.activatePage(thiz.controller.doc.pages[0]);
114+
activePage = thiz.controller.findPageById(thiz.controller.doc.properties.activeId);
115+
}
116+
if (activePage == null && thiz.controller.doc.pages.length > 0) {
117+
activePage = thiz.controller.doc.pages[0];
118+
}
119+
if (activePage != null) {
120+
thiz.controller.activatePage(activePage);
109121
}
110122
thiz.controller.applicationPane.onDocumentChanged();
111123
thiz.modified = false;
@@ -114,7 +126,7 @@ FileHandler.prototype.parseDocument = function (filePath, callback) {
114126
Pencil.documentHandler.preDocument = filePath;
115127
} catch (e) {
116128
// Pencil.documentHandler.newDocument()
117-
console.error(e);
129+
console.log(e);
118130
Dialog.alert("Unexpected error while accessing file: " + path.basename(filePath), null, function() {
119131
(oldPencilDocument != null) ? Pencil.documentHandler.loadDocument(oldPencilDocument) : function() {
120132
Pencil.controller.confirmAndclose(function () {

app/pencil-core/common/FontLoader.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ FontRepository.SUPPORTED_VARIANTS["italic"] = {
262262
displayName: "Regular Italic"
263263
};
264264

265+
FontRepository.findVariantName = function (weight, style) {
266+
for (var variantName in FontRepository.SUPPORTED_VARIANTS) {
267+
var spec = FontRepository.SUPPORTED_VARIANTS[variantName];
268+
if (spec.weight == weight && spec.style == style) return variantName;
269+
}
270+
271+
return null;
272+
};
273+
265274
FontRepository.prototype.addFont = function (data) {
266275
if (!this.loaded) this.load();
267276
var font = {

app/pencil-core/definition/collectionManager.js

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -288,23 +288,37 @@ CollectionManager.extractCollection = function(file, callback) {
288288
var targetDir = path.join(CollectionManager.getUserStencilDirectory(), fileName);
289289
console.log("extracting to", targetDir);
290290

291-
var extractor = unzip.Extract({ path: targetDir });
292-
extractor.on("close", function () {
293-
if (callback) {
294-
callback(err);
291+
var admZip = require('adm-zip');
292+
293+
var zip = new admZip(filePath);
294+
zip.extractAllToAsync(targetDir, true, function (err) {
295+
if (err) {
296+
error(err);
297+
setTimeout(function() {
298+
CollectionManager.removeCollectionDir(targetDir);
299+
}, 10);
300+
} else {
301+
resolve(targetDir);
295302
}
296-
resolve(targetDir);
297303
});
298-
extractor.on("error", (err) => {
299-
console.log("extract error", err);
300-
error(err);
301304

302-
setTimeout(function() {
303-
CollectionManager.removeCollectionDir(targetDir);
304-
}, 10);
305-
});
306-
307-
fs.createReadStream(filePath).pipe(extractor);
305+
// var extractor = unzip.Extract({ path: targetDir });
306+
// extractor.on("close", function () {
307+
// if (callback) {
308+
// callback(err);
309+
// }
310+
// resolve(targetDir);
311+
// });
312+
// extractor.on("error", (err) => {
313+
// console.log("extract error", err);
314+
// error(err);
315+
316+
// setTimeout(function() {
317+
// CollectionManager.removeCollectionDir(targetDir);
318+
// }, 10);
319+
// });
320+
321+
// fs.createReadStream(filePath).pipe(extractor);
308322
});
309323
};
310324
CollectionManager.installCollectionFonts = function (collection) {
@@ -319,6 +333,7 @@ CollectionManager.installCollectionFonts = function (collection) {
319333
if (existingFont.source == collection.id) {
320334
FontLoader.instance.userRepo.removeFont(existingFont);
321335
} else {
336+
console.log("Skip installing: " + font.name);
322337
continue; //skip installing this font
323338
}
324339
}
@@ -344,6 +359,8 @@ CollectionManager.installCollectionFonts = function (collection) {
344359
fontData[variantName + "FilePath"] = filePath;
345360
}
346361

362+
console.log("Fontdata to install", fontData);
363+
347364
FontLoader.instance.installNewFont(fontData);
348365
installedFonts.push(fontData.fontName);
349366
}

app/pencil-core/definition/shapeDefCollectionParser.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,15 @@ ShapeDefCollectionParser.prototype.loadCustomLayout = function (installDirPath)
210210
});
211211
Dom.workOn("./p:Fonts/p:Font", shapeDefsNode, function (fontNode) {
212212
var font = {
213-
name: fontNode.getAttribute("name"),
214-
regular: fontNode.getAttribute("regular"),
215-
bold: fontNode.getAttribute("bold"),
216-
italic: fontNode.getAttribute("italic"),
217-
boldItalic: fontNode.getAttribute("boldItalic")
213+
name: fontNode.getAttribute("name")
218214
};
215+
216+
for (var variantName in FontRepository.SUPPORTED_VARIANTS) {
217+
var filePath = fontNode.getAttribute(variantName);
218+
if (filePath) font[variantName] = filePath;
219+
}
220+
221+
console.log("Font:", font);
219222
collection.fonts.push(font);
220223
});
221224

app/pencil-core/privateCollection/privateCollectionManager.js

Lines changed: 106 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -221,63 +221,122 @@ PrivateCollectionManager.installCollectionFromFile = function (file) {
221221
var targetDir = path.join(tempDir.name, fileName);
222222
console.log("targetPath:", targetDir);
223223

224-
var extractor = unzip.Extract({ path: targetDir });
225-
extractor.on("close", function () {
224+
var admZip = require('adm-zip');
226225

227-
//try loading the collection
228-
try {
229-
var definitionFile = path.join(targetDir, "Definition.xml");
230-
if (!fs.existsSync(definitionFile)) throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
226+
var zip = new admZip(filePath);
227+
zip.extractAllToAsync(targetDir, true, function (err) {
228+
if (err) {
229+
ApplicationPane._instance.unbusy();
230+
Dialog.error("Error installing collection.");
231+
tempDir.removeCallback();
232+
} else {
233+
//try loading the collection
234+
try {
235+
var definitionFile = path.join(targetDir, "Definition.xml");
236+
if (!fs.existsSync(definitionFile)) throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
231237

232-
var fileContents = fs.readFileSync(definitionFile, ShapeDefCollectionParser.CHARSET);
238+
var fileContents = fs.readFileSync(definitionFile, ShapeDefCollectionParser.CHARSET);
233239

234-
var domParser = new DOMParser();
240+
var domParser = new DOMParser();
235241

236-
var collection = null;
237-
var dom = domParser.parseFromString(fileContents, "text/xml");
238-
if (dom != null) {
239-
var dom = dom.documentElement;
240-
var parser = new PrivateShapeDefParser();
241-
Dom.workOn("./p:Collection", dom, function (node) {
242-
collection = parser.parseNode(node);
243-
});
244-
};
245-
246-
if (collection && collection.id) {
247-
//check for duplicate of name
248-
for (i in PrivateCollectionManager.privateShapeDef.collections) {
249-
var existingCollection = PrivateCollectionManager.privateShapeDef.collections[i];
250-
if (existingCollection.id == collection.id) {
251-
throw Util.getMessage("collection.named.already.installed", collection.id);
252-
}
253-
}
242+
var collection = null;
243+
var dom = domParser.parseFromString(fileContents, "text/xml");
244+
if (dom != null) {
245+
var dom = dom.documentElement;
246+
var parser = new PrivateShapeDefParser();
247+
Dom.workOn("./p:Collection", dom, function (node) {
248+
collection = parser.parseNode(node);
249+
});
250+
};
254251

255-
Dialog.confirm("Are you sure you want to install the unsigned collection: " + collection.displayName + "?",
256-
"Since a collection may contain execution code that could harm your machine. It is hightly recommanded that you should only install collections from authors whom you trust.",
257-
"Install", function () {
258-
// CollectionManager.setCollectionCollapsed(collection, false);
259-
PrivateCollectionManager.addShapeCollection(collection);
260-
tempDir.removeCallback();
261-
}, "Cancel", function () {
262-
tempDir.removeCallback();
252+
if (collection && collection.id) {
253+
//check for duplicate of name
254+
for (i in PrivateCollectionManager.privateShapeDef.collections) {
255+
var existingCollection = PrivateCollectionManager.privateShapeDef.collections[i];
256+
if (existingCollection.id == collection.id) {
257+
throw Util.getMessage("collection.named.already.installed", collection.id);
258+
}
263259
}
264-
);
265-
} else {
266-
throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
260+
261+
Dialog.confirm("Are you sure you want to install the unsigned collection: " + collection.displayName + "?",
262+
"Since a collection may contain execution code that could harm your machine. It is hightly recommanded that you should only install collections from authors whom you trust.",
263+
"Install", function () {
264+
// CollectionManager.setCollectionCollapsed(collection, false);
265+
PrivateCollectionManager.addShapeCollection(collection);
266+
tempDir.removeCallback();
267+
}, "Cancel", function () {
268+
tempDir.removeCallback();
269+
}
270+
);
271+
} else {
272+
throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
273+
}
274+
} catch (e) {
275+
Dialog.error("Error installing collection.");
276+
} finally {
277+
ApplicationPane._instance.unbusy();
278+
tempDir.removeCallback();
267279
}
268-
} catch (e) {
269-
Dialog.error("Error installing collection.");
270-
} finally {
271-
ApplicationPane._instance.unbusy();
272-
tempDir.removeCallback();
273280
}
274-
}).on("error", function (error) {
275-
ApplicationPane._instance.unbusy();
276-
Dialog.error("Error installing collection.");
277-
tempDir.removeCallback();
278281
});
279282

280-
fs.createReadStream(filePath).pipe(extractor);
283+
// var extractor = unzip.Extract({ path: targetDir });
284+
// extractor.on("close", function () {
285+
286+
// //try loading the collection
287+
// try {
288+
// var definitionFile = path.join(targetDir, "Definition.xml");
289+
// if (!fs.existsSync(definitionFile)) throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
290+
291+
// var fileContents = fs.readFileSync(definitionFile, ShapeDefCollectionParser.CHARSET);
292+
293+
// var domParser = new DOMParser();
294+
295+
// var collection = null;
296+
// var dom = domParser.parseFromString(fileContents, "text/xml");
297+
// if (dom != null) {
298+
// var dom = dom.documentElement;
299+
// var parser = new PrivateShapeDefParser();
300+
// Dom.workOn("./p:Collection", dom, function (node) {
301+
// collection = parser.parseNode(node);
302+
// });
303+
// };
304+
305+
// if (collection && collection.id) {
306+
// //check for duplicate of name
307+
// for (i in PrivateCollectionManager.privateShapeDef.collections) {
308+
// var existingCollection = PrivateCollectionManager.privateShapeDef.collections[i];
309+
// if (existingCollection.id == collection.id) {
310+
// throw Util.getMessage("collection.named.already.installed", collection.id);
311+
// }
312+
// }
313+
314+
// Dialog.confirm("Are you sure you want to install the unsigned collection: " + collection.displayName + "?",
315+
// "Since a collection may contain execution code that could harm your machine. It is hightly recommanded that you should only install collections from authors whom you trust.",
316+
// "Install", function () {
317+
// // CollectionManager.setCollectionCollapsed(collection, false);
318+
// PrivateCollectionManager.addShapeCollection(collection);
319+
// tempDir.removeCallback();
320+
// }, "Cancel", function () {
321+
// tempDir.removeCallback();
322+
// }
323+
// );
324+
// } else {
325+
// throw Util.getMessage("collection.specification.is.not.found.in.the.archive");
326+
// }
327+
// } catch (e) {
328+
// Dialog.error("Error installing collection.");
329+
// } finally {
330+
// ApplicationPane._instance.unbusy();
331+
// tempDir.removeCallback();
332+
// }
333+
// }).on("error", function (error) {
334+
// ApplicationPane._instance.unbusy();
335+
// Dialog.error("Error installing collection.");
336+
// tempDir.removeCallback();
337+
// });
338+
339+
// fs.createReadStream(filePath).pipe(extractor);
281340
};
282341
PrivateCollectionManager.setLastUsedCollection = function (collection) {
283342
Config.set("PrivateCollection.lastUsedCollection.id", collection.id);

0 commit comments

Comments
 (0)