2020-01-21 07:10:10 +00:00
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
/** Node.js または Electron 固有の機能を利用した関数のモジュール ************* */
|
|
|
|
|
|
|
|
|
|
// ローカルプロパティ
|
|
|
|
|
// Hard Coding!!!
|
|
|
|
|
const appName = 'ocoge';
|
2021-02-21 13:40:35 +00:00
|
|
|
|
const defpath = '/home/pi/Documents/ocoge_docs/';
|
2021-02-15 04:36:41 +00:00
|
|
|
|
const mascotDefPath = '/home/pi/Applications/ocoge/img/';
|
2020-01-21 07:10:10 +00:00
|
|
|
|
// Require
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
const path = require("path");
|
2021-09-03 14:12:32 +00:00
|
|
|
|
|
|
|
|
|
const mainWin = require('@electron/remote').getCurrentWindow();
|
|
|
|
|
const dialog = require('@electron/remote').dialog;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
const shell = require('electron').shell;
|
|
|
|
|
const clipboard = require('electron').clipboard;
|
|
|
|
|
|
|
|
|
|
var saveFilepath = null;
|
|
|
|
|
var wsChanged = false;
|
2021-02-26 11:11:24 +00:00
|
|
|
|
var mascotFilePath = mascotDefPath + 'cogechee.png';
|
2020-01-21 07:10:10 +00:00
|
|
|
|
|
|
|
|
|
// 0で数値の桁合わせ
|
|
|
|
|
// NUM=値 LEN=桁数
|
|
|
|
|
const zeroPadding = (NUM, LEN) => (Array(LEN).join('0') + NUM).slice(-LEN);
|
|
|
|
|
|
|
|
|
|
// 現在の日付時刻から workspace フォルダ内のユニークなファイルパスを作成
|
|
|
|
|
const getUniqueFilepath = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let today = new Date();
|
|
|
|
|
let filename = today.getFullYear() + '-' + zeroPadding((today.getMonth() + 1), 2) + '-' + zeroPadding(today.getDate(), 2) + '-' + zeroPadding(today.getHours(), 2) + '-' + zeroPadding(today.getMinutes(), 2) + '-' + zeroPadding(today.getSeconds(), 2);
|
|
|
|
|
let filepath = path.join(defpath, filename);
|
|
|
|
|
return filepath;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// クリップボードにコピー
|
|
|
|
|
exports.copyText = text => clipboard.writeText(text);
|
|
|
|
|
|
|
|
|
|
// リンクを外部ブラウザで開く
|
|
|
|
|
exports.openURL = (url) => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
shell.openExternal(url);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// タイトルバーにファイル名を表示
|
|
|
|
|
// const setTitle = () => {
|
|
|
|
|
// if (saveFilepath) let title = appName;
|
|
|
|
|
// else let title = saveFilepath + ' - ' + appName;
|
|
|
|
|
// mainWin.setTitle(title);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// saveFilepath を更新
|
|
|
|
|
// ウィンドウタイトルバーテキストを変更
|
|
|
|
|
const setSaveFilepath = filepath => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let title;
|
|
|
|
|
saveFilepath = filepath;
|
|
|
|
|
// if (filepath) title = filepath + ' - ' + appName;
|
|
|
|
|
// else title = appName;
|
|
|
|
|
// mainWin.setTitle(title);
|
|
|
|
|
this.setWsChanged(false);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ワークスペースが変更された・保存された
|
|
|
|
|
// ウィンドウタイトルバーテキストを変更
|
|
|
|
|
exports.setWsChanged = changed => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let title;
|
|
|
|
|
wsChanged = changed;
|
|
|
|
|
if (saveFilepath) title = saveFilepath + ' - ' + appName;
|
|
|
|
|
else title = appName;
|
|
|
|
|
if (changed) title = '*' + title;
|
|
|
|
|
mainWin.setTitle(title);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存ファイルプロパティを更新
|
|
|
|
|
exports.newFile = () => setSaveFilepath(null);
|
|
|
|
|
|
|
|
|
|
// ワークスペースファイル読み込みの一連の動作のラッパ
|
|
|
|
|
exports.loadWsFile = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let filepath = openFile('xml', defpath);
|
|
|
|
|
if (filepath.length > 0) {
|
|
|
|
|
if (saveFilepath === null) {
|
|
|
|
|
setSaveFilepath(filepath);
|
|
|
|
|
} //読み込みに失敗してもsaveFilepathが更新されてしまうのはちょっと具合が悪いかも
|
|
|
|
|
return readFromFile(filepath);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// その他ファイル読み込みの一連の動作のラッパ
|
|
|
|
|
exports.loadFile = ext => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let filepath = openFile(ext, defpath);
|
|
|
|
|
if (filepath.length > 0) {
|
|
|
|
|
return readFromFile(filepath);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
2021-02-15 04:36:41 +00:00
|
|
|
|
exports.selectMascotFile = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
return openFile('png', mascotDefPath);
|
2021-02-15 04:36:41 +00:00
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
// オープンファイルダイアログ
|
2021-02-15 04:36:41 +00:00
|
|
|
|
const openFile = (ext, dpath) => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let filter;
|
|
|
|
|
if (ext == 'xml') {
|
|
|
|
|
filter = { name: 'XML - Extensible Markup Language', extensions: ['xml'] };
|
|
|
|
|
} else if (ext == 'js') {
|
|
|
|
|
filter = { name: 'JS - JavaScript', extensions: ['js'] };
|
|
|
|
|
} else if (ext == 'png') {
|
|
|
|
|
filter = { name: 'PNG - Portable Network Graphics', extensions: ['png'] };
|
|
|
|
|
} else {
|
|
|
|
|
filter = { name: 'text file', extensions: ['txt'] };
|
|
|
|
|
}
|
|
|
|
|
let filepaths = dialog.showOpenDialogSync(mainWin, {
|
|
|
|
|
properties: ['openFile'],
|
|
|
|
|
title: 'Select a file',
|
|
|
|
|
defaultPath: dpath,
|
|
|
|
|
filters: [
|
|
|
|
|
filter
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
if (filepaths == undefined) {
|
|
|
|
|
return '';
|
|
|
|
|
} else {
|
|
|
|
|
return filepaths[0];
|
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// ファイルからデータを読み込み
|
|
|
|
|
const readFromFile = filepath => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let data = '';
|
|
|
|
|
try {
|
|
|
|
|
data = fs.readFileSync(filepath, 'utf-8');
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
}
|
|
|
|
|
return data;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// テキストファイル読み込み: 外部スクリプト動的読み込みに使用
|
|
|
|
|
exports.readTextFile = filepath => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
return readFromFile(filepath);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ワークスペースファイル保存の一連の動作のラッパ
|
|
|
|
|
exports.saveWsFile = data => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
if (saveFilepath === null) {
|
|
|
|
|
let filepath = selectSaveFile('xml');
|
|
|
|
|
if (filepath === undefined) { //キャンセル
|
|
|
|
|
return undefined;
|
|
|
|
|
} else {
|
|
|
|
|
setSaveFilepath(filepath);
|
|
|
|
|
} //これも保存が成功したら変更するようにすべきかしら
|
|
|
|
|
} else this.setWsChanged(false);
|
|
|
|
|
return writeToFile(saveFilepath, data);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// その他ファイル保存の一連の動作のラッパ
|
|
|
|
|
exports.saveFile = (data, ext) => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let filepath = selectSaveFile(ext);
|
|
|
|
|
if (filepath === undefined) { //キャンセル
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
return writeToFile(filepath, data);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// ファイル保存ダイアログ
|
|
|
|
|
const selectSaveFile = ext => {
|
2021-08-28 14:28:26 +00:00
|
|
|
|
let filter, filter_name;
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let defName;
|
|
|
|
|
if (ext == 'xml') {
|
|
|
|
|
filter = { name: 'xml file', extensions: ['xml'] };
|
|
|
|
|
defName = getUniqueFilepath() + '.xml';
|
2021-08-28 14:28:26 +00:00
|
|
|
|
} else if (ext == 'js' || ext == 'py') {
|
|
|
|
|
if (ext == 'js') filter_name = 'javascript file';
|
|
|
|
|
else filter_name = 'python file'
|
|
|
|
|
filter = { name: filter_name, extensions: [ext] };
|
2021-02-26 11:11:24 +00:00
|
|
|
|
// ワークスペース保存名がある場合、それをベースにファイル名の候補を決める
|
|
|
|
|
if (saveFilepath === null) {
|
2021-08-28 14:28:26 +00:00
|
|
|
|
defName = getUniqueFilepath() + '.' + ext;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
} else {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let dirname = path.dirname(saveFilepath);
|
|
|
|
|
let basename = path.basename(saveFilepath, '.xml');
|
2021-08-28 14:28:26 +00:00
|
|
|
|
defName = path.join(dirname, basename) + '.' + ext;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
2021-02-26 11:11:24 +00:00
|
|
|
|
} else {
|
|
|
|
|
filter = { name: 'text file', extensions: ['txt'] };
|
|
|
|
|
}
|
|
|
|
|
let filename = dialog.showSaveDialogSync(mainWin, {
|
|
|
|
|
title: '保存先を決定してください',
|
|
|
|
|
defaultPath: defName,
|
|
|
|
|
filters: [filter]
|
|
|
|
|
});
|
|
|
|
|
return filename;
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// ファイル書き込み
|
|
|
|
|
const writeToFile = (filepath, data) => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
try {
|
|
|
|
|
fs.writeFileSync(filepath, data);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 子プロセス関連
|
|
|
|
|
let children = [];
|
|
|
|
|
// 新しい子プロセスを作成し、配列に保存
|
|
|
|
|
exports.addChild = (child) => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
children.push(child);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
// 全ての子プロセスを殺し、配列をクリア
|
|
|
|
|
exports.killAllChildren = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
children.forEach(function (child) {
|
|
|
|
|
child.kill();
|
|
|
|
|
});
|
|
|
|
|
children = [];
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
|
|
|
|
exports.savePrefsToLS = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let wc = '0';
|
|
|
|
|
if (wsChanged) wc = '1';
|
|
|
|
|
let o = { 'saveFilepath': saveFilepath, 'wsChanged': wc, 'mascotFilePath': mascotFilePath };
|
|
|
|
|
let s = JSON.stringify(o);
|
|
|
|
|
localStorage.setItem("ocoge.json", s);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージからロード
|
|
|
|
|
exports.loadPrefsFromLS = () => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
let s = localStorage.getItem("ocoge.json");
|
|
|
|
|
if (s !== null) {
|
2020-01-21 07:10:10 +00:00
|
|
|
|
let o = JSON.parse(s);
|
|
|
|
|
setSaveFilepath(o.saveFilepath);
|
|
|
|
|
if (o.wsChanged == '0') this.setWsChanged(false);
|
|
|
|
|
else this.setWsChanged(true);
|
2021-02-15 04:36:41 +00:00
|
|
|
|
if (o.mascotFilePath) this.setMascotFilePath(o.mascotFilePath);
|
2021-02-26 11:11:24 +00:00
|
|
|
|
}
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-15 04:36:41 +00:00
|
|
|
|
// マスコット画像パスをプロパティにセット
|
|
|
|
|
exports.setMascotFilePath = fpath => mascotFilePath = fpath;
|
|
|
|
|
exports.getMascotFilePath = () => mascotFilePath;
|
|
|
|
|
|
2020-01-21 07:10:10 +00:00
|
|
|
|
|
|
|
|
|
// ファイル名にアプリケーションのドキュメントルートまでのパスをつけて返す
|
|
|
|
|
exports.getDocPath = filename => {
|
2021-02-26 11:11:24 +00:00
|
|
|
|
return path.join(appDocRoot, filename);
|
2020-01-21 07:10:10 +00:00
|
|
|
|
}
|