/**
* @file ui.js UI handler
* @author Dreamsavior
*/
/**
* The reference of the icons
* @external Icon reference
* @see https://dreamsavior.net/files/docs/tpp/fontello-f7017850/demo.html
*/
var win = nw.Window.get();
window.CustomFields = require("www/js/CustomFields");
// Loads Prism and it's components
window.Prism = require("prismjs");
require("prismjs/plugins/highlight-keywords/prism-highlight-keywords");
require("prismjs/plugins/line-numbers/prism-line-numbers");
require("prismjs/plugins/file-highlight/prism-file-highlight");
require("prismjs/plugins/line-highlight/prism-line-highlight");
require("prismjs/plugins/keep-markup/prism-keep-markup");
require("prismjs/plugins/command-line/prism-command-line");
// Listen to main window's close event
win.on('close', async function() {
// confirm
if (!nw.appIsClosing) {
if (trans.gridIsModified()) {
var conf = confirm(t("Do you really want to exit Translator++?\nAll unsaved changes will be discarded!"));
if (!conf) return false;
nw.appIsClosing = true;
}
}
// Hide the window to give user the feeling of closing immediately
$(window).trigger("beforeClose");
this.hide();
try {
sys.saveConfig();
} catch (e) {
// do nothing
}
if (nw.process.versions["nw-flavor"] == "sdk") {
win.closeDevTools();
await common.wait(200);
}
$(document).trigger("close");
// If the new window is still open then close it.
// close all popup
for (var id in ui.windows) {
if (ui.windows[id] != null || ui.windows[id] != undefined || typeof ui.windows[id] != 'undefined') ui.windows[id].close(true);
}
// After closing the all popups window, close the main window.
this.close(true);
});
// prevent windows goes beyond screen
setTimeout(()=>{
if (win.y < 0) win.y = 0;
console.log("current Y", win.y);
}, 200)
$.fn.insertAt = function(index, $parent) {
return this.each(function() {
if (index === 0) {
$parent.prepend(this);
} else {
$parent.children().eq(index - 1).after(this);
}
});
}
/**
* Handling user interface stuff
* @namespace
* @classdesc ui is a static object to handle anything related to user interface
* ui utility belt can be accessed through `window.ui` or calling `ui` directly
*/
var ui = {
isLoaded: false,
autoComplateData:[],
selectedCell:null,
dialogs:[],
windows:{},
timers:{},
$elm: $('<div></div>')
}
/**
* Create a new event with JQuery eventing convenience
* @param {String} evt - Event name
* @param {Function} fn - Function to trigger
* @since 4.3.20
* @example
* ui.on('transLoaded', (e, opt)=> {
* // do something
* })
*/
ui.on = function(evt, fn) {
this.$elm.on(evt, fn)
}
/**
* Removes an event
* @param {String} evt - Event name
* @param {Function} fn - Function to trigger
* @since 4.3.20
* @example
* ui.off('transLoaded', (e, opt)=> {
* // do something
* })
*/
ui.off = function(evt, fn) {
this.$elm.off(evt, fn)
}
/**
* Run the event once
* Trigger an event and immediately removes it
* @param {String} evt - Event name
* @param {Function} fn - Function to trigger
* @since 4.3.20
*/
ui.one = function(evt, fn) {
this.$elm.one(evt, fn)
}
/**
* Trigger an event
* @param {String} evt - Event name
* @param {Function} fn - Function to trigger
* @since 4.3.20
*/
ui.trigger = function(evt, param) {
this.$elm.trigger(evt, param)
}
/**
* This function is called when the UI is ready. It takes a function as a parameter and adds it to the onReadyPool if the UI is not initialized.
* If the UI is already initialized, it calls all the functions in the onReadyPool and then clears the pool.
* @param {Function} onReadyEvent - The function to be called when the UI is ready.
*/
ui.onReady = function (onReadyEvent) {
if (typeof onReadyEvent !== 'function') return console.log("parameter must be a function");
this.__onReadyPool = this.__onReadyPool||[];
if (Boolean(this.isInitialized) == false) {
this.__onReadyPool.push(onReadyEvent)
} else {
for (var i=0; i<this.__onReadyPool.length; i++) {
this.__onReadyPool[i].apply(this, arguments);
}
this.__onReadyPool = [];
onReadyEvent.apply(this, arguments);
}
}
/**
* This function is called when the DOM is ready. It takes a function as a parameter and calls it immediately if the DOM is already available.
* If the DOM is not available, it adds an event listener to call the function when the DOMContentLoaded event is fired.
* @param {Function} fn - The function to be called when the DOM is ready.
*/
ui.onDOMReady = function(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
ui.menus = {}
ui.menus.saveAs = new nw.Menu();
ui.menus.saveAs.append(new nw.MenuItem({
label: t('Trans file'),
type: "normal",
click: function(){
trans.saveAs();
}
}));
ui.menus.saveAs.append(new nw.MenuItem({
label: t('Translator++ Project Package (TPP) file'),
type: "normal",
click: async function(){
console.log("Exporting to TPP");
var savePath = await ui.saveAsTPP(trans.currentFile);
trans.exportTPP(savePath, {
onDone: function() {
ui.closeExportDialog();
}
});
}
}));
ui.centerWindow = function() {
console.log("centering window");
var leftMargin = (screen.width - window.outerWidth)/2;
var topMargin = (screen.height - window.outerHeight)/2;
win.y = parseInt(topMargin);
win.x = parseInt(leftMargin);
console.log(win.y, win.x);
return [win.x, win.y]
}
ui.isInViewport = function($obj) {
var elementTop = $obj.offset().top;
var elementBottom = elementTop +$obj.outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
ui.scrollToView = function(row, col, onAfterScroll){
//console.log("scrolling to : "+row+","+col);
// for performance check only last visible row, since the only possible way is goes to next row;
var lastVisibleRow = ui.getLastFullyVisibleRow();
if (row < lastVisibleRow) return false;
var center = row-Math.round(trans.grid.countVisibleRows()/2);
// registering event once
if (typeof onAfterScroll == 'function') {
trans.grid.addHookOnce('afterScrollVertically', function() {
onAfterScroll.call(trans.grid, row, col);
});
}
trans.grid.scrollViewportTo(center, col);
//trans.grid.selectCell(center, col,center, col);
return true;
/*
var firstRendered = trans.grid.rowOffset()+3;
var renderedCount = trans.grid.countRenderedRows()-3;
var margin = 4;
if (row <= renderedCount-margin) return false;
var center = row-Math.round(renderedCount/2);
if (row >= firstRendered+renderedCount-margin) {
trans.grid.scrollViewportTo(center, col);
}
return true;
*/
}
/**
* Add 20% to the grid's scroll height
*/
ui.bumpGridScroll = function(addHeight) {
var $scrollerElm = $("#table .wtHolder .wtHider").eq(0)
var curHeight = $scrollerElm.height();
curHeight = curHeight || 1;
addHeight ||= Math.round((curHeight/100) *20);
var bump = curHeight + addHeight;
console.log(bump);
curHeight = $scrollerElm.css("height", bump+"px")
}
ui.setGridScrollHeight = function(newHeight) {
$("#table > .ht_master .wtHider").css("height", newHeight+"px");
}
ui.saveIndicatorStart = async function() {
$(".button-save img").addClass("rotating");
}
ui.saveIndicatorEnd = async function() {
$(".button-save img").removeClass("rotating");
}
ui.disableGrid = function(state) {
if (typeof state == 'undefined') {
state = !$("#gridDisabler").hasClass("hidden");
}
if (state) {
$("#gridDisabler").removeClass("hidden");
var panRight= $(".panel-right");
var thisHeight = panRight.outerHeight();
var thisWidth = panRight.outerWidth();
var thisTop = panRight.offset().top;
var thisLeft = panRight.offset().left;
var disabler = $("#gridDisabler");
disabler.css("width", thisWidth);
disabler.css("height", thisHeight);
disabler.css("top", thisTop);
disabler.css("left", thisLeft);
ui.timers.gridDisabler = undefined;
$(window).on("resize.gridDisabler", function() {
if (ui.timers.gridDisabler) clearTimeout(ui.timers.gridDisabler);
ui.timers.gridDisabler = setTimeout(function() {
var panRight= $(".panel-right");
var thisHeight = panRight.outerHeight();
var thisWidth = panRight.outerWidth();
var thisTop = panRight.offset().top;
var thisLeft = panRight.offset().left;
var disabler = $("#gridDisabler");
disabler.css("width", thisWidth);
disabler.css("height", thisHeight);
disabler.css("top", thisTop);
disabler.css("left", thisLeft);
ui.timers.gridDisabler = undefined;
}, 250);
});
} else {
$("#gridDisabler").addClass("hidden");
$(window).off("resize.gridDisabler");
}
}
/**
* Disable buttons when no project is currently oppened
*/
ui.disableButtons = function() {
$(".menu-button.button-save").prop("disabled", true)
$(".menu-button.button-save-as").prop("disabled", true)
$(".menu-button.button-import").prop("disabled", true)
$(".menu-button.button-export").prop("disabled", true)
$(".menu-button.button-inject").prop("disabled", true)
$(".menu-button.batch-translate").prop("disabled", true)
$(".menu-button.contextTool").prop("disabled", true)
$(".menu-button.button-properties").prop("disabled", true)
$(".menu-button.addNewKey").prop("disabled", true)
$(".menu-button.importHere").prop("disabled", true)
$(".menu-button.filePropertiesMenu").prop("disabled", true)
$(".menu-button.addNote").prop("disabled", true)
$(".menu-button.find").prop("disabled", true)
$(".menu-button.removeTranslation").prop("disabled", true)
$(".menu-button.removeFile").prop("disabled", true)
$(".menu-button .button-save-as").prop("disabled", true);
$(".menu-button .button-save-as-side").prop("disabled", true);
$("#table").addClass("hidden");
}
ui.enableButtons = function() {
$(".menu-button.button-save").prop("disabled", false)
$(".menu-button.button-save-as").prop("disabled", false)
$(".menu-button.button-import").prop("disabled", false)
$(".menu-button.button-export").prop("disabled", false)
$(".menu-button.button-inject").prop("disabled", false)
$(".menu-button.batch-translate").prop("disabled", false)
$(".menu-button.contextTool").prop("disabled", false)
$(".menu-button.button-properties").prop("disabled", false)
$(".menu-button.addNewKey").prop("disabled", false)
$(".menu-button.importHere").prop("disabled", false)
$(".menu-button.filePropertiesMenu").prop("disabled", false)
$(".menu-button.addNote").prop("disabled", false)
$(".menu-button.find").prop("disabled", false)
$(".menu-button.removeTranslation").prop("disabled", false)
$(".menu-button.removeFile").prop("disabled", false)
$(".menu-button .button-save-as").prop("disabled", false);
$(".menu-button .button-save-as-side").prop("disabled", false);
$("#table").removeClass("hidden");
}
ui.showBusyOverlay = function() {
ui.appIsBusy = true;
$("#busyOverlay").removeClass("hidden");
/**
* Triggered when busyOverlay opened
* @event ui#busyOverlayOpened
* @since 4.3.20
*/
this.trigger("busyOverlayOpened")
}
ui.hideBusyOverlay = function() {
ui.appIsBusy = false;
$("#busyOverlay").addClass("hidden");
/**
* Triggered when busyOverlay closed
* @event ui#busyOverlayClosed
* @since 4.3.20
*/
this.trigger("busyOverlayClosed")
}
ui.getFirstVisibleRow = function() {
var $header = $("#table .ht_clone_top_left_corner")
var visibleTop = $header.offset().top + $header.outerHeight();
var $rows = $(".ht_master .htCore tbody tr");
for (var i=0; i<$rows.length; i++) {
var rowsBottom = $rows.eq(i).offset().top+$rows.eq(i).outerHeight();
if (rowsBottom >= visibleTop) {
var coords = trans.grid.getCoords($rows.eq(i).find("td").eq(0)[0]);
return coords.row;
}
}
}
ui.getFirstFullyVisibleRow = function() {
var $header = $("#table .ht_clone_top_left_corner")
var visibleTop = $header.offset().top + $header.outerHeight();
var $rows = $(".ht_master .htCore tbody tr");
for (var i=0; i<$rows.length; i++) {
var rowsTop = $rows.eq(i).offset().top;
if (rowsTop >= visibleTop) {
var coords = trans.grid.getCoords($rows.eq(i).find("td").eq(0)[0]);
return coords.row;
}
}
}
ui.getLastFullyVisibleRow = function() {
var $table = $("#table")
var visibleBottom = $table.offset().top + $table.height();
var $rows = $(".ht_master .htCore tbody tr");
for (var i=$rows.length-1; i>=0; i--) {
var rowsBottom = $rows.eq(i).offset().top+$rows.eq(i).outerHeight();
if (visibleBottom >= rowsBottom) {
var coords = trans.grid.getCoords($rows.eq(i).find("td").eq(0)[0]);
return coords.row;
}
}
}
ui.getLastVisibleRow = function() {
var $table = $("#table")
var visibleBottom = $table.offset().top + $table.height();
var $rows = $(".ht_master .htCore tbody tr");
for (var i=$rows.length-1; i>=0; i--) {
var rowsBottom = $rows.eq(i).offset().top;
if (visibleBottom >= rowsBottom) {
var coords = trans.grid.getCoords($rows.eq(i).find("td").eq(0)[0]);
return coords.row;
}
}
}
ui.isRowVisible = function(row) {
var first = ui.getFirstVisibleRow();
var last = ui.getLastVisibleRow();
return (row>=first && row<=last);
}
ui.generateColSelector = function(options) {
options = options||{};
options.data = options.data||window.trans;
options.onNoSelection = options.onNoSelection|| function() {};
options.onHasSelection = options.onHasSelection|| function() {};
options.skipFirstCol = options.skipFirstCol||false;
if (typeof options.data.colHeaders == 'undefined') return $("<select></select>");
var thisColHeader = options.data.colHeaders;
console.log(thisColHeader);
var $select = $("<select></select>");
for (var i=0; i<thisColHeader.length; i++) {
if (i==0 && options.skipFirstCol) continue;
$select.append("<option value='"+i+"'>"+thisColHeader[i]+"</option>");
}
return $select;
}
ui.generateColMultiSelector = function(options) {
options = options||{};
options.data = options.data||window.trans;
options.onNoSelection = options.onNoSelection|| function() {};
options.onHasSelection = options.onHasSelection|| function() {};
options.skipFirstCol = options.skipFirstCol||false;
if (typeof options.data.colHeaders == 'undefined') return $("<select></select>");
var thisColHeader = options.data.colHeaders;
console.log(thisColHeader);
var $select = $("<select multiple='multiple' class='multiple'></select>");
for (var i=0; i<thisColHeader.length; i++) {
if (i==0 && options.skipFirstCol) continue;
$select.append("<option value='"+i+"'>"+thisColHeader[i]+"</option>");
}
return $select;
}
ui.drawFileSelector = function(data, $target, options) {
console.log("entering : ui.drawFileSelector");
data = data || trans.project || {};
options = options||{};
options.onNoSelection = options.onNoSelection|| function() {};
options.onHasSelection = options.onHasSelection|| function() {};
options.filePath = options.filePath || "";
options.defaultSelection = options.defaultSelection || [];
options.defaultSelectionMode = options.defaultSelectionMode||"";
options.insensitiveDefault = options.insensitiveDefault || false;
if (Array.isArray(options.defaultSelection) == false) options.defaultSelection = [options.defaultSelection];
var selectorTitle = options.filePath;
console.log($target);
if (typeof data.project.files == 'undefined') return false;
if ($target.length == 0) return false;
$target.addClass("fileSelector");
$target.addClass("rendered");
$target.empty();
$target.append("<div class='fileSelectorHeader icon-doc-inv'>"+selectorTitle+"</div>\
<div class='fileSelectorBody'></div>\
<div class='fileSelectorOptions fileSelectorFooter' ><form>\
<button class='fileSelectorAction actionSelectAll'>"+t("Select all")+"</button>\
<button class='fileSelectorAction actionSelectNone'>"+t("Select none")+"</button>\
<button class='fileSelectorAction actionSelectInvert'>"+t("Invert")+"</button>\
<button class='fileSelectorAction actionSelectMatch'>"+t("Match destination selection")+"</button>\
<span class='info icon-info-circled'>"+t("use mouse drag to do bulk selection")+"</span>\
</form></div>");
//var $selectAll = $target.find(".fileSelectorOptions .selectAll");
$target.find("form").on("submit", function(e) {
e.preventDefault();
})
$target.find(".actionSelectAll").on("click", function() {
$(this).closest(".fileSelector").find(".fileSelectorBody .filename").prop("checked", true);
});
$target.find(".actionSelectNone").on("click", function() {
$(this).closest(".fileSelector").find(".fileSelectorBody .filename").prop("checked", false);
});
$target.find(".actionSelectInvert").on("click", function() {
$(this).closest(".fileSelector").find(".fileSelectorBody .filename").each(function() {
$(this).prop("checked", !$(this).prop("checked"));
});
});
$target.find(".actionSelectMatch").on("click", function() {
$(this).closest(".fileSelector").find(".fileSelectorBody .filename").prop("checked", false);
var targetSelection = options.defaultSelection || [];
if (targetSelection.length < 0) {
targetSelection = trans.getCheckedFiles() || [];
}
console.log("targetSelection", targetSelection);
var $selectorBody = $(this).closest(".fileSelector").find(".fileSelectorBody");
for (var i=0; i<targetSelection.length; i++ ) {
$selectorBody.find("input[type=checkbox][value='"+CSS.escape(targetSelection[i])+"']").prop("checked", true);
}
});
var getFilename = (path)=>{
if (!path) return ""
return nwPath.parse(path.split('\\').pop().split('/').pop()).name
}
var insDefault = [];
if (options.insensitiveDefault) {
for (var i in options.defaultSelection) {
insDefault.push(getFilename(options.defaultSelection[i]).toLowerCase());
}
}
console.log("insDefault:", insDefault);
var content = $target.find(".fileSelectorBody");
for (let file in data.project.files) {
let checkbox = $("<input type='checkbox' class='filename' value='"+file+"' />");
if (options.defaultSelection.includes(file)) {
checkbox.prop("checked", true);
} else {
if (insDefault.includes(getFilename(file).toLowerCase())) checkbox.prop("checked", true);
}
checkbox.on("change", function() {
var selected = $(this).closest(".fileSelectorBody").find(".filename:checked");
if (selected.length < 1) {
options.onNoSelection.call($(this));
} else {
options.onHasSelection.call($(this));
}
});
let template = $("<label class='fileSelectorLabel' title='"+file+"'><span>"+data.project.files[file].filename+"</span><label>");
template.prepend(checkbox);
content.append(template);
}
if (typeof data.project.references !== 'undefined') {
for (let file in data.project.references) {
let checkbox = $("<input type='checkbox' class='filename' value='"+file+"' />");
if (options.defaultSelection.includes(file)) checkbox.prop("checked", true);
checkbox.on("change", function() {
var selected = $(this).closest(".fileSelectorBody").find(".filename:checked");
if (selected.length < 1) {
options.onNoSelection.call($(this));
} else {
options.onHasSelection.call($(this));
}
});
let template = $("<label class='fileSelectorLabel' title='"+file+"'><span>"+data.project.references[file].filename+"</span><label>");
template.prepend(checkbox);
content.append(template);
}
}
if (options.defaultSelectionMode == 'none') {
$target.find(".actionSelectNone").trigger("click");
} else if (options.defaultSelectionMode == 'all'){
$target.find(".actionSelectAll").trigger("click");
} else if (options.defaultSelectionMode == 'match'){
$target.find(".actionSelectMatch").trigger("click");
}
//$selectAll.trigger("change");
//console.log("target : ", $target, $target[0]);
var DragSelect = DragSelect||require("dragselect");
ui.ds = new DragSelect({
selectables: $target.find(".fileSelectorBody")[0].getElementsByClassName('fileSelectorLabel'),
autoScrollSpeed: 15,
area :$target.find(".fileSelectorBody")[0],
callback : function(elm) {
//console.log("Selected element : ", $(elm));
var $elm = $(elm);
// ignore selection if selecting less than 2 row
if ($elm.length <= 1) return false;
$elm.each(function() {
var $input = $(this).find("input");
console.log("input : ", $input);
$(this).removeClass("ds-hover");
$input.prop("checked", true)
$input.trigger("change");
ui.ds.clearSelection();
})
}
});
return $target;
}
ui.openTrans = async function() {
// open supported trans file
var opts = {
types: [
{
description: 'Trans File',
accept: {'text/trans': ['.trans']},
},
{
description: 'Translator++ Package File',
accept: {'application/tpp': ['.tpp']},
},
{
description: 'Trans formatted JSON File',
accept: {'text/json': ['.json']},
},
]
}
try {
return await window.showOpenFilePicker(opts);
} catch (e) {
return;
}
}
/**
* Open import translator dialog window
* @param {String} transFile - Path to the file
* @param {Object} [options] - options
*
*/
ui.openImportTrans = async function(transFile, options) {
/*
options {
mode : 0/1 => import translation or object
}
example : {mode:1, defaultSelection:["Common Reference"]}
*/
options = options || {};
options.mode = options.mode || 0;
options.defaultSelectionMode = options.defaultSelectionMode || "";
options.defaultSelection = options.defaultSelection || [];
if (options.defaultSelection.length == 0) options.defaultSelection = trans.getCheckedFiles();
console.log("Opening : "+transFile);
const doOpenImportTrans = async function(transFile, data) {
return new Promise((resolve, reject) => {
const $importDialog = $("#dialogImportTrans");
if ($importDialog.hasClass("initialized") == false) {
let $importDialog = $("#dialogImportTrans");
$importDialog.dialog({
autoOpen: false,
modal:true,
minWidth:480,
minHeight:320,
width:Math.round($(window).width()/100*80),
height:Math.round($(window).height()/100*80),
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
close: function() {
$importDialog.data("transFile", undefined);
$importDialog.data("options", undefined);
$importDialog.data("data", undefined);
resolve();
},
buttons: [
{
text: "Cancel",
click: function() {
$(this).dialog( "close" );
}
},
{
text: "Import",
click: function() {
var mode = $("#dialogImportTrans input[name='importMode']:checked"). val();
var options = $importDialog.data("options");
var translateContext = $(this).find(".contextTranslation").prop("checked");
if (mode == 0) {
var $elm=$(this).find(".selectorBody[data-if='0']");
// import translation
var selectedCell = [];
//if ($("#dialogImportTrans .fileSelectorHeader .selectAll").prop("checked") == false) {
let checkedElm = $("#dialogImportTrans .fileSelectorBody .filename:checked");
for (var x=0; x<checkedElm.length; x++) {
selectedCell.push(checkedElm.eq(x).attr("value"));
}
//}
var targetFiles = options.defaultSelection||[];
//if ($("#dialogImportTrans .destinationFile .targetAllFiles").prop("checked") == false) {
if (targetFiles.length == 0) {
targetFiles = trans.getCheckedFiles();
}
var fileData = $importDialog.data("data");
trans.importTranslation(fileData,
{
targetColumn : $elm.find(".selectRow select").val(),
overwrite : $elm.find(".overwriteTarget").prop("checked"),
files : selectedCell,
destination : targetFiles,
compareMode : $elm.find(".compareMode").val(),
translateContext: translateContext,
destinationMode : $(this).find(".destinationMode").val(),
caseInsensitive : $elm.find(".caseInsensitive").prop("checked"),
});
} else if (mode == 1) {
// import object
console.log("generating target pair");
var targetPair = {};
let checkedElm = $("#dialogImportTrans .fileSelectorBody .filename:checked");
for (let x=0; x<checkedElm.length; x++) {
targetPair[checkedElm.eq(x).attr("value")] = true;
}
let fileData = $importDialog.data("data");
//return true;
trans.importFromFile(fileData, {
targetPair: targetPair,
mergeData : $("#dialogImportTrans .mergeData").prop("checked")
});
} else if (mode == 2) {
let $elm=$(this).find(".selectorBody[data-if='2']");
// import translation
let selectedCell = [];
var checkedElm = $("#dialogImportTrans .fileSelectorBody .filename:checked");
for (let x=0; x<checkedElm.length; x++) {
selectedCell.push(checkedElm.eq(x).attr("value"));
}
let targetFiles = options.defaultSelection||[];
if (targetFiles.length == 0) targetFiles = trans.getCheckedFiles();
let fileData = $importDialog.data("data");
trans.importTranslation(fileData,
{
targetColumn : $elm.find(".selectRow select").val(),
overwrite : $elm.find(".overwriteTarget").prop("checked"),
files : selectedCell,
destination : targetFiles,
compareMode : parseInt($elm.find(".compareMode").val()),
translateContext: translateContext,
caseInsensitive : $elm.find(".caseInsensitive").prop("checked"),
});
}
// clearing data
$importDialog.data("data", {});
$(this).dialog( "close" );
}
}
]
});
$importDialog.addClass("initialized");
$("#dialogImportTrans .ImportTransImportMode").off("input");
$("#dialogImportTrans .ImportTransImportMode").on("input", function() {
console.log("change tab", $(this));
if ($(this).prop("checked") == false) return false;
var $tabObj = $(this).closest(".tabWrapper")
var $targetObj = $tabObj.find(".selectorBody[data-if='"+CSS.escape($(this).val())+"']");
if ($targetObj.length == 0) return false;
$tabObj.find(".selectorBody").addClass("hidden");
$targetObj.removeClass("hidden");
});
$("#dialogImportTrans .destinationMode").off("change");
$("#dialogImportTrans .destinationMode").on("change", function() {
var $this = $(this)
var val = $(this).val();
$this.closest(".tabWrapper").find(`[data-for]`).addClass("hidden");
$this.closest(".tabWrapper").find(`[data-for="${val}"]`).removeClass("hidden");
})
}
if (options.defaultSelection.length > 1) {
$importDialog.find(".destinationList").html(options.defaultSelection.length+" objects selected")
} else {
$importDialog.find(".destinationList").html(options.defaultSelection)
}
$importDialog.data("transFile", transFile);
$importDialog.data("options", options);
$importDialog.data("data", data);
$importDialog.dialog("open");
//$importDialog.find(".selectorBody[value='"+options.mode+"']").prop("checked", true).trigger("input");
$importDialog.find(".ImportTransImportMode[value='"+CSS.escape(options.mode)+"']").prop("checked", true).trigger("input");
// return $importDialog;
})
}
var data;
var transPath = transFile;
if (trans.isTrans(transFile)) {
data = transFile;
transPath = "Imported Trans Object";
} else {
data = await trans.loadJSON(transFile);
data = trans.validateTransData(data);
}
if (!trans.isTrans(data)) {
alert(t("Invalid trans data"));
return;
}
ui.drawFileSelector(data, $("#dialogImportTrans .fileSelectorWrapper"), {
onNoSelection:function() {
$(".ui-dialog[aria-describedby=dialogImportTrans] .ui-dialog-buttonpane button").eq(1).button("disable");
},
onHasSelection:function() {
$(".ui-dialog[aria-describedby=dialogImportTrans] .ui-dialog-buttonpane button").eq(1).button("enable");
},
filePath:transPath,
defaultSelection: options.defaultSelection,
defaultSelectionMode: options.defaultSelectionMode,
insensitiveDefault:true
});
$("#dialogImportTrans .selectRow").empty();
ui.generateColSelector({
skipFirstCol:true
}).appendTo($("#dialogImportTrans .selectRow"));
if ($("#dialogImport").hasClass("initialized")) {
if ($("#dialogImport").dialog( "isOpen" )) {
$("#dialogImport").off( "dialogclose");
$("#dialogImport").on( "dialogclose", function( event, ui ) {
console.log("closing import dialog");
$("#dialogImport").off( "dialogclose");
doOpenImportTrans(transPath, data);
});
$("#dialogImport").dialog( "close" );
} else {
doOpenImportTrans(transPath, data);
}
} else {
doOpenImportTrans(transPath, data);
}
}
ui.openImportDialog = function() {
ui.importDialogOnClose = function() {};
if ($("#dialogImport").hasClass("initialized") == false) {
$("#dialogImport").dialog({
autoOpen: false,
modal:true,
minWidth:480,
minHeight:320,
maxWidth:640,
maxHeight:420,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
}
});
$("#dialogImport").addClass("initialized");
}
$("#dialogImport").dialog("open");
return $("#dialogImport");
}
ui.openInjectDialog = function(options) {
options = options || {};
options.ignoreSelection ||= false;
var $dialogInject = $("#dialogInject");
var title = t("Inject / Apply translation")
if (options.ignoreSelection) {
options.files = [];
title = t("Inject / Apply translation to all");
$dialogInject.find(".applyAllWarn").removeClass("hidden")
} else {
$dialogInject.find(".applyAllWarn").addClass("hidden")
}
// reset
$dialogInject.find(".customContent").empty();
$dialogInject.find(".sourceDir").removeClass("hidden");
$dialogInject.find(".targetDir").removeClass("hidden");
$dialogInject.find(".targetExe").addClass("hidden");
$dialogInject.find(".copyOptionsBlock").addClass("hidden");
$dialogInject.find(".copyOptionsBlock option").removeClass("hidden");
engines.handler('onOpenInjectDialog').call(this, $dialogInject, options);
$(document).trigger("beforeOpenInjectDialog", options);
console.log("openInjectDialog, options : ", options);
var tags = new UiTags();
this._uiTags = tags;
$dialogInject.find(".colorTagSelector").empty();
$dialogInject.find(".colorTagSelector").append(tags.element);
if ($dialogInject.find(".targetExe").is(":visible")) {
$dialogInject.find(".targetDir").addClass("hidden");
}
var $wordWrapByTagField = this.drawWordWrapByTagField(options);
$dialogInject.find(".wordWrapByTag .wrapper").empty();
$dialogInject.find(".wordWrapByTag").removeClass("hidden");
$dialogInject.find(".wordWrapByTag .wrapper").append($wordWrapByTagField);
var getSelectedFiles = function() {
if (options.files) return options.files;
if (trans.getCheckedFiles().length > 0) return trans.getCheckedFiles();
return false;
}
// settingUp customFieldOptions
let enginesFieldOptions = engines.current().getProperty("injectOptionFields");
var customFields;
const $customFieldsWrapper = $dialogInject.find(".customFields");
$customFieldsWrapper.empty();
(async ()=> {
if (enginesFieldOptions) {
customFields = new CustomFields($customFieldsWrapper, enginesFieldOptions);
console.log("custom field for inject field:", customFields);
await customFields.until("ready");
}
engines.handler('onOpenInjectDialogReady').call(this, $dialogInject, options);
})()
//if ($dialogInject.hasClass("initialized") == false) {
$dialogInject.dialog({
title: title,
autoOpen: false,
modal:true,
minWidth:640,
minHeight:420,
width:640,
height:480,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons: [
{
text: t("Cancel"),
//icon: "ui-icon-heart",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Apply Translation"),
//icon: "ui-icon-heart",
click: function() {
// do apply translation
var targetPath = "";
var $sourceField = $("#injectSourceMaterial");
if ($sourceField.is(":visible")) {
targetPath = $sourceField.val();
var exist = common.isExist($sourceField.val());
if (!exist) {
$(".sourceMaterialTooltip").removeClass("hidden");
return;
}
}
var destinationPath = "";
if ($dialogInject.find(".targetDir").is(":visible")) {
let $destField = $("#injectDestFolder");
destinationPath = $destField.val()
}
if ($dialogInject.find(".targetExe").is(":visible")) {
let $destField = $("#injectDestExe");
destinationPath = $destField.val()
}
if (destinationPath == "") {
$(".injectDestFolderTooltip").removeClass("hidden");
return;
}
var thisOptions = ui._uiTags.getValue();
if (thisOptions === false) return false;
thisOptions.files = getSelectedFiles();
thisOptions.copyOptions = $dialogInject.find(".copyOptions").val();
/*
if (typeof $wordWrapByTagField.data("getValue") == "function") {
thisOptions.wordWrapByTags = $wordWrapByTagField.data("getValue")();
console.log("wordWrapSetting", thisOptions);
}
*/
thisOptions.wordWrapByTags = trans.getOption("wordWrapByTags") || [];
if (customFields) {
thisOptions.custom = customFields.getValues();
}
trans.applyTranslation.start(destinationPath, targetPath, thisOptions)
$(this).dialog( "close" );
}
}
]
});
//$dialogInject.addClass("initialized");
//}
$(".sourceMaterialTooltip").addClass("hidden");
$dialogInject.find("#injectSourceMaterial").off("change")
$dialogInject.find("#injectSourceMaterial").on("change", function() {
trans.project.loc = $(this).val()
})
$dialogInject.find("#injectDestFolder").off("change")
$dialogInject.find("#injectDestFolder").on("change", function() {
trans.project.devPath = $(this).val()
})
$dialogInject.find("form").off("submit.injectHandler");
$dialogInject.find("form").on("submit.injectHandler", function(e) {
console.log("prevent submit");
e.preventDefault()
})
if ($dialogInject.find("#injectSourceMaterial").data("projectId") != trans.project.projectId) {
$dialogInject.find("#injectSourceMaterial").data("projectId", trans.project.projectId);
//if ($dialogInject.find("#injectSourceMaterial").val() == "") $dialogInject.find("#injectSourceMaterial").val(trans.project.loc)
$dialogInject.find("#injectSourceMaterial").val(trans.project.loc);
}
$dialogInject.find("#injectDestFolder").val(trans.project.devPath)
$dialogInject.dialog("open");
if ($dialogInject.find(".targetExe").is(":visible")) {
try {
$dialogInject.find("[name=injectDestExe]").val(trans.project.options.executable || "")
} catch (e) {
// do nothing
}
}
return $dialogInject;
}
ui.openImportSpreadsheetDialog = function() {
ui.importDialogOnClose = function() {};
if ($("#dialogImportSpreadsheet").hasClass("initialized") == false) {
ui.generateColSelector({
skipFirstCol:true
}).appendTo($("#dialogImportSpreadsheet .targetCol"));
$("#dialogImportSpreadsheet .importSpreadsheetPathType").on("click", function() {
$(this).closest(".importSpreadsheetPathTypeWrapper").find("label").removeClass("active");
$(this).closest("label").addClass("active");
var notActive = $(this).closest(".importSpreadsheetPathTypeWrapper").find("label").not(".active");
notActive.find(".importSpreadsheet").val("");
notActive.find(".importSpreadsheet").data("files", []);
notActive.find(".selectedFileRemark").html("");
$(this).closest("label").find(".importSpreadsheet").trigger("click");
});
$("#dialogImportSpreadsheet .importSpreadsheet").on("input", function() {
var $this = $(this);
//var text = "";
$this.data("files", $this.val().split(";"))
if ( $this.data("files").length > 1) {
$this.closest("label").find(".selectedFileRemark").html($this.data("files").length+" object selected.");
} else {
$this.closest("label").find(".selectedFileRemark").html($this.val());
}
});
$("#dialogImportSpreadsheet").dialog({
autoOpen: false,
modal:true,
minWidth:640,
minHeight:480,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},buttons: [
{
text: t("Help"),
//icon: "ui-icon-heart",
click: function() {
nw.Shell.openExternal("https://dreamsavior.net/docs/translator/features/importing-translations/importing-translation-from-spreadsheet-files/")
}
},
{
text: t("Cancel"),
//icon: "ui-icon-heart",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Import"),
//icon: "ui-icon-heart",
click: function() {
var selectedFiles = $("#dialogImportSpreadsheet .importSpreadsheetPathTypeWrapper label.active .importSpreadsheet").data("files");
if (typeof selectedFiles == 'undefined' || selectedFiles == '' || selectedFiles.length == 0) return alert("Please select a file/folder");
var columns = $("#dialogImportSpreadsheet .targetCol select").val();
var targetFiles = trans.getCheckedFiles();
if (targetFiles.length == 0) targetFiles = trans.getAllFiles();
var options = {
overwrite: $("#dialogImportSpreadsheet .overwriteTarget").prop("checked"),
files:targetFiles
}
$(this).dialog( "close" );
setTimeout( function() {
trans.importSheet(selectedFiles, columns, options);
}, 300);
}
}
]
});
$("#dialogImportSpreadsheet").addClass("initialized");
}
$("#dialogImportSpreadsheet").dialog("open");
return $("#dialogImportSpreadsheet");
}
ui.openImportRPGMTransDialog = function() {
ui.importDialogOnClose = function() {};
if ($("#dialogImportRPGMTrans").hasClass("initialized") == false) {
ui.generateColSelector({
skipFirstCol:true
}).appendTo($("#dialogImportRPGMTrans .targetCol"));
$("#dialogImportRPGMTrans .importRPGMTransPathType").on("click", function() {
$(this).closest(".importRPGMTransPathTypeWrapper").find("label").removeClass("active");
$(this).closest("label").addClass("active");
var notActive = $(this).closest(".importRPGMTransPathTypeWrapper").find("label").not(".active");
notActive.find(".importRPGMTrans").val("");
notActive.find(".importRPGMTrans").data("files", []);
notActive.find(".selectedFileRemark").html("");
$(this).closest("label").find(".importRPGMTrans").trigger("click");
});
$("#dialogImportRPGMTrans .importRPGMTrans").on("input", function() {
var $this = $(this);
//var text = "";
$this.data("files", $this.val().split(";"))
if ( $this.data("files").length > 1) {
$this.closest("label").find(".selectedFileRemark").html($this.data("files").length+" object selected.");
} else {
$this.closest("label").find(".selectedFileRemark").html($this.val());
}
});
$("#dialogImportRPGMTrans").dialog({
autoOpen: false,
modal:true,
minWidth:640,
minHeight:480,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},buttons: [
{
text: t("Cancel"),
//icon: "ui-icon-heart",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Import"),
//icon: "ui-icon-heart",
click: function() {
var selectedFiles = $("#dialogImportRPGMTrans .importRPGMTransPathTypeWrapper label.active .importRPGMTrans").data("files");
if (typeof selectedFiles == 'undefined' || selectedFiles == '' || selectedFiles.length == 0) return alert("Please select a file/folder");
var columns = $("#dialogImportRPGMTrans .targetCol select").val();
var targetFiles = trans.getCheckedFiles();
if (targetFiles.length == 0) targetFiles = trans.getAllFiles();
var options = {
overwrite: $("#dialogImportRPGMTrans .overwriteTarget").prop("checked"),
files:targetFiles
}
$(this).dialog( "close" );
setTimeout( function() {
trans.importRPGMTrans(selectedFiles, columns, options);
}, 300);
}
}
]
});
$("#dialogImportRPGMTrans").addClass("initialized");
}
$("#dialogImportRPGMTrans").dialog("open");
return $("#dialogImportRPGMTrans");
}
ui.openExportDialog = function(options) {
options = options || {};
if ($("#dialogExport").hasClass("initialized") == false) {
$("#dialogExport").dialog({
autoOpen: false,
modal:true,
minWidth:480,
minHeight:320,
maxWidth:640,
maxHeight:420,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
}
});
$("#dialogExport").addClass("initialized");
}
$("#dialogExport").data("options", options);
$("#dialogExport").dialog("open");
return $("#dialogExport");
}
ui.closeExportDialog = function() {
if ($("#dialogExport").hasClass("initialized")) {
$("#dialogExport").dialog("close");
}
}
ui.openRevertToOriginalDialog = async function(defaultPath = "", options) {
try {
defaultPath = defaultPath || trans.project.devPath
} catch (e) {
defaultPath = "";
}
return new Promise((resolve, reject)=> {
var $popup = $("#ui_revertToOrigin");
if ($popup.length == 0) {
var dvField = new DVField();
$popup = $("<div id='ui_revertToOrigin'></div>");
var $content = ($(`
<div>
<h2 data-tran="">${t(`Revert to origin data`)}</h2>
<div data-tran="">
${t(`Select target directory.`)}<br />
<span class="red">${t(`The existing files will be overwritten!`)}</span>
</div>
<label>
<input type="dvSelectPath" nwdirectory class="fullWidth targetPath" value="${defaultPath}" />
</label>
</div>`));
console.log("rendering ", $popup);
dvField.renderSelectPath($content.find("[type=dvSelectPath]"));
$popup.empty();
$popup.append($content);
}
$popup.dialog({
title: t("Revert to origin data"),
autoOpen: false,
modal:true,
width:640,
height:240,
minWidth:640,
minHeight:240,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
close:function( event, ui ) {
var value = $("#ui_revertToOrigin .targetPath").val();
$("#ui_revertToOrigin").remove();
resolve(value || "");
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$("#ui_revertToOrigin .targetPath").val("");
$(this).dialog( "close" );
}
},
{
text: t("Process"),
click: async function() {
var $this = $(this)
var to = $this.find(".targetPath").val()
if (!to) return alert(t("Path to the directory can not be empty!"));
if (await common.isDirectory(to) == false) return alert(t('Invalid directory:')+to);
$(this).dialog("close");
}
}
]
});
$popup.find("#ui_revertToOrigin .defaultPath").val(defaultPath);
$popup.dialog("open");
})
}
ui.dialogProjectIsExist = function(existedData, options) {
existedData = existedData||[];
console.log(arguments);
options = options||{};
var thisTitle = existedData[0]['title'];
$("#dialogProjectIsExist").find(".dialogGameTitle").html(thisTitle);
$("#dialogProjectIsExist .existedCache").empty();
for (var i=0; i<existedData.length; i++) {
var template = $("<li class='cacheItem'><ul></ul><div class='projectIsExistAction'></div></li>");
var openButton = $("<button class='openButton'>Open this</button>").on("click", function(e) {
var that = $(this);
$("#dialogProjectIsExist").dialog("close");
trans.procedureCreateProject(options.gameFolder, {
force:"",
projectInfo:that.closest(".cacheItem").data("data")
});
});
var openButton2 = $("<button class='openButton'>"+t("Rebuild translation table from this cache")+"</button>").on("click", function(e) {
var that = $(this);
$("#dialogProjectIsExist").dialog("close");
trans.procedureCreateProject(options.gameFolder, {
force:"true",
projectInfo:that.closest(".cacheItem").data("data")
});
});
template.find(".projectIsExistAction").append(openButton);
template.find(".projectIsExistAction").append(openButton2);
template.data("data", existedData[i]);
if ( existedData[i]['title'] == existedData[i]['Title']) delete(existedData[i]['Title']);
for (var part in existedData[i]) {
let $locTemplate= $("<li><label title='"+part+"'>"+part+"</label></span>"+existedData[i][part]+"</span></li>");
template.find("ul").append($locTemplate);
}
$("#dialogProjectIsExist .existedCache").append(template);
}
if ($("#dialogProjectIsExist").hasClass("initialized") == false) {
$("#dialogProjectIsExist").dialog({
autoOpen: false,
modal:true,
width:Math.round($(window).width()/100*80),
height:Math.round($(window).height()/100*80),
minWidth:600,
minHeight:420,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Create new project"),
icon: "ui-icon-plus",
click: function() {
$(this).dialog( "close" );
console.log("begin creating new project");
trans.procedureCreateProject(options.gameFolder, {
force:true
});
}
},
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$("#dialogProjectIsExist").addClass("initialized");
}
$("#dialogProjectIsExist").dialog("open");
return ($("#dialogProjectIsExist"));
}
// ==============================================================
// LOADING BAR
// ==============================================================
// Table Corner
// ui.tableCornerShowLoading = function(title="") {
// ui._cache = ui._cache || {};
// if (typeof ui._cache.$tppLoader == 'undefined') {
// ui._cache.$tppLoader = $(`<img src="img/tpp-loading-inv.svg" class="tableCornerLoading tppLoader" style="height:16px; max-height:16px" alt="" title="${common.htmlEntities(title)}">`)
// }
// $(".colHeader.cornerHeader").html(ui._cache.$tppLoader);
// }
// ui.tableCornerHideLoading = function() {
// $(".colHeader.cornerHeader").html(" ");
// }
ui._tableCornerLoadingStack = 0;
ui.tableCornerShowLoading = function(title="") {
if(!$("#topCornerLoading").length) {
$(`<style id="topCornerLoading">
.handsontable.ht_clone_top_left_corner .wtHider .htCore > thead > tr > th {
background-image: url(img/tpp-loading-inv.svg);
background-repeat: no-repeat;
background-position: center;
}
<style>`).appendTo("head");
}
if (title) {
$(".handsontable.ht_clone_top_left_corner .wtHider .htCore > thead > tr > th").attr("title", title)
}
this._tableCornerLoadingStack += 1;
}
ui.tableCornerHideLoading = function(force) {
this._tableCornerLoadingStack -= 1;
if (this._tableCornerLoadingStack <= 0 || force) {
$("#topCornerLoading").remove();
$(".handsontable.ht_clone_top_left_corner .wtHider .htCore > thead > tr > th").attr("title", "")
this._tableCornerLoadingStack = 0;
}
}
ui.isLoadingOverlayVisible = function() {
return $("#loadingOverlay").is(":visible");
}
ui.showLoading = function(options) {
/*
options.buttons = [{
text: "text to display",
onClick : function
}]
*/
options = options||{};
options.buttons = options.buttons||[];
$("#applicationBar .appActionsLeft").hide();
// autofix direct options.buttons object
if (Array.isArray(options.buttons) == false) {
if (typeof options.buttons.text !== "undefined") options.buttons = [options.buttons];
}
ui.consoleIsShown = true;
$("#loadingOverlay .console").empty();
$("#loadingOverlay .loadingBarProgress").empty();
//$("#loadingOverlay .console").addClass("stickToBottom");
$("#loadingOverlay .loadingBarProgress").removeClass("stopped");
$("#loadingOverlay .loadingBarProgress").removeClass("error");
$(".loadingBarButtons").empty();
for (var i=0; i<options.buttons.length; i++) {
var thisButton = $("<a href='#'>"+options.buttons[i].text+"</a>");
if (typeof options.buttons[i].onClick == 'function') {
thisButton.data("onClick", options.buttons[i].onClick)
thisButton.on("click", function(e) {
$(this).data("onClick").call(this);
});
}
$(".loadingBarButtons").append(thisButton);
}
if ($("#loadingOverlay").hasClass("initialized") == false) {
$("#loadingOverlay").addClass("initialized");
ui.loadingInit();
}
ui.appBarTheme("dark");
$("#loadingOverlay").removeClass("hidden");
$(document).trigger("showLoading");
ui.log("Log started!");
ui._logTimeStart = Date.now();
if (nw.process.versions["nw-flavor"] == "sdk") ui.log(t("You can view the more detailed information on console log (F12)"));
return $("#loadingOverlay");
}
ui.hideLoading = function(destroy) {
ui.consoleIsShown = false;
destroy = destroy||false;
$("#loadingOverlay .loadingStatus").text("");
if (destroy) {
$("#loadingOverlay .console").empty();
}
$("#loadingOverlay").addClass("hidden");
ui.appBarTheme("");
$("#applicationBar .appActionsLeft").show();
//$(document).trigger("hideLoading");
/**
* Triggered when loading console closed
* @event ui#loadingScreenIsClosed
* @since 4.3.20
*/
ui.trigger("loadingConsoleClosed")
return $("#loadingOverlay");
}
ui.loadingClearButton = function() {
$(".loadingBarButtons").empty();
}
ui.showCloseButton = function(options) {
options=options||{};
var $loadingBarBtn = $(".loadingBarButtons");
if ($loadingBarBtn.find(".closeButton").length > 0) return;
var thisButton = $("<a class='closeButton icon-cancel-1' href='#'>"+t("Close")+"</a>");
thisButton.on("click", function(e) {
ui.hideLoading.call(this, true);
ui.loadingClearButton();
});
$loadingBarBtn.append(thisButton);
}
ui.showOpenCacheButton = function(target, options) {
options=options||{};
if (typeof target == 'undefined') return false;
$(".loadingBarButtons").find(".openCache").remove();
var thisButton = $("<a href='#' class='openCache icon-folder-open'>Open Cache</a>");
thisButton.on("click", function(e) {
//var thisTmpPath = str_ireplace("\\", "\\\\", target);
//console.log("running command : \r\n"+'explorer "'+thisTmpPath+'"');
require('child_process').exec('explorer "'+target+'"' , function (err, stdout, stderr) { console.log("Explorer opened") });
});
$(".loadingBarButtons").append(thisButton);
}
ui.LoadingAddButton = function(text, onClick, options) {
options=options||{};
options.class=options.class||"";
if (typeof text == 'undefined') return false
if (typeof onClick !== 'function') onClick = function(){};
text = text||"";
options.a = options.a||"#";
var thisButton = $("<a class='"+options.class+"' href='"+options.a+"'>"+text+"</a>");
thisButton.on("click", function(e) {
onClick.call(this);
});
$(".loadingBarButtons").append(thisButton);
return thisButton;
}
ui.stickToBottom = function($elm) {
if ($elm.length == 0) return $elm;
console.log($elm[0].scrollTop+"+"+$elm.height()+" >= "+$elm[0].scrollHeight);
if (($elm[0].scrollTop+$elm.height() >= $elm[0].scrollHeight)) {
$elm[0].scrollTop=$elm[0].scrollHeight;
}
return $elm;
}
ui.loadingProgress = async function(percent, status, options) {
/*
options.mode = consoleOutput -> no pre wrapper
*/
var $loading = $("#loadingOverlay");
options = options||{};
options.consoleOnly = options.consoleOnly||false;
options.mode = options.mode||"";
options.classStr = options.classStr||"";
if (typeof percent == 'string') {
//$loading.find(".loadingBarProgress").css("width", 100+"%");
$loading.find(".loadingBarProgress").css("left", "0%");
$loading.find(".loadingBarOverlay").text(percent);
} else if (typeof percent !== 'undefined') {
percent = percent||0;
percent = Math.round(percent);
//$loading.find(".loadingBarProgress").css("width", percent+"%");
$loading.find(".loadingBarProgress").css("left", (-100+percent)+"%");
$loading.find(".loadingBarOverlay").text(percent+"%");
}
var classStr = "";
if (options.classStr) {
classStr = ' class="'+options.classStr+'"';
}
if (typeof status !== "undefined") {
if (options.consoleOnly == false) {
$loading.find(".loadingStatus").text(status);
}
var console = $("#loadingOverlay .console");
if (options.mode == "consoleOutput") {
console.append("<span"+classStr+">"+status+"</span>");
} else {
console.append("<pre"+classStr+">"+status+"</pre>");
}
/*
if (console.hasClass("stickToBottom")) {
console[0].scrollTop=console[0].scrollHeight;
}
*/
return status;
}
}
ui.log = async function(message) {
const maxWaitTime = 250; // half second for node change is already too slow
var $console = $("#loadingOverlay .console");
if (!$console.is(":visible")) return console.log(message);
var texts = [];
for (var i=0; i<arguments.length; i++) {
if (typeof arguments[i] !== "string") {
texts.push(JSON.stringify(arguments[i], undefined, 2));
} else {
texts.push(arguments[i]);
}
}
if (ui.logGetConfig().type) {
$console.append(`<pre data-type="${ui.logGetConfig().type}">${texts.join("\n ")}</pre>`);
} else {
$console.append("<pre>"+texts.join("\n ")+"</pre>");
}
console.log.apply(this, arguments);
var resolver;
var promise = new Promise((resolve, reject) => {
resolver = resolve;
ui.one("logIsAdded", async ()=>{
resolve();
});
})
window.setTimeout(()=>{
resolver();
}, maxWaitTime)
return promise;
}
ui.logSetConfig = function(config = {}) {
this.logConfig = config;
}
ui.logGetConfig = function() {
return this.logConfig || {};
}
ui.logError = async function() {
this.logSetConfig({type:"error"});
await this.log.apply(this, Array.from(arguments));
this.logSetConfig({type:undefined});
return;
}
ui.loadingInit = function() {
if (this.loadingObserverIsInitialized) return;
// Select the node that will be observed for mutations
const targetNode = $("#loadingOverlay")[0];
// Options for the observer (which mutations to observe)
const config = { attributes: false, childList: true, subtree: true };
// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
ui.trigger("logIsAdded");
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
this.loadingObserverIsInitialized = true;
}
ui.loadingEnd = function(percent, status, options) {
options = options||{};
console.log("Loading end", arguments);
var elapsed = Date.now() - ui._logTimeStart;
ui.log("Log ended!");
ui.log("Elapsed time : "+elapsed+"ms");
ui.loadingProgress(percent, status, options);
var $loading = $("#loadingOverlay");
options.error = options.error || false;
var thisClass = "stopped";
if (options.warning) thisClass = "warning";
if (options.error) thisClass = "error";
$loading.find(".loadingBarProgress").addClass(thisClass);
ui.showCloseButton();
}
ui.setWindowTitle=function(title) {
title = title||trans.currentFile.replace(/^.*[\\\/]/, ''); // eslint-disable-line
nw.appSuffix = nw.appSuffix||"";
var suffix = "";
if (nw.appSuffix) {
suffix = " "+nw.appSuffix;
}
var applicationTitle = "Translator++ Ver."+nw.App.manifest.version+suffix;
if (title.length > 0) {
applicationTitle = title+" - Translator++ Ver."+nw.App.manifest.version+suffix;
$(".appTitle").text(applicationTitle);
return $("title").text(applicationTitle);
}
$(".appTitle").text(applicationTitle);
return $("title").text(applicationTitle);
}
ui.setStatusBar = function(index, content) {
$(".footer .footer-content").eq(index).find("span").html(content);
}
ui.updateEditorStatus = function() {
var $editorContent = $(".footer-content.footer2 > span");
var $editorStatus = $editorContent.find(".editorStatus");
if ($editorContent.find(".editorStatus").length < 1) {
$editorStatus = $("<span class='editorStatus'><span class='keyLength'>keylength</span><span class='keyLength'>keylength</span></span>");
$editorContent.append($editorStatus);
}
}
ui.initTextResizer = function() {
var $elm = $(".resizeFont");
$elm.each(function() {
var hookName = $(this).data("for");
if (Boolean(hookName) == false) return;
var currentSize = sys.getConfig("textSize"+hookName) || 100;
var $targetElm = $(hookName);
$targetElm.css("font-size", currentSize+"%");
$targetElm.data("currentSize", currentSize);
})
}
ui.openTextResizer = function(hookTo, $targetElm, options) {
console.log("text resizer opened");
if (typeof hookTo == 'undefined') return false;
if (hookTo.length == 0) return false;
options = options||{};
options.default = options.default||100;
$("#textSlider .textResizer").data("target", $targetElm);
$("#textSlider .textResizer").data("targetString", hookTo.attr("data-for"));
$("#textSlider").removeClass("hidden");
$("#textSlider .textResizer")[0].focus();
$("#textSlider").position({
my: "center top",
at: "center bottom",
of: hookTo,
collision : "fit flip"
});
$(document).on("mouseup.resizer", function(e) {
var container = $("#textSlider");
if (!container.is(e.target) && container.has(e.target).length === 0) {
container.addClass("hidden");
$(document).off("mouseup.resizer");
sys.saveConfig();
}
});
var thisDefault = $targetElm.data("currentSize") || 100;
$("#textSlider .textResizeValue").val(thisDefault+"%");
$("#textSlider .textResizer").val(thisDefault);
$("body").scrollTop(0)
if ($("#textSlider").hasClass('rendered') == false) {
$("#textSlider .textResizer").on("input", function(e) {
$(this).data("target").css("font-size", $(this).val()+"%");
$(this).data("target").data("currentSize", $(this).val())
$("#textSlider .textResizeValue").val($(this).val()+"%");
//console.log("size", $(this).val(), "hookTo", $(this).data("targetString"));
sys.setConfig("textSize"+$(this).data("targetString"), $(this).val())
ui.trigger("textSizeChanged", $(this).val(), $(this).data("targetString"));
if ($(this).data("target").is("#currentCellText")) {
console.log("current text resize");
ui.generateBackgroundNumber($("#currentCellText"), undefined, true);
ui.redrawBackgroundHelper();
}
});
$("#textSlider button").eq(0).on("click", function(e) {
var textResizer =$("#textSlider .textResizer");
var newValue = parseInt(textResizer.val())-parseInt(textResizer.attr('step'));
if (newValue < parseInt(textResizer.attr("min"))) newValue = parseInt(textResizer.attr("min"));
textResizer.val(newValue);
textResizer.trigger("input");
});
$("#textSlider button").eq(1).on("click", function(e) {
var textResizer =$("#textSlider .textResizer");
var newValue = parseInt(textResizer.val())+parseInt(textResizer.attr('step'));
if (newValue > parseInt(textResizer.attr("max"))) newValue = parseInt(textResizer.attr("max"));
textResizer.val(newValue);
textResizer.trigger("input");
});
$("#textSlider .textResizer").on('wheel.resizer', function(event){
// deltaY obviously records vertical scroll, deltaX and deltaZ exist too
if(event.originalEvent.deltaY < 0){
//wheeled up
//console.log("wheel up");
$("#textSlider button").eq(1).trigger("click");
}
else {
//wheeled down
//console.log("wheel down");
$("#textSlider button").eq(0).trigger("click");
}
});
$("#textSlider").addClass('rendered');
}
}
/*
var _consoleLog = console.log;
console.log = function(string) {
_consoleLog.call(this, string);
if (ui.consoleIsShown) {
$("#loadingOverlay .console").append("<pre>"+string+"</pre>");
}
}
*/
ui.closeAllChildWindow = function(force) {
for (var thisWin in ui.windows) {
if (ui.windows[thisWin]) {
if (ui.windows[thisWin].win) {
ui.windows[thisWin].win.close(force);
} else {
ui.windows[thisWin].close(force);
}
}
}
}
ui.contextToolFetchSelected = function() {
/*
returns array of selected context
$("#dialogContextTool .contextSelector");
or
$("#dialogContextTool .contextSelectorText").val();
*/
var contextSelector = $("#dialogContextTool .contextSelector");
var context = contextSelector.val();
context = context||[];
var textContent = $("#dialogContextTool .contextSelectorText").val();
var textContentA = [];
if (textContent) {
textContentA = textContent.split("\n").map(function(input) {
return common.stripCarriageReturn(input);
});
}
var resultArray = [];
for (let i=0; i<context.length; i++) {
if (Boolean(context[i]) == false) continue;
resultArray.push(context[i]);
}
for (let i=0; i<textContentA.length; i++) {
if (Boolean(textContentA[i]) == false) continue;
if (resultArray.indexOf(textContentA[i]) !== -1) continue;
resultArray.push(textContentA[i]);
}
return resultArray;
}
ui.contextToolDialog = function() {
ui.showBusyOverlay();
var contextKeywords = trans.collectContextKeyword();
var contextSelector = $("#dialogContextTool .contextSelector").empty();
contextSelector.append("<option value=''>"+t("-nothing-")+"</option>");
for (var context in contextKeywords) {
contextSelector.append("<option value='"+context+"'>"+context+" ("+contextKeywords[context]+") items</option>");
}
if ($("#dialogContextTool").hasClass("initialized") == false) {
$("#dialogContextTool").dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:480,
minWidth:480,
minHeight:420,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog("close");
}
},
{
text: t("Ok"),
icon: "ui-icon-close",
click: function() {
var $actionSet = $(".contextAction");
if ($actionSet.find( "input:checked" ).length == 0) {
var conf = confirm(t("No action selected, are you sure?"));
if (conf) {
$(this).dialog("close");
return false;
}
}
var selectedAction = $actionSet.find( "input:checked" ).val();
console.log("action is", selectedAction);
var targetArray = ui.contextToolFetchSelected();
if (targetArray.length < 1) {
alert(t("No context's keyword specified!"));
return false;
}
if (selectedAction == "actionRemoveSelected") {
let conf = confirm(t("Remove context containing keyword :\n")+targetArray.join(", ")+t("\nfrom project?"));
if (conf) {
trans.removeRowByContext(undefined, targetArray, {
matchAll:$("#dialogContextTool .matchAll").prop("checked")
});
$(this).dialog( "close" );
}
} else if (selectedAction == "actionRemoveButSelected"){
let conf = confirm(t("Remove every rows except rows that has a context containing keyword :\n")+targetArray.join(", ")+t("\nfrom project?"));
if (conf) {
trans.removeRowByContext(undefined, targetArray, {
matchAll:$("#dialogContextTool .matchAll").prop("checked")
}, true);
$(this).dialog( "close" );
}
}
$(this).dialog( "close" );
}
}
]
});
$("#dialogContextTool").addClass("initialized");
}
ui.hideBusyOverlay();
$("#dialogContextTool").dialog("open");
return ($("#dialogContextTool"));
}
ui.batchWrapingDialog = function() {
ui.showBusyOverlay();
var contextKeywords = trans.collectContextKeyword();
var contextSelector = $("#batchWraping .contextSelector").empty();
contextSelector.append("<option value=''>"+t("-nothing-")+"</option>");
for (var context in contextKeywords) {
contextSelector.append("<option value='"+context+"'>"+context+" ("+contextKeywords[context]+") "+t("items")+"</option>");
}
$("#batchWraping .sourceCol").empty();
$("#batchWraping .sourceCol").append(ui.generateColSelector({skipFirstCol:true}));
$("#batchWraping .targetCol").empty();
$("#batchWraping .targetCol").append(ui.generateColSelector({skipFirstCol:true}));
$("#batchWraping .sourceCol select").off("change");
$("#batchWraping .targetCol select").off("change");
$("#batchWraping .sourceCol select").on("change", function(e) {
});
if ($("#batchWraping").hasClass("initialized") == false) {
$("#batchWraping").dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:480,
minWidth:480,
minHeight:320,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Wrap text"),
icon: "ui-icon-close",
click: function() {
if ($("#batchWraping .sourceCol select").val() == $("#batchWraping .targetCol select").val()) return alert(t("Source & target column can not be same!"));
var selectedFiles = trans.getCheckedFiles();
if (selectedFiles.length == 0) {
var conf = confirm(t("No files are selected on file selector pane.\nTranslator++ will assume that all files will be processed\nAre you sure with this?"));
if (!conf) return false;
}
ui.showBusyOverlay();
setTimeout(function() {
trans.wordWrapFiles(selectedFiles, $("#batchWraping .sourceCol select").val(), $("#batchWraping .targetCol select").val(), {
maxLength:$("#batchWraping .maxLength").val(),
context:trans.evalContextsQuery($("#batchWraping .contextSelector").val(), $("#batchWraping .contextSelectorText").val())
});
trans.refreshGrid();
ui.hideBusyOverlay();
}, 250);
$(this).dialog("close");
}
}
]
});
$("#batchWraping").addClass("initialized");
}
ui.hideBusyOverlay();
$("#batchWraping").dialog("open");
return ($("#batchWraping"));
}
ui.translateAllDialog = function() {
var $dialogTranslateAll = $("#dialogTranslateAll");
var $targetColumn = ui.generateColSelector({skipFirstCol:true});
$dialogTranslateAll.find(".targetCol").empty();
$dialogTranslateAll.find(".targetCol").append($targetColumn);
var $sourceColumn = ui.generateColSelector({skipFirstCol:false});
$dialogTranslateAll.find(".columnSelector").empty();
$dialogTranslateAll.find(".columnSelector").append($sourceColumn);
if ($dialogTranslateAll.hasClass("initialized") == false) {
$dialogTranslateAll.find(".translatorSelector").empty();
for (var i=0; i<trans.translator.length; i++) {
console.log("creating option : "+trans.translator[i]);
$dialogTranslateAll.find(".translatorSelector").append("<option value='"+trans.translator[i]+"'>"+trans[trans.translator[i]].name+"</option>");
}
$dialogTranslateAll.find(".translatorSelector").val(trans.getActiveTranslator());
var tags = new UiTags();
this._uiTagsTrans = tags;
$dialogTranslateAll.find(".colorTagSelector").empty();
$dialogTranslateAll.find(".colorTagSelector").append(tags.element);
$dialogTranslateAll.dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:400,
minWidth:480,
minHeight:320,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Translate Now"),
icon: "ui-icon-plus",
click: function() {
var thisTrans = $("#dialogTranslateAll .translatorSelector").val()
if (!thisTrans) {
alert(t("Please select translator engine"));
return false;
}
trans[thisTrans].targetColumn = parseInt($("#dialogTranslateAll .targetCol select").val());
//trans.translateAll(thisTrans, {});
var options = ui._uiTagsTrans.getValue();
if (Boolean(options)==false) return; // tag selected but no action
$(this).dialog( "close" );
var sourceColumn = parseInt($("#dialogTranslateAll .sourceCol select").val());
options = options || {};
options.translateOther = $("#dialogTranslateAll .translateOther").prop("checked"),
options.ignoreTranslated = $("#dialogTranslateAll .untranslatedOnly").prop("checked")
options.playSoundOnComplete = $("#dialogTranslateAll .playSoundOnComplete").prop("checked");
options.overwrite = $("#dialogTranslateAll .overwrite").prop("checked");
options.saveOnEachBatch = $("#dialogTranslateAll .saveOnEachBatch").prop("checked");
if (sourceColumn) {
options.keyColumn = sourceColumn;
if (trans[thisTrans].targetColumn == options.keyColumn) return alert(t("Can not process your request because the source column and target column are same!"));
}
console.log(options);
trans.translateAll(thisTrans, options);
}
}
]
});
$dialogTranslateAll.addClass("initialized");
}
$dialogTranslateAll.dialog("open");
return ($dialogTranslateAll);
}
/**
* Create wordWrapperByTag DOM element
* @param {} options
*/
ui.drawWordWrapByTagField = function(options) {
var $wrapper = $(`
<div class="wordWrapByTag fieldSet" data-type="wordWrapByTag">
<table class="fullWidth">
<thead>
<tr>
<td>Tags</td>
<td>Maximum length</td>
<td> </td>
</tr>
</thead>
<tbody class="resultSet">
</tbody>
</table>
<hr />
<button class="addRule"><i class="icon-list-add"></i> Add rows</button>
</div>`);
$wrapper.data("getValue", function() {
var result = [];
var $rows = $wrapper.find(".wordWrapTagField");
for (var i=0; i<$rows.length; i++) {
var $thisRow = $rows.eq(i);
var maxLength = parseInt($thisRow.find(".maxLength").val());
if (empty(maxLength)) continue;
var tags = $thisRow.find(".wordWrapTags").data("value");
if (empty(tags)) continue;
result.push({
maxLength:maxLength,
tags:tags
});
}
return result;
});
$wrapper.data("saveValue", function() {
console.log("saving value");
trans.setOption("wordWrapByTags", $wrapper.data("getValue")());
});
var $field = $(`
<tr class="wordWrapTagField fullWidth">
<td><input type="text" class="wordWrapTags" /></td>
<td><input type="number" class="maxLength" min="1" max="1000" /></td>
<td><button title="Remove this row"><i class="icon-cancel-1"></i></button></td>
</tr>`);
$field.find("button").on("click", function() {
$(this).closest(".wordWrapTagField").remove();
$wrapper.data("saveValue")();
});
var addField = (defaultVal) => {
defaultVal = defaultVal || {};
var $fieldCopy = $field.clone(true, true);
var tagSelector = new UiTagSelector($fieldCopy.find(".wordWrapTags"), {default:defaultVal.tags});
$wrapper.find(".resultSet").append($fieldCopy);
if (defaultVal.maxLength) $fieldCopy.find(".maxLength").val(defaultVal.maxLength);
tagSelector.on("input", ()=> {
$wrapper.data("saveValue")();
});
$wrapper.find(".maxLength").on("change", ()=>{
$wrapper.data("saveValue")();
})
}
$wrapper.find(".addRule").on("click", () => {
addField();
});
// setting up default
if (!empty(trans.getOption("wordWrapByTags"))) {
var settings = trans.getOption("wordWrapByTags");
for (var i=0; i < settings.length ; i++ ) {
(()=>{
var thisSetting = settings[i];
addField(thisSetting);
})()
}
}
return $wrapper;
}
ui.exportPreparationDialog = function(path, options) {
console.log("Export preparation", options);
options = options||{};
options.onDone = options.onDone||function(){}
options.useTagSelection ||= false;
options.wordWrapOption ||= false;
var $dialogExport = $("#dialogExportPreparation")
$dialogExport.data("onDone", options.onDone);
$dialogExport.find(".exportPath").val(path);
this.lastTags = new UiTags();
$dialogExport.find(".colorTagSelector").empty();
if (options.useTagSelection) {
$dialogExport.find(".tagSelection").removeClass("hidden");
$dialogExport.find(".colorTagSelector").append(this.lastTags.element);
} else {
$dialogExport.find(".tagSelection").addClass("hidden");
}
$dialogExport.find(".sheetOption").remove();
$dialogExport.find(".infoSpreadsheetExport").remove();
if (options.sheetOption) {
$dialogExport.prepend(`
<div class="infoSpreadsheetExport blockBox infoBlock withIcon" data-tran="">
<b>About editing exported spreadsheet file using MS Excel</b><br />
Please note that Microsoft Excel has known compatibility issues when editing UTF-8 formatted spreadsheets.
To avoid any problems, it is recommended to use an alternative spreadsheet editor such as OpenOffice, LibreOffice, or Google Sheets.
</div>`)
var $section = $(`
<div class="dialogSection sheetOption">
<h2 data-tran="">Export to table format</h2>
<div class="wrapper">
<label class="flex fullWidth bottomSpace">
<div class="flexMain">
<div class="label" data-tran="">Include header</div>
<div class="info" data-tran="">Print column header on the first row of the data.</div>
</div>
<div>
<input type="checkbox" name="includeColumnHeader" class="flipSwitch includeColumnHeader" value="1" checked="" />
</div>
</label>
</div>
</div>`);
$("#dialogExportPreparation").append($section);
} else if (trans.project.gameEngine == "spreadsheet") {
$dialogExport.prepend(`
<div class="infoSpreadsheetExport blockBox infoBlock withIcon" data-tran="">
<b>About editing exported spreadsheet file using MS Excel</b><br />
Please note that Microsoft Excel has known compatibility issues when editing UTF-8 formatted spreadsheets.
To avoid any problems, it is recommended to use an alternative spreadsheet editor such as OpenOffice, LibreOffice, or Google Sheets.
</div>`)
}
if (options.wordWrapOption) {
var $wordWrapByTag = this.drawWordWrapByTagField(options);
$dialogExport.find(".wordWrapByTag .wrapper").empty();
$dialogExport.find(".wordWrapByTag").removeClass("hidden");
$dialogExport.find(".wordWrapByTag .wrapper").append($wordWrapByTag);
} else {
$dialogExport.find(".wordWrapByTag .wrapper").empty();
$dialogExport.find(".wordWrapByTag").addClass("hidden");
}
// settingUp customFieldOptions
let enginesFieldOptions = engines.current().getProperty("exportOptionFields");
var customFields;
const $customFieldsWrapper = $dialogExport.find(".customFields");
$customFieldsWrapper.empty();
(async ()=> {
if (enginesFieldOptions) {
customFields = new CustomFields($customFieldsWrapper, enginesFieldOptions);
await customFields.until("ready");
}
engines.handler('onOpenExportDialogReady').call(this, $dialogExport, options);
})()
if ($dialogExport.hasClass("initialized") == false) {
$dialogExport.dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:480,
minWidth:640,
minHeight:480,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Export Now"),
icon: "ui-icon-plus",
click: function() {
var $dialogExport = $("#dialogExportPreparation");
var thisOptions = ui.lastTags.getValue();
if (thisOptions === false) return false;
var thisOnDone = $(this).data("onDone");
if (typeof thisOnDone !== 'function') return console.log("thisOnDone is not a function");
console.log("Tags : ", thisOptions);
// get value from wrapper options
if (options.wordWrapOption) {
thisOptions.wordWrapByTags = trans.getOption("wordWrapByTags") || [];
}
if (options.sheetOption) {
thisOptions.sheetOption = {};
thisOptions.sheetOption.includeHeader = $dialogExport.find(".includeColumnHeader").prop("checked");
}
if (customFields) {
thisOptions.custom = customFields.getValues();
}
console.log("Export options:", thisOptions);
thisOnDone.call(this, thisOptions);
$(this).dialog( "close" );
}
}
]
});
$("#dialogExportPreparation").addClass("initialized");
}
$("#dialogExportPreparation").dialog("open");
return $("#dialogExportPreparation");
}
ui.taggingDialog = function(cellSelection, options) {
console.log("taggingDialog", arguments);
options = options||{};
options.onDone = options.onDone||function(){}
var $dialogContent = $("#dialogSetTags");
ui._tagSelector = new UiTags({
options : $(`
<h2 data-tran="">${t('Action')}</h2>
<div class="actionSet">
<label class="flex"><input type="radio" name="tagAction" class="appendTags" value="appendTags" /> <span data-tran="">${t('Append tags')}</span></label>
<label class="flex"><input type="radio" name="tagAction" class="removeTags" value="removeTags" /> <span data-tran="">${t('Remove tags')}</span></label>
<label class="flex"><input type="radio" name="tagAction" class="setTags" value="setTags" /> <span data-tran="">${t('Set tags')}</span></label>
<label class="flex"><input type="radio" name="tagAction" class="actionNone" value="" /> <span data-tran="">${t('Do nothing')}</span></label>
</div>
`)
});
$dialogContent.find(".colorTagSelector").empty();
$dialogContent.find(".colorTagSelector").append(ui._tagSelector.element);
if ($dialogContent.hasClass("initialized") == false) {
console.log("initializing dialogSetTags");
$dialogContent.dialog({
autoOpen: true,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:500,
height:320,
minWidth:500,
minHeight:320,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog("close");
}
},
{
text: t("Ok"),
icon: "ui-icon-plus",
click: function() {
var tags = ui._tagSelector;
console.log("Tag object:", tags);
var tagsData = tags.getValue();
var tagList = tagsData.filterTag;
var action = tagsData.filterTagMode;
if (tagsData === false) return false;
$(this).dialog( "close" );
if (action == "appendTags") {
trans.setTagForSelectedRow(tagList, cellSelection, undefined, {append:true});
} else if (action == "setTags") {
trans.setTagForSelectedRow(tagList, cellSelection, undefined, {append:false});
} else if (action == "removeTags") {
trans.removeTagForSelectedRow(undefined, cellSelection, tagList)
}
}
}
]
});
}
$dialogContent.dialog("open");
return $dialogContent;
}
/**
* Set Current Cell Text
* @param {String} value - New value
* @param {Boolean} trigger - Immidiately trigger change event
* @since 4.12.11
*/
ui.setCurrentCellText = function(value, trigger) {
var $currentCellText = $("#currentCellText")
if ($currentCellText.prop("disabled")) return;
if ($currentCellText.prop("readonly")) return;
$currentCellText.val(value);
if (trigger) $currentCellText.trigger("change")
}
ui.toggleWordWrapCurrentCellPane = function(state=false) {
var $currentCellText = $("#currentCellText");
if (state) {
$(".currentCellTextCtrl .wordWrap").addClass("checked");
$currentCellText.addClass("pre");
ui.generateBackgroundNumber();
} else {
$(".currentCellTextCtrl .wordWrap").removeClass("checked");
$currentCellText.removeClass("pre");
ui.clearBackgroundNumber();
}
sys.setConfig("wordWrapCurrentCellPane", state);
sys.saveConfig();
}
ui.toggleWordWrapRomajiPane = function(state=false) {
if (state) {
$("#currentRomaji .text").css("white-space", "pre")
$(".cellInfoCtrl .wordWrap").addClass("checked")
} else {
$("#currentRomaji .text").css("white-space", "break-spaces")
$(".cellInfoCtrl .wordWrap").removeClass("checked")
}
sys.setConfig("wordWrapRomajiPane", state);
sys.saveConfig();
}
// ==================================================================
// INTRO WINDOW SECTION
// ==================================================================
ui.introWindowShow = function(options) {
//ui.blurAll();
ui.showRandomTip();
$("#introWindow").fadeIn(200);
//$("#introWindow").removeClass("hidden");
ui.appBarTheme("dark");
this.ribbonMenu.select("start", false)
}
ui.introWindowClose = function(options) {
//ui.unBlurAll();
trans.grid.render();
//$("#introWindow").addClass("hidden");
$("#introWindow").fadeOut(200);
ui.appBarTheme("");
ui.backgroundHelperInitialize();
this.ribbonMenu.select("home", false)
}
ui.showRecentFile = function(num, $target) {
if (Boolean(sys) == false) return;
if (Boolean(sys.config) == false) return;
if (Boolean(sys.config.historyOpenedFiles) == false) return;
$target = $target||$("#introWindow .recentProject");
num = num||1;
$target.empty();
for (var i=0; i<num; i++) {
if (Boolean(sys.config.historyOpenedFiles[i]) == false) continue;
sys.config.historyOpenedFiles[i] = sys.config.historyOpenedFiles[i] || {};
if (JSON.stringify(sys.config.historyOpenedFiles[i]) == "{}") continue;
var thisGameTitle = sys.config.historyOpenedFiles[i].gameTitle||t("-unknown title-");
var thisEngine = "";
let thisPath = sys.config.historyOpenedFiles[i].path || "";
try {
console.log("Path is : ", sys.config.historyOpenedFiles[i].path);
thisEngine = sys.config.historyOpenedProject[sys.config.historyOpenedFiles[i].projectId].gameEngine;
} catch (e) {
//console.warn(e);
}
var $template = $(`<li><i class='icon icon-angle-right'></i><span class='title'></span><span class='date icon-calendar'></span>
<span class="filePath icon-tpp">
<div class="flex"><span class="folderPath">${nwPath.dirname(thisPath)}</span><span class="fileName">\\${nwPath.basename(thisPath)}</span>
</div>
</span></li>`);
$template.find(".title").html(thisGameTitle);
$template.find(".date").html(new Date().toLocaleString());
$template.data("gameData", sys.config.historyOpenedFiles[i]);
if (thisEngine) $template.append("<span class='engine'>"+thisEngine+"</span>");
$template.data("historyIndex", i);
$template.data("engineName", thisEngine);
$target.append($template);
$template.on("click", async function() {
//sys.loadFileHistory($(this).data("historyIndex"));
var transPath = $(this).data("gameData").path;
if (!await common.isFileAsync(transPath)) return alert(t("Can not open file. File not exist."))
trans.open(transPath);
ui.introWindowClose();
})
}
if ($target.find("li").length == 0) {
let $template = $(`<li title='`+t('Go to online documentation.')+`'>
<i class='icon icon-angle-right mainIconRight'></i>
<span class='title'><i class="icon-info-circled-1"></i>`+t('No projects yet')+`</span>
<span>`+t(`Are you new to Translator++?<br />
Please read our online documentation at <b>dreamsavior.net</b>.<br />
Press <b>F1</b> to open online help.<br />
Contact me at <b>patreon.com/dreamsavior</b> for question and bug reports.
`)+
`</span>
</li>`);
$template.on("click", function() {
nw.Shell.openExternal('http://dreamsavior.net/docs/');
})
$target.append($template);
}
return $target;
}
ui.showRandomTip = function($container) {
let $tipPlaceHolder = $(".tipsPlaceHolder > div");
var $item = $tipPlaceHolder[Math.floor(Math.random()*$tipPlaceHolder.length)];
$item = $($item).clone(true, true);
$container = $container || $(".tipsContent");
$container.html(ui.render($item));
return $item;
}
ui.warning = function(msg, title, options) {
options = options||{};
options.onDone = options.onDone||function(){}
title = title||"Warning";
$("#warningDialog").data("onClose", options.onDone);
if ($("#warningDialog").length == 0) {
$("#template").append("<div id='warningDialog' class='warningDialog' title='Warning'><h1 class='icon-attention warningTitle'>"+t("Warning")+"</h1><p class='warningContent'></p></div>");
$("#warningDialog .warningContent").html(msg);
$("#warningDialog .warningTitle").html(title);
$("#warningDialog").dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:320,
minWidth:640,
minHeight:320,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$("[aria-describedby='warningDialog']").find(".ui-dialog-title").prepend("<span class='icon-attention'></span>");
} else {
$("#warningDialog .warningContent").html(msg);
$("#warningDialog .warningTitle").html(title);
}
$("#warningDialog .warningContent a").on("click", function(e) {
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
});
$("#warningDialog").dialog("open");
return $("#warningDialog");
}
ui.confirmRunScript = async function(options) {
return new Promise((resolve) => {
options = options||{};
const $dialog = $(`<div>
<h1 class='icon-attention warningTitle'>${t("You are about to run a user script!")}</h1>
<p class='warningContent'>You are about to execute a user script that is not a part of Translator++. Please be aware that running a malicious script can cause harm to your computer. Only proceed if you fully understand the consequences and trust the source of the script.</p>
</div>`)
var result = false;
$dialog.dialog({
autoOpen: false,
title:"⚠️Warning: Running User Script⚠️",
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:640,
height:320,
minWidth:640,
minHeight:320,
classes: {
"ui-dialog": "highlight warning dialogTopMost"
},
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
open: function() {
// make topmost
console.log("this", this);
console.log("setting z-index for", $(this).closest(".ui-dialog[role='dialog']"));
$(this).closest(".ui-dialog[role='dialog']").css("z-index", "9000")
},
close: ()=> {
resolve(result);
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
/*
{
text: t("View the code"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
*/
{
text: t("Execute the script"),
icon: "ui-icon-close",
click: function() {
result = true;
$(this).dialog( "close" );
}
}
]
});
//$("[aria-describedby='warningDialog']").find(".ui-dialog-title").prepend("<span class='icon-attention'></span>");
$dialog.dialog("open");
$dialog.css("z-index", "9000 !important")
})
}
// ==============================================================
// TRANSLATOR PANE
// ==============================================================
ui.openTranslatorPane = function(param, options) {
param = param||"";
options = options||{};
var targetWidth = $(".fileListWrapperOuter").outerWidth();
var targetHeight = $(".fileListWrapperOuter").outerHeight()-48;
var posTop = $(".fileListWrapperOuter").offset().top + window.screenY+48;
var posLeft = $(".fileListWrapperOuter").offset().left + window.screenX;
ui.windows['translator'] = window.open("translator.html#"+param, "translator", "width="+targetWidth+",height="+targetHeight+",left="+posLeft+",top="+posTop+",fullscreen=no");
//$(".menu-button.addNote").addClass("checked");
}
ui.undockTranslatorPane = function() {
if ($("#translationPane").attr("src") == "") return false;
if (ui.windows['translator']) return "Translator window is already opened!";
var translationWindow = $("#translationPane")[0].contentWindow;
var lastText = "";
try {
lastText = translationWindow.translator.last.text;
} catch(err) {
lastText = "";
}
$(".menu-button.undockPane").addClass("checked");
$(".menu-button.translationPane").prop("disabled", true);
$(".panel-left .fileListButton").trigger("click");
$("#translationPane").attr("src", "");
ui.openTranslatorPane(lastText);
}
ui.dockTranslatorPane = function(lastText, dontClose) {
console.log("running : ui.dockTranslatorPane");
if (ui.windows['translator']) {
lastText = "";
try {
lastText = ui.windows['translator'].translator.last.text;
} catch(err) {
lastText = "";
}
if (!dontClose) {
ui.windows['translator'].close();
}
}
$("#translationPane").attr("src", "translator.html#"+lastText);
$(".menu-button.undockPane").removeClass("checked");
$(".menu-button.translationPane").prop("disabled", false);
}
ui.toggleDockTranslatorPane = function() {
if (ui.windows['translator']) { //undocked
ui.dockTranslatorPane();
} else {
ui.undockTranslatorPane();
}
}
ui.resize = {};
ui.resize.leftPane = function(size) {
size = size||200;
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.leftPane = size;
if (typeof size == 'number') size = size+"px"
$(".panel-right").css("overflow", "auto");
$(".panel-left").css("width", size);
$(".panel-right").css("overflow", "hidden");
trans.refreshGrid();
}
ui.resize.editorWidth = function(size) {
size = size || "30%";
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.editorWidth = size;
if (typeof size == 'number') size = size+"px"
$(".cellInfoPartsA").width(size);
}
ui.resize.editorHeight = function(size) {
size = size || "calc(100vh - 180px)";
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.editorHeight = size;
if (typeof size == 'number') size = size+"px"
$(".panel-wrapper").css("height", size);
trans.refreshGrid();
ui.fixCellInfoSize();
}
ui.resize.reset = function() {
ui.resize.leftPane();
ui.resize.editorWidth();
ui.resize.editorHeight();
trans.grid.render();
}
ui.resize.collapse = function(target) {
$(".panel-left").addClass("hidden");
$(".panelLeftTabHandler > i").removeClass("flip");
trans.grid.render();
}
ui.resize.unCollapse = function(target) {
$(".panel-left").removeClass("hidden");
$(".panelLeftTabHandler > i").addClass("flip");
trans.grid.render();
}
ui.resize.toggleCollapse = function(target) {
if ($(".panel-left").hasClass('hidden')) {
ui.resize.unCollapse()
} else {
ui.resize.collapse()
}
}
ui.resize.init = function() {
//var $currentRomaji = $("#currentRomaji");
var $cellInfoContent = $(".cellInfoTabContent");
$(".panel-wrapper").resizable({
handles:'s',
start:function(e, thisUi) {
$(document).trigger("onCellInfoResizeStart");
var maxHeight = $(window).height()-120;
$(".panel-wrapper").resizable( "option", "maxHeight", maxHeight );
},
resize:function(e, thisUi) {
var negativeHeight = thisUi.element.height() + 100;
$cellInfoContent.css("height", "calc(100vh - "+negativeHeight+"px)");
},
stop:function(e, thisUi) {
$(document).trigger("onCellInfoResizeStop");
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.editorHeight = $(this).css("height");
trans.refreshGrid();
//trans.grid.refreshDimensions();
ui.fixCellInfoSize();
}
})
$(".cellInfoPartsA").resizable({
handles:'e',
start:function(e, thisUi) {
//$(".cellInfoPartsB").css("width", "unset");
$(document).trigger("onCellInfoResizeStart");
var maxWidth = Math.round($(window).width()/100*80);
$(".cellInfoPartsA").resizable( "option", "maxWidth", maxWidth );
},
stop:function(e, thisUi) {
$(document).trigger("onCellInfoResizeStop");
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.editorWidth = $(this).css("width");
}
});
$(".panel-left").resizable({
handles:'e',
start:function(e, thisUi) {
$(".panel-right").css("overflow", "auto");
trans.ignoreResize = true;
},
resize:function() {
//console.log("resize");
//$(".panel-left").attr("style", "width:calc(100vw - "+$(".panel-right").outerHeight()+"px)");
},
stop:function(e, thisUi) {
$(".panel-right").css("overflow", "hidden");
trans.ignoreResize = false;
//trans.grid.render();
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
sys.config.paneSizes.leftPane = $(this).width();
trans.grid.render();
}
});
sys.onReady(function() {
sys.config = sys.config || {}
sys.config.paneSizes = sys.config.paneSizes||{};
ui.resize.leftPane(sys.config.paneSizes.leftPane);
ui.resize.editorWidth(sys.config.paneSizes.editorWidth);
ui.resize.editorHeight(sys.config.paneSizes.editorHeight);
console.log("rerendering grids");
trans.ignoreResize = false;
trans.refreshGrid();
})
}
// active cell info
ui.toggleActiveCellInfo = function(isOn) {
var $elm = $('#cellSelectionInfo')
var $btn = $('.toggle-activeCellInfo')
if (typeof isOn == 'undefined') {
if ($elm.is(':visible')) {
$btn.removeClass('checked');
isOn = false;
} else {
$btn.addClass('checked');
isOn = true;
}
}
if (isOn) {
$('.panel-wrapper').css("max-height", "");
$elm.show();
} else {
$('.panel-wrapper').css("max-height", "100%");
$elm.hide();
}
trans.grid.render();
}
ui.clearActiveCellInfo = function() {
$("#currentCoordinate").val('');
$("#currentRomaji .header").html("");
$("#currentRomaji .text").html("");
$("#currentCellText").val('')
}
ui.clearPathInfo = function() {
$('.pathinfoWrapper .fileId').val('')
}
// ==============================================================
// APP BAR
// ==============================================================
ui.appBarTheme = function(theme) {
$(".applicationBar").attr("data-theme", theme);
}
// ==============================================================
// NOTE
// ==============================================================
ui.applyCurrentNote = function() {
// store current note
if (ui.windows['note']) {
try {
ui.windows['note'].note.saveData();
} catch (e) {
console.warn("can not save note", e)
}
}
ui.evalFileNoteIcon();
}
ui.openFileNote = function(param, options) {
param = param||trans.getSelectedId()||"";
options = options||{};
//options.thisNote = options.thisNote||trans.getSelectedObject().note || "";
ui.applyCurrentNote();
ui.windows['note'] = window.open("note.html#"+param, "note", "width=640,height=320,left=100,top=100,fullscreen=no");
$(".menu-button.addNote").addClass("checked");
/*
if (ui.noteIsOpened) {
ui.windows['note'].document.getElementById('note').value= options.thisNote;
} else {
ui.windows['note'].onload = function() {
ui.windows['note'].document.getElementById('note').value= options.thisNote;
}
}
*/
}
ui.closeFileNote = function() {
$(".menu-button.addNote").removeClass("checked");
if (ui.windows['note']) ui.windows['note'].close();
}
ui.evalFileNoteIcon = function() {
/*
if (Boolean(trans.getSelectedObject().note) == false) {
$(".menu-button.addNote img").attr("src", "img/spechbubble_sq_icon.png");
} else {
$(".menu-button.addNote img").attr("src", "img/spechbubble_sq_icon_line.png");
}
*/
const fileObj = trans.getSelectedObject();
const $noteIcon = $("#commentButtonIcon");
$noteIcon.css("color", "")
if (!fileObj.note) {
$noteIcon.attr("class", "icon-comment-empty")
} else {
$noteIcon.attr("class", "icon-commenting")
if (fileObj.noteColor) $noteIcon.css("color", fileObj.noteColor)
}
}
ui.switchLeftPane = function(target) {
if (target == 'transPaneWrapper' ) {
var $transFrame = $("#translationPane");
if ($transFrame.attr("src") == "") {
$transFrame.attr("src", "translator.html")
}
}
$(".panel-left .switchablePane").addClass("hidden");
$(".panel-left .switchablePane").removeClass("activePane");
$(".panel-left .switchablePane."+target).removeClass("hidden");
$(".panel-left .switchablePane."+target).addClass("activePane");
$(".panel-left .panel-switcher").removeClass("checked");
$(".panel-left .panel-switcher[data-for="+target+"]").addClass("checked");
}
// ==============================================================
// SEARCH
// ==============================================================
ui.openSearchWindow = function(param) {
param = param||"";
console.log("selected text is: "+common.getSelectionText());
var searchIsLoaded = false;
if (typeof ui.windows['search'] !== 'undefined') {
searchIsLoaded = true;
}
if (ui.windows['search']) {
ui.windows['search'].win.restore();
ui.windows['search'].win.requestAttention(2);
}
var posTop = $(".fileListWrapperOuter").offset().top + window.screenY+100;
var posLeft = $(".fileListWrapperOuter").offset().left + window.screenX+240;
console.log("window possition : "+posTop+", "+posLeft);
//ui.windows['search'] = window.open("find.html#"+param, "Search", "width=640,height=320,resizable=no,left="+posLeft+",top="+posTop+",fullscreen=no,dialog=1");
nw.Window.open('www/find.html#'+param,
{
// id will makes the search window will be spawned one
'id': "search"+window.windowIndex,
'frame':false,
'transparent':true
},
function(thisWin) {
ui.windows['search'] = thisWin.window;
ui.windows['search'].onload = function() {
var thisSelectedText = common.getSelectionText();
if (Boolean(thisSelectedText.trim()) == false) thisSelectedText="";
ui.windows['search'].document.getElementById('fieldFind').value= thisSelectedText;
ui.windows['search'].document.getElementById('fieldReplaceFind').value= thisSelectedText;
ui.windows['search'].document.getElementById('fieldPutFind').value= thisSelectedText;
if (param !== "replace") {
var selectedText = thisSelectedText||"";
if (selectedText.trim().length > 0 && selectedText !== " ") ui.windows['search'].search.sendCommandFind();
//if (common.getSelectionText()) ui.windows['search'].search.sendCommand();
}
}
});
if (searchIsLoaded) {
var thisSelectedText = common.getSelectionText();
if (Boolean(thisSelectedText.trim()) == false) thisSelectedText="";
ui.windows['search'].document.getElementById('fieldFind').value= thisSelectedText;
ui.windows['search'].document.getElementById('fieldReplaceFind').value= thisSelectedText;
ui.windows['search'].document.getElementById('fieldPutFind').value= thisSelectedText;
if (param !== "replace") {
var selectedText = thisSelectedText||"";
if (selectedText.trim().length > 0 && selectedText !== " ") ui.windows['search'].search.sendCommand();
// switch tab manually
ui.windows['search'].document.querySelectorAll(".findAnchor")[0].click();
} else {
ui.windows['search'].document.querySelectorAll(".replaceAnchor")[0].click();
}
}
}
ui.openSearchMenu = function() {
function openMenu() {
var $wrapper = $(".group-find.buttonGroup");
var left = Math.round($wrapper.offset().left);
var top = Math.round($wrapper.offset().top + $wrapper.outerHeight());
console.log(left, top)
//ui.menus.saveAs.popup(parseInt(ev.originalEvent.x), parseInt(ev.originalEvent.y));
ui.menus.search.popup(left, top);
return false;
}
if (ui.menus.search) {
return openMenu()
}
ui.menus.search = new nw.Menu();
ui.menus.search.append(new nw.MenuItem({
label: t('Bring to main screen'),
type: "normal",
click: async function(){
if (!ui.windows.search) return;
ui.windows.search.win.restore(); // restore if minimized
ui.windows.search.win.show(); // show if hidden
var left = Math.round(win.x+(win.width/2) - (ui.windows.search.win.width/2));
var top = Math.round(win.y+(win.height/2) - (ui.windows.search.win.height/2));
for (var i=0; i<3; i++) {
if (ui.windows.search.win.x == left && ui.windows.search.win.y == top) break;
console.log("Sending windows to ", left, top, "current pos", ui.windows.search.win.x, ui.windows.search.win.y);
ui.windows.search.win.x = left;
ui.windows.search.win.y = top;
await common.wait(10);
}
}
}));
return openMenu()
}
ui.openMenuAtElm = function($elm, menu) {
var left = Math.round($elm.offset().left);
var top = Math.round($elm.offset().top + $elm.outerHeight());
console.log(left, top)
menu.popup(left, top);
}
ui.toggleGridInfo = function() {
var gridInfoOption = trans.getOption("gridInfo") || {};
var $button = $(".button-gridInfo.gridInfo");
$button.toggleClass("checked");
gridInfoOption.isRuleActive = $button.hasClass("checked");
trans.setOption("gridInfo", gridInfoOption);
trans.renderGridInfo();
trans.grid.render();
}
ui.openGridInfoMenu = function() {
var $elm = $(".menu-button .button-gridInfo.menuSide").parent();
if (ui.menus.gridInfo) return ui.openMenuAtElm($elm, ui.menus.gridInfo);
// initializing menu
//var gridInfoOption = trans.getOption("gridInfo") || {};
ui.menus.gridInfo = new nw.Menu();
ui.menus.gridInfo.append(new nw.MenuItem({
label: t('Show row header info'),
type: "checkbox",
checked: Boolean(trans.getOption("gridInfo")?.rowHeaderInfo),
click: async function(e){
let gridInfoOption = trans.getOption("gridInfo") || {};
gridInfoOption.rowHeaderInfo = !gridInfoOption.rowHeaderInfo
this.checked = gridInfoOption.rowHeaderInfo;
trans.setOption("gridInfo", gridInfoOption);
trans.renderGridInfo();
}
}));
ui.menus.gridInfo.append(new nw.MenuItem({
label: t('Row header width'),
type: "normal",
click: async function(e){
var promptNewWidth = ()=> {
let gridInfoOption = trans.getOption("gridInfo") || {};
gridInfoOption.rowHeaderWidth = gridInfoOption.rowHeaderWidth || 130;
let newWidth = prompt("Enter the row width in pixels.\r\nRow header width must be greater then 50px.", gridInfoOption.rowHeaderWidth);
if (!newWidth) return;
newWidth = parseInt(newWidth);
if (newWidth < 50) return promptNewWidth();
gridInfoOption.rowHeaderWidth = newWidth;
trans.setOption("gridInfo", gridInfoOption);
trans.renderGridInfo();
}
promptNewWidth();
}
}));
ui.menus.gridInfo.append(new nw.MenuItem({ type: 'separator' }));
ui.menus.gridInfo.append(new nw.MenuItem({
label: t('Display marker on organic cells'),
type: "checkbox",
checked: Boolean(trans.getOption("gridInfo")?.viewOrganicCellMarker),
click: async function(e){
let gridInfoOption = trans.getOption("gridInfo") || {};
gridInfoOption.viewOrganicCellMarker = !gridInfoOption.viewOrganicCellMarker
this.checked = gridInfoOption.viewOrganicCellMarker;
trans.setOption("gridInfo", gridInfoOption);
trans.grid.render();
}
}));
ui.menus.gridInfo.append(new nw.MenuItem({ type: 'separator' }));
ui.menus.gridInfo.append(new nw.MenuItem({
label: t('Leave trail on cell visit'),
type: "checkbox",
checked: Boolean(trans.getOption("gridInfo")?.enableTrail),
click: async function(e){
let gridInfoOption = trans.getOption("gridInfo") || {};
gridInfoOption.enableTrail = !gridInfoOption.enableTrail
this.checked = gridInfoOption.enableTrail;
trans.setOption("gridInfo", gridInfoOption);
trans.grid.render();
}
}));
ui.menus.gridInfo.append(new nw.MenuItem({
label: t('Display trails on visited cells'),
type: "checkbox",
checked: Boolean(trans.getOption("gridInfo")?.viewTrail),
click: async function(e){
let gridInfoOption = trans.getOption("gridInfo") || {};
gridInfoOption.viewTrail = !gridInfoOption.viewTrail
this.checked = gridInfoOption.viewTrail;
trans.setOption("gridInfo", gridInfoOption);
trans.grid.render();
}
}));
ui.openMenuAtElm($elm, ui.menus.gridInfo);
}
// ==============================================================
// PANE EXPANDER
// ==============================================================
ui.fixKeyCellOverflow = function() {
console.log("fix overflow. Col width :", trans.grid.getColWidth(0), "range left :", window.innerWidth - $("#menuPanel")[0].getBoundingClientRect().width + 40);
console.log("manual calculation width :", $("#table .ht_clone_top_left_corner .wtSpreader thead th:eq(1)")[0].getBoundingClientRect().width);
if (trans.grid.getColWidth(0) <= (window.innerWidth - $("#menuPanel")[0].getBoundingClientRect().width + 40)) return ;
console.log("fixing overflow");
trans.grid.setColWidth(0, 150)
}
ui.fixCellInfoSize = function() {
return ;
// var mainPanelHeight = $(".panel-wrapper").eq(0).outerHeight();
// var subs = mainPanelHeight +82;
// $("#cellSelectionInfo").css("height", "calc(100vh - "+subs+"px)");
}
// ==============================================================
// ROW PROPERTIES WINDOW
// ==============================================================
ui.openRowProperties = function(range, options) {
options = options||{};
//ui.windows['rowProperties'] = window.open("rowProperties.html", "rowProperties", "");
//$(".menu-button.addNote").addClass("checked");
range = range||trans.grid.getSelectedRange();
if (typeof range == 'undefined') return false;
var highlightedRow = range[0].highlight.row;
var keyText = trans.grid.getData()[highlightedRow][0];
var contextList = [];
if (trans.project !== 'undefined') {
try {
contextList = trans.project.files[trans.getSelectedId()].context[highlightedRow];
} catch (error) {
console.log(error);
}
}
var contextTemplate = "";
contextList = contextList||[];
for (var i=0; i<contextList.length; i++) {
contextTemplate+= "<li>"+contextList[i]+"</li>";
}
var $container = $("#rowProperties");
$container.find(".rowProp_fileName").html(trans.getSelectedId());
$container.find(".rowProp_location").html(highlightedRow);
$container.find(".rowProp_keyText").html(keyText);
$container.find(".rowProp_contextList").html(contextTemplate);
$container.find(".rowProp_bestTranslatiion").html(trans.getTranslationFromRow(trans.grid.getData()[highlightedRow]));
if ($("#rowProperties").hasClass("initialized") == false) {
$("#rowProperties").dialog({
autoOpen: false,
title: t("Row Properties"),
modal:true,
width:Math.round($(window).width()/100*50),
height:Math.round($(window).height()/100*50),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: "Close",
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$("#rowProperties").addClass("initialized");
}
$("#rowProperties").dialog("open");
/**
* Triggered when dialog Row Properties Opened
* @event ui#dialogRowPropertiesOpened
*/
this.trigger("dialogRowPropertiesOpened", $container);
return ($("#rowProperties"));
}
// ==============================================================
// PROJECT PROPERTIES WINDOW
// ==============================================================
ui.drawTranslatorOptions = function($parent) {
for (var i=0; i<trans.translator.length; i++) {
$parent.append("<option value='"+trans.translator[i]+"'>"+trans[trans.translator[i]].name+"</option>");
}
return $parent;
}
ui.drawLanguageOptions = function($parent) {
for (var code in consts.languages) {
$parent.append("<option value='"+code+"'>"+consts.languages[code]+"</option>");
}
return $parent;
}
ui.openProjectProperties = async function(options) {
options = options||{};
var $container = $("#projectProperties");
$container.find(".fileProp_id").html();
trans.project.options = trans.project.options||{};
trans.project.cache = trans.project.cache||{};
if ($container.hasClass("initialized") == false) {
// initializing translator field
var $translator = $container.find(".projProp_translator");
ui.drawTranslatorOptions($("#translatorEngines"));
$translator.off("change");
$translator.on("change", function(e) {
trans.project.options.translator = $(this).val();
});
var $sl = $container.find(".projProp_langFrom");
var $tl = $container.find(".projProp_langTo");
ui.drawLanguageOptions($("#languages"));
$sl.off("change");
$sl.on("change", function(e) {
trans.project.options.sl = $(this).val();
trans.trigger("languageChange", [$sl.val(), $tl.val()])
});
$tl.off("change");
$tl.on("change", function(e) {
trans.project.options.tl = $(this).val();
trans.trigger("languageChange", [$sl.val(), $tl.val()])
});
$container.find(".projProp_title").on("blur paste", function() {
trans.project.gameTitle = $(this).val();
$(".footer-content.footer2 > span").html(trans.project.gameTitle);
})
$container.find(".editableHtmlFld").on("blur paste", function() {
let $html = $(this);
$html.find("style, script, iframe, webview").remove();
$html.find("a").addClass("external")
$html.find("a").attr("external", "")
trans.project.options.info = $html.html()
})
$container.find(".displayInfo").on("input", function() {
trans.project.options.displayInfo = $(this).prop("checked")
})
$container.dialog({
autoOpen: false,
title: t("Project Properties"),
modal:true,
width:Math.round($(window).width()/100*50),
height:Math.round($(window).height()/100*50),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$container.find("a.externalLink, a[external]").on("click", function(e) {
console.warn("clicked")
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
$container.find("#projPropWrapper").tabs();
$container.addClass("initialized");
}
$container.find(".projProp_fileLoc").html(trans.currentFile);
ui.clearFieldInfo($container.find(".projProp_fileLoc"));
if (trans.currentFile) {
if (common.isExist(trans.currentFile) == false) {
ui.setFieldInfo($container.find(".projProp_fileLoc"), "Path not found! Effect: export & inject procedure will fail.", "warning");
}
}
$container.find(".projProp_id").html(trans.project.projectId);
$container.find(".projProp_date").html(trans.project.buildOn);
$container.find(".projProp_engine").html(trans.project.gameEngine);
$container.find(".projProp_editorName").html(trans.project.editorName || "");
$container.find(".projProp_editorVersion").html(trans.project.editorVersion || "");
$container.find(".projProp_parser").html(trans.project.parser || "");
$container.find(".projProp_parserVersion").html(trans.project.parserVersion || "");
// writable
$container.find(".projProp_title").val(trans.project.gameTitle);
$container.find(".projProp_loc").val(trans.project.loc);
$container.find(".projProp_devPath").val(trans.project.devPath || "");
$container.find(".projProp_translator").val(trans.project.options.translator);
$container.find(".projProp_stagingPath").val(trans.project.cache.cachePath);
ui.clearFieldInfo($container.find(".projProp_stagingPath"));
if (trans.project.cache.cachePath) {
if (common.isDir(trans.project.cache.cachePath) == false) {
ui.setFieldInfo($container.find(".projProp_stagingPath"), `Path not found! Effect: export & inject procedure will fail.
<a href="https://dreamsavior.net/?p=1062" class="icon-help-circled externalLink" external>Help</a>`, "warning");
}
}
// Stats
trans.evalTranslationProgress();
var stats = trans.getStats();
console.log(stats);
stats.organicPercent = Math.round((stats.organicPercent*10)/10);
$container.find("#projProp-stats [data-field]").each(function() {
var key = $(this).attr("data-field");
console.log("key", key);
if (typeof stats[key] == "undefined") return;
console.log("Assigning:", key);
$(this).html(stats[key]);
})
$container.find("#projProp-stats [data-field=percent]").attr("value", stats.percent);
$container.find("#projProp-stats .percentDisplay").text(Math.round(stats.percent*10)/10);
// info
$container.find(".editableHtmlFld").html(trans.project.options.info);
$container.find(".displayInfo").prop("checked", trans.project.options.displayInfo || false)
$container.dialog( "instance" ).uiDialog.find(".ui-dialog-title").html("<i class='icon-cog'></i>"+t("Project Properties : ")+trans.project.gameTitle );
var $loc = $container.find(".projProp_loc");
var evalProjectLoc = async ($elm)=>{
if (await common.isDirectory($elm.val()) == false) {
$elm.addClass("error");
$elm.closest(".dialogSectionBlock").find(".dialogInfo").removeClass("hidden");
} else {
$elm.removeClass("error");
$elm.closest(".dialogSectionBlock").find(".dialogInfo").addClass("hidden");
}
}
var $dvFields = $(".dvField_isRendered");
$dvFields.each(function() {
evalProjectLoc($(this));
})
if ($container.hasClass("isInitialized") == false) {
$loc.on("change", function() {
trans.project.loc = $(this).val();
evalProjectLoc($(this));
})
$container.find(".projProp_devPath").on("change", function() {
trans.project.devPath = $(this).val();
evalProjectLoc($(this));
});
$container.find(".projProp_stagingPath").on("change", function() {
trans.project.cache = trans.project.cache || {}
trans.project.cache.cachePath = $(this).val();
//evalProjectLoc($(this));
});
$container.find(".openStagingDir").on("click", async function() {
var stagePath = nwPath.resolve(trans.project.cache.cachePath);
if (!await common.isDir(stagePath)) return alert(t("Stage path do not exist!"));
stagePath = nwPath.join(stagePath, "gameInfo.json");
nw.Shell.showItemInFolder(stagePath)
});
$container.find(".editFunction").on("click", async function() {
var $this = $(this)
const workspace = $this.attr("for");
trans.project.options ||= {}
trans.project.options.hooks ||= {}
await ui.openScriptEditor("scriptEditor",
{
"workspaceType":"hook",
"workspace": workspace,
readOnly:false,
script: trans.project?.options?.hooks[workspace] || "",
onSave: (script)=> {
console.log("saved", script);
common.setPropertyByPath(trans.project.options, `hooks.${workspace}`, script, true)
}
});
});
}
$container.dialog("open");
$container.addClass("isInitialized");
return $container;
}
ui.setFieldInfo = function($elm, msg, type) {
var $template = $elm.parent().find(".fieldInfo");
if ($template.length == 0) {
$template = $("<div class='fieldInfo'></div>");
$elm.parent().append($template)
}
if (type == "warning") {
$template.addClass("icon-attention");
} else if (type == "error") {
$template.addClass("icon-minus-circled");
} else {
$template.addClass("icon-info-circled");
}
$template.html(msg);
}
ui.clearFieldInfo = function($elm) {
$elm.parent().find(".fieldInfo").remove();
}
ui.openDialogSetDevPath = async function(defPath) {
defPath = defPath || trans.project.devPath || "";
return new Promise((resolve, reject)=> {
var $popup = $("#ui_selectDevPath");
if ($popup.length == 0) {
var dvField = new DVField();
$popup = $("<div id='ui_selectDevPath'></div>");
var $content = ($(`
<div>
<h2 data-tran="">${t(`Select dev folder`)}</h2>
<div data-tran="">
${t(`Where is the translated game's directory located at?<br />This is the same folder with the destination directory when injecting your game.`)}
</div>
<label>
<input type="dvSelectPath" nwdirectory class="fullWidth devPath" value="${defPath}" />
</label>
</div>`));
console.log("rendering ", $popup);
dvField.renderSelectPath($content.find("[type=dvSelectPath]"));
$popup.empty();
$popup.append($content);
}
$popup.dialog({
title: t("Select folder"),
autoOpen: false,
modal:true,
width:640,
height:240,
minWidth:640,
minHeight:240,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
close:function( event, ui ) {
resolve(trans.project.devPath || "");
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Submit"),
click: async function() {
var $this = $(this)
var to = $this.find(".devPath").val()
if (!to) return alert(t("Path to the directory can not be empty!"));
if (await common.isDirectory(to) == false) return alert(t('Invalid directory:')+to);
trans.project.devPath = to;
$(this).dialog("close");
}
}
]
});
$popup.find(".devPath").val(defPath);
$popup.dialog("open");
})
}
// ==============================================================
// FILE PROPERTIES WINDOW
// ==============================================================
ui.openFileProperties = function(contextMenuId, options) {
options = options||{};
if (Boolean(contextMenuId) == false) {
//$container.find(".rowProp_fileName").html(trans.getSelectedId());
var $selected = $(".fileList .data-selector.context-menu-active");
if ($selected.length < 1) return console.warn("unable to find selected document");
if ($selected.length > 1) return console.warn("can not process more than one selected document");
contextMenuId = $selected.attr("data-id");
}
var currentFile = trans.project.files[contextMenuId]||{};
trans.evalTranslationProgress([contextMenuId]);
var $container = $("#fileProperties");
$container.find(".fileProp_id").html(contextMenuId);
$container.find(".fileProp_path").html(currentFile.path);
$container.find(".fileProp_originalFormat").html(currentFile.originalFormat);
$container.find(".fileProp_dataLength").html(currentFile.data.length);
$container.find(".fileProp_translatedLength").html(currentFile.progress.translated);
$container.find(".translatedPercent").html(Math.round(currentFile.progress.percent)+"%");
$container.find(".translatedPercent").css("background", 'linear-gradient(to right, rgb(49, 89, 249) 0%, rgb(49, 89, 249) '+currentFile.progress.percent+'%, rgb(255, 0, 4) '+currentFile.progress.percent+'%, rgb(255, 0, 4) 100%');
if ($container.hasClass("initialized") == false) {
$container.dialog({
autoOpen: false,
title: t("File Properties"),
modal:true,
width:Math.round($(window).width()/100*50),
height:Math.round($(window).height()/100*50),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$container.addClass("initialized");
}
$container.dialog( "instance" ).uiDialog.find(".ui-dialog-title").html("<i class='icon-cog'></i>"+t("File Properties : ")+contextMenuId );
$container.dialog("open");
return $container;
}
// ==============================================================
// OPTIONS WINDOW
// ==============================================================
ui.openOptionsWindow = function(options) {
options = options||{};
ui.windows['options'] = window.open("options.html", "options", "");
//$(".menu-button.addNote").addClass("checked");
/*
nw.Window.open('www/options.html',
{
// id will makes the search window will be spawned one
'id': "options"
},
function(thisWin) {
ui.windows['options'] = thisWin.window;
});
*/
}
// ==============================================================
// TRIM DIALOG WINDOW
// ==============================================================
ui.openTrimWindow = function(options) {
options = options||{};
var $container
if ($("#trimDialogWindow").length == 0) {
// initializing
$("#template").append('<div id="trimDialogWindow">\
<div class="dialogGuide"><img src="img/guide-trim.png"></div>\
<div class="dialogContent">\
<h2>'+t("Target column")+'</h2>\
<div class="columnSelector"></div>\
</div>\
</div>');
$container = $("#trimDialogWindow");
$container.dialog({
autoOpen: false,
title: t("Trim Whitespaces"),
modal:true,
width:Math.round($(window).width()/100*50),
height:Math.round($(window).height()/100*50),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Ok"),
icon: "ui-icon-close",
click: function() {
var selectedValue = $("#trimDialogWindow select").val();
if (Array.isArray(selectedValue) == false) return alert(t("Please select a column"));
var confirmation = confirm(t("Are you sure want to trim the whitespaces on selected column?\nThis action can not be undone!"));
if (confirmation) {
ui.showBusyOverlay();
var selectedFile = trans.getCheckedFiles();
if (selectedFile.length == 0) selectedFile = trans.getAllFiles();
trans.trimTranslation(selectedFile, selectedValue);
$(this).dialog("close");
ui.hideBusyOverlay();
}
}
}
]
});
}
$container = $("#trimDialogWindow");
$container.find(".columnSelector").html(ui.generateColMultiSelector({skipFirstCol:true}));
$container.dialog("open");
return $container;
}
ui.openPaddingWindow = function(options) {
options = options||{};
var $container;
if ($("#paddingDialogWindow").length == 0) {
// initializing
$("#template").append('<div id="paddingDialogWindow">\
<div class="dialogGuide"><img src="img/guide-padding.png"></div>\
<div class="dialogContent">\
<h2>'+t("Target column")+'</h2>\
<div class="columnSelector"></div>\
</div>\
</div>');
$container = $("#paddingDialogWindow");
$container.dialog({
autoOpen: false,
title: "Auto Padding",
modal:true,
width:Math.round($(window).width()/100*50),
height:Math.round($(window).height()/100*50),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Ok"),
icon: "ui-icon-close",
click: function() {
var selectedValue = $("#paddingDialogWindow select").val();
if (Array.isArray(selectedValue) == false) return alert(t("Please select a column"));
var confirmation = confirm(t("Are you sure want commit autopadding on selected column?\nThis action can not be undone!"));
if (confirmation) {
ui.showBusyOverlay();
var selectedFile = trans.getCheckedFiles();
if (selectedFile.length == 0) selectedFile = trans.getAllFiles();
trans.paddingTranslation(selectedFile, selectedValue);
$(this).dialog("close");
ui.hideBusyOverlay();
}
}
}
]
});
}
$container = $("#paddingDialogWindow");
$container.find(".columnSelector").html(ui.generateColMultiSelector({skipFirstCol:true}));
$container.dialog("open");
return $container;
}
// ========================================================
// CURRENT CELL'S TEXT EDITOR
// Background Layer
// ========================================================
ui.currentCellTextOptionsOpen = function(options) {
console.log("Opening ui.currentCellTextOptionsOpen");
options = options||{};
sys.config.backgroundHelper = sys.config.backgroundHelper||[];
var applyChange = function($element) {
$element = $element || $("#currentCellTextOptions");
let $ctMarkers = $element.find("#currentCellTextOptions_marker .ctMarkers");
var ctOptions = [];
for (var index=0; index<$ctMarkers.length; index++) {
var $thisElm = $ctMarkers.eq(index);
ctOptions.push({
at: $thisElm.find(".ctMarkers_number").val(),
color: $thisElm.find(".ctMarkers_color").val(),
unit: $thisElm.find(".ctMarkers_unit").val()
})
}
console.log(ctOptions);
ui.createBackgroundHelper($("#currentCellText"), ctOptions);
sys.config = sys.config||{};
sys.config.backgroundHelper = sys.config.backgroundHelper || [];
sys.config.backgroundHelper = ctOptions;
return ctOptions;
}
var $container
if ($("#currentCellTextOptions").length == 0) {
// initializing
$container = $(`<div id='currentCellTextOptions'>
<div id='currentCellTextOptionsTabs'>
<ul>
<li><a href='#currentCellTextOptions_marker'>`+t("Markers")+`</a></li>
<li><a href='#currentCellTextOptions_options'>`+t("Options")+`</a></li>
</ul>
<div id='currentCellTextOptions_marker'>
<div class='ct_marker_info'>
<div class="blockBox infoBlock withIcon" data-tran="">
Markers are visual guidelines for the number of characters in a line.<br />
The marker will only be visible if wordwrap in the text area is disabled.
</div>
</div>
<div class='ct_marker_container'></div>
<div class='ct_marker_tools'>
<button class='ct_marker_tools_add icon-plus-circled'>Add</button>
<button class='ct_marker_tools_clear icon-cancel-circled'>Clear all</button>
</div>
</div>
<div id='currentCellTextOptions_options'>
<div class="dialogSectionBlock">
<label><input type="checkbox" class="enableAutoComplete" /> <span>Enable suggestion</span></label>
</div>
<div class="dialogSection">
<h2>Speech Synthesizer</h2>
<div class="dialogSectionBlock">
<label>
<div>Reading speed:</div>
<input type="range" data-type="float" data-autoset="sys.config.speechRate" min="0.5" max="2" value="1" step="0.1" oninput="this.nextElementSibling.value = this.value"><output data-autoset="sys.config.speechRate">0</output>
</label>
</div>
<div class="dialogSectionBlock">
<label>
<div>Pitch:</div>
<input type="range" data-type="float" data-autoset="sys.config.speechPitch" min="0.5" max="2" value="1" step="0.1" oninput="this.nextElementSibling.value = this.value"><output data-autoset="sys.config.speechPitch">0</output>
</label>
</div>
<div class="dialogSectionBlock">
<label>
<div>Volume:</div>
<input type="range" data-type="float" data-autoset="sys.config.speechVolume" min="0" max="1" value="1" step="0.1" oninput="this.nextElementSibling.value = this.value"><output data-autoset="sys.config.speechVolume">0</output>
</label>
</div>
</div>
</div>
</div>
</div>`);
// setting up default
$container.find('.enableAutoComplete').on("input", function() {
ui.autoCompleteSet($(this).prop('checked'));
if (ui.autoCompleteIsEnabled() == false) ui.autoCompleteClear();
})
$container.find('[data-autoset]').on("input", function() {
var $this = $(this)
var value = $this.val();
var configPath = $this.attr("data-autoset");
if (!configPath) return;
if ($this.attr("data-type") == "float") {
value = parseFloat(value);
} else if ($this.attr("data-type") == "int") {
value = parseInt(value);
}
common.varAsStringSet(configPath, value, true);
})
$("#template").append($container);
$container.find("#currentCellTextOptionsTabs").tabs();
// drawing tabs content
var $markerTemplate = $("<div class='ctMarkers'>\
<label><span class='markerLabel'>"+t("Mark at")+"</span><span><input type='number' data-type='at' min='0' value='0' class='ctInput ctMarkers_number' /></span></label>\
<label><span class='markerLabel'>"+t("Units")+"</span><span><select data-type='unit' class='ctInput ctMarkers_unit' ><option value='0'>"+t("Half width character (ie. Alphabet, etc)")+"</option><option value='1'>"+t("Full width character (ie. Hiragana, Kanji, 漢字, etc)")+"</option></select></span></label>\
<label><span class='markerLabel'>"+t("Color")+"</span><span><input type='color' data-type='color' class='ctInput ctMarkers_color' value='#FF0000' /></span></label>\
<label class='ctToolbar'><button class='removeMarker icon-cancel-circled'>"+t("Remove")+"</button></label>\
</div>");
// events
$markerTemplate.find(".removeMarker").on("click", function() {
$(this).closest(".ctMarkers").remove();
applyChange();
});
$markerTemplate.find(".ctInput").on("input", function() {
applyChange();
//console.log("changed");
});
$container.find(".ct_marker_tools_add").on("click", function(e) {
var thisTemplate = $markerTemplate.clone(true, true);
console.log(thisTemplate);
console.log("marker container", $container.find(".ct_marker_container"));
$container.find(".ct_marker_container").append(thisTemplate);
})
$container.find(".ct_marker_tools_clear").on("click", function(e) {
$container.find(".ct_marker_container").empty();
applyChange();
})
// initializing saved data
console.log("Initializing saved data", sys.config.backgroundHelper)
for (var i=0; i<sys.config.backgroundHelper.length; i++) {
var $thisTemplate = $markerTemplate.clone(true, true);
$container.find(".ct_marker_container").append($thisTemplate);
$thisTemplate.find(".ctMarkers_number").val(sys.config.backgroundHelper[i].at);
$thisTemplate.find(".ctMarkers_color").val(sys.config.backgroundHelper[i].color);
console.log("Setting unit : ", sys.config.backgroundHelper[i].unit)
$thisTemplate.find(".ctMarkers_unit").val(sys.config.backgroundHelper[i].unit);
}
// registering popup
$container.dialog({
autoOpen: false,
title: t("Current Cell's Editor Options"),
modal:false,
closeOnEscape:true,
classes: {
"ui-dialog": "highlight",
"ui-dialog-titlebar": "hidden"
},
width:$(".cellInfoPartsB").outerWidth(),
height:Math.round($(window).height()/100*50),
minWidth:320,
minHeight:320,
position: {
my: "right bottom",
at: "right top",
of: ".cellInfoPartsB"
},
show: {
effect: "slide",
direction: "down",
duration: 200
},
hide: {
effect: "slide",
direction: "down",
duration: 200
},
close: function( event, ui ) {
//console.log("closed");
sys.saveConfig();
},
buttons:[
{
text: t("Ok"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$container.addClass("initialized");
}
$container = $("#currentCellTextOptions");
trans.project.options = trans.project.options || {}
$container.find('.enableAutoComplete').prop('checked', ui.autoCompleteGet())
$container.find('[data-autoset]').each(function() {
var $this = $(this);
try {
if ($this.attr("type") == "checkbox") {
$this.prop("checked", Boolean(common.varAsStringGet($this.attr('data-autoset'))));
} else if (["INPUT", "SELECT"].includes($this.prop("tagName")) == false) {
$this.text(common.varAsStringGet($this.attr('data-autoset')));
} else {
$this.val(common.varAsStringGet($this.attr('data-autoset')));
}
} catch (e) {
// do nothing
}
});
//$container.closest(".ui-dialog").addClass("hidden");
$container.dialog( "option", "position", { my: "right bottom", at: "right top", of: ".cellInfoPartsB" } );
$container.dialog( "option", "width", $(".cellInfoPartsB").outerWidth() );
$container.dialog("open");
return $container;
}
ui.calculateFontWidth = function($elm, unitType) {
$elm = $elm || $("#currentCellText");
//console.log("calculateFontWidth", arguments);
unitType = parseInt(unitType) || 0;
var font = "E";
if (unitType) font = "字";
//console.log(font);
var $dummyElm
if ($("#fontSampler__").length == 0) {
$dummyElm = $("<div id='fontSampler__' style='position:absolute; top:-1000; left: -1000;'>"+font+"</div>");
} else {
$dummyElm = $("#fontSampler__");
}
$dummyElm.css("font-family", $elm.css("font-family"))
.css("font-size", $elm.css("font-size"))
.css("font-weight", $elm.css("font-weight"))
.css("padding", "0px")
.css("top", "-999px")
.css("left", "-999px")
.css("position", "absolute")
//var calculatedWidth = $dummyElm.appendTo("body").width()/1;
var calculatedWidth = $dummyElm.appendTo($elm.parent()).width()/1;
//console.log("dummy elm total width : ", $dummyElm.width());
$dummyElm.remove();
//console.log("font size : ", $elm.css("font-size"));
//console.log("font weight : ", $elm.css("font-weight"));
//console.log(calculatedWidth);
return calculatedWidth;
}
ui.calculateFontHeight = function($elm) {
$elm = $elm || $("#currentCellText");
var $dummyElm;
if ($("#fontSampler__").length == 0) {
$dummyElm = $("<div id='fontSampler__' style='position:absolute; top:-1000; left: -1000;'>ABC<br />ABC<br />ABC<br />ABC<br />ABC<br />ABC<br />ABC<br />ABC<br />ABC<br />ABC</div>");
} else {
$dummyElm = $("#fontSampler__");
}
$dummyElm.css("font-family", $elm.css("font-family"))
.css("font-size", $elm.css("font-size"))
.css("font-weight", $elm.css("font-weight"))
.css("line-height", $elm.css("line-height"))
.css("padding", "0px")
.css("top", "-999px")
.css("left", "-999px")
.css("position", "absolute")
//var calculatedHeight = $dummyElm.appendTo("body").innerHeight()/10;
var calculatedHeight = $dummyElm.appendTo($elm.parent()).innerHeight()/10;
$dummyElm.remove();
return calculatedHeight;
}
ui.clearBackgroundNumber = function($target) {
$target = $target||$("#currentCellText");
$target.css("background-image", "none");
$target.css("background-repeat", "no-repeat");
$target.css("background-attachment", "local");
$target.css("padding-left", "4px");
}
ui.generateBackgroundNumber = function($target, maxLine, force) {
if ($("button.wordWrap").hasClass("checked") == false) {
ui.clearBackgroundNumber();
return;
}
$target = $target||$("#currentCellText");
force = force || false;
this._cache = this._cache || {};
this._cache.bgNumbersSVG = this._cache.bgNumbersSVG || {};
//var padding = 2;
maxLine = maxLine || $target.val().split("\n").length || 100;
// let fontFamily =$target.css("font-family");
// let lineHeight =$target.css("line-height");
// let fontSize =$target.css("font-size");
// let paddingTop =$target.css("padding-top");
// let fontWeight =$target.css("font-weight");
let intPaddingTop = parseInt($target.css("padding-top"));
var marginLeft = "8";
var aspect = $target.css("font-size");
var svgEncoded;
if (Boolean(this._cache.bgNumbersSVG[maxLine+"-"+aspect]) == false || force == true) {
var calculatedHeight = ui.calculateFontHeight($target);
var adjustment = -((calculatedHeight/2)-6);
var textContent = "";
for (var i=0; i<maxLine; i++) {
var drawedLine = i+1;
var thisCoord = ((calculatedHeight*i)+calculatedHeight+intPaddingTop)+adjustment;
//console.log("drawing: "+' <text x="'+marginLeft+'" y="'+thisCoord+'px"> '+drawedLine+'</text>\n');
textContent += ' <text fill="#888888" x="'+marginLeft+'" y="'+thisCoord+'px"> '+drawedLine+'</text>\n';
}
var height = thisCoord+1000;
var svg = '<svg xmlns="http://www.w3.org/2000/svg" height="'+height+'" width="45px">\
<style>\
/* <![CDATA[ */\
text {\
fill:"red";\
font-size: 11pt;\
font-family: "Courier New";\
background-color: "#ff0000";\
}\
/* ]]> */\
</style>\
<rect width="40px" height="'+height+'" style="fill:rgba(255,255,255,.1)" />\
'+textContent+'\
<line x1="40px" y1="0" x2="40px" y2="'+height+'" style="stroke:rgba(128,128,128,1);stroke-width:1" />\
</svg>';
svgEncoded = btoa(svg);
this._cache.bgNumbersSVG[maxLine+"-"+aspect] = svgEncoded;
} else {
svgEncoded = this._cache.bgNumbersSVG[maxLine+"-"+aspect];
}
var svgBody = "url('data:image/svg+xml;base64,"+svgEncoded+"')";
ui.appendBackground($target, {
"background-image" : svgBody,
"background-repeat" : "no-repeat",
"background-attachment" : "local"
}, 0);
$target.css("padding-left", "48px");
}
ui.createBackgroundNumberDelayed = function(delay, force) {
var $that = $("#currentCellText");
delay = delay || 200;
ui._cache = ui._cache || {};
ui._cache.lastCellLineNumber = ui._cache.lastCellLineNumber || 0;
if (ui._cache.bgNumberProcessing) {
clearTimeout(ui._cache.bgNumberProcessing);
ui._cache.bgNumberProcessing = setTimeout(function() {
var currentLineNumber = $that.val().split("\n").length;
if (ui._cache.lastCellLineNumber !== currentLineNumber) {
ui._cache.lastCellLineNumber = currentLineNumber;
ui.generateBackgroundNumber($that, currentLineNumber);
}
//console.log("input delayer triggered");
ui._cache.bgNumberProcessing = undefined;
}, delay);
return;
}
ui._cache.bgNumberProcessing = setTimeout(function() {
var currentLineNumber = $that.val().split("\n").length;
if (ui._cache.lastCellLineNumber !== currentLineNumber) {
ui._cache.lastCellLineNumber = currentLineNumber;
ui.generateBackgroundNumber($that, currentLineNumber);
}
//console.log("input delayer triggered");
ui._cache.bgNumberProcessing = undefined;
}, delay);
}
ui.clearBackgroundHelper = function($target) {
$target = $target || $("#currentCellText");
ui.appendBackground($("#currentCellText"), {
"background-image" : "none",
"background-repeat" : "repeat-y",
"background-attachment" : "local",
"background-position": "0px 0px"
}, 1);
}
ui.createBackgroundHelper = function($target, atText) {
$target = $target || $("#currentCellText");
//atText = atText||1;
if (typeof atText == 'number') {
atText = [{
at:atText,
color:"rgba(255,0,0,0.5)",
unit:0
}];
}
if (atText.length < 1) {
ui.clearBackgroundHelper();
return;
}
var initialPadding = parseInt($("#currentCellText").css("padding-left"))||48;
if ($(".currentCellTextCtrl .wordWrap").hasClass("checked")) {
initialPadding = 48;
}
var fontWidth = [];
var maxWidth = 200;
var svgLine = "";
for (var i=0; i<atText.length; i++) {
var thisUnit = atText[i].unit || 0;
fontWidth[thisUnit] = fontWidth[thisUnit] || ui.calculateFontWidth($target, thisUnit);
var rangeLeft = (fontWidth[thisUnit]*atText[i].at)-1;
if (maxWidth < rangeLeft+200 ) maxWidth = rangeLeft+200;
console.log("rangeLeft", "("+fontWidth[thisUnit]+"*"+atText[i].at+")");
atText[i].color = atText[i].color||"rgba(255,0,0,0.5)";
svgLine += '<line x1="'+rangeLeft+'" y1="0" x2="'+rangeLeft+'" y2="200" style="stroke:'+atText[i].color+';stroke-width:1" stroke-dasharray="4 1" />\n';
}
var svg = '<svg xmlns="http://www.w3.org/2000/svg" height="200" width="'+maxWidth+'">\n\
<line x1="0" y1="0" x2="0" y2="200" style="stroke:rgba(128,128,128,1);stroke-width:1" stroke-dasharray="4 1" />\n\
'+svgLine+'\n\
</svg>'
// console.log(svg);
var svgEncoded = btoa(svg);
var svgBody = "url('data:image/svg+xml;base64,"+svgEncoded+"')";
ui.appendBackground($target, {
"background-image" : svgBody,
"background-repeat" : "repeat-y",
"background-attachment" : "local",
"background-position": initialPadding+"px 0px"
}, 1);
}
ui.backgroundHelperInitialize = function(conf) {
// load config to background helper
if (this.backgroundHelperIsInitialized) return;
sys.config = sys.config || {};
sys.config.backgroundHelper = sys.config.backgroundHelper || {};
conf = conf || sys.config.backgroundHelper ||[];
if (Array.isArray(conf) == false) return;
ui.createBackgroundNumberDelayed();
ui.createBackgroundHelper( $("#currentCellText"), conf);
this.backgroundHelperIsInitialized = true;
}
ui.redrawBackgroundHelper = function() {
sys.config = sys.config || {};
sys.config.backgroundHelper = sys.config.backgroundHelper || {};
var conf = conf || sys.config.backgroundHelper ||[];
if (Array.isArray(conf) == false) return;
ui.createBackgroundNumberDelayed();
ui.createBackgroundHelper( $("#currentCellText"), conf);
}
ui.appendBackground = function($target, bgOptions, layer) {
if ($target.length < 1) return $target;
bgOptions = bgOptions||{};
layer = layer||0;
if (Boolean(bgOptions['background-image']) == false) return $target;
var pseudoName = "bgPseudo_"+$target.attr("id");
var $pseudoElm = $("#"+pseudoName);
if ($pseudoElm.length == 0) {
$pseudoElm = $("<style id='"+pseudoName+"'></style>");
$("body").append($pseudoElm);
}
//console.log("pass here");
var cssBG = $target.data("cssBG") || {};
for (let bgObject in bgOptions) {
cssBG[bgObject] = cssBG[bgObject]||[];
cssBG[bgObject][layer] = bgOptions[bgObject];
}
// determine the length of cssBG
var maxLength = cssBG['background-image'].length;
//console.log("maxLength", maxLength);
// fill the gap
for (let index =0; index<maxLength; index++) {
//console.log('background-image', index, cssBG['background-image'][index]);
if (cssBG['background-image'][index]) continue;
cssBG['background-image'][index] = "none";
}
if (cssBG['background-position']) {
for (let index =0; index<maxLength; index++) {
if (cssBG['background-position'][index]) continue;
cssBG['background-position'][index] = "0px 0px";
}
}
if (cssBG['background-repeat']) {
for (let index =0; index<maxLength; index++) {
if (cssBG['background-repeat'][index]) continue;
cssBG['background-repeat'][index] = "no-repeat";
}
}
// others
for (let bgObject in cssBG) {
if (Array.isArray(cssBG[bgObject]) == false ) continue;
if (bgObject == 'background-image' || bgObject == 'background-position' || bgObject == 'background-repeat') continue;
for (var index =0; index<maxLength; index++) {
if (cssBG[bgObject][index]) continue;
cssBG[bgObject][index] = "unset";
}
}
$target.data("cssBG", cssBG);
//console.log("cssBG : ", cssBG);
//var cssText = "";
for (let bgObject in cssBG) {
if (Array.isArray(cssBG[bgObject]) == false ) continue;
//console.log("Setting : ", bgObject, "value : ", cssBG[bgObject].join(","));
$target.css(bgObject, cssBG[bgObject].join(","));
//cssText += bgObject+":"+cssBG[bgObject].join(",")+";"
}
//console.log("#"+pseudoName+"{"+cssText+"}");
//$pseudoElm.html("#"+$target.attr("id")+"{"+cssText+"}");
}
// ==============================================================
// Term of use WINDOW
// ==============================================================
ui.openToU = function(options) {
options = options||{};
var $container
if ($("#ToU").length == 0) {
// initializing
$("#template").append('<div id="ToU">\
<div class="dialogGuide"><img src="img/guide-padding.png"></div>\
<div class="dialogContent">\
<h2>Target column</h2>\
<div class="columnSelector"></div>\
</div>\
</div>');
$container = $("#ToU");
$container.dialog({
autoOpen: false,
title: t("Auto Padding"),
modal:true,
width:Math.round($(window).width()-80),
height:Math.round($(window).height()-80),
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Ok"),
icon: "ui-icon-close",
click: function() {
var selectedValue = $("#ToU select").val();
if (Array.isArray(selectedValue) == false) return alert(t("Please select a column"));
var confirmation = confirm(t("Are you sure want commit autopadding on selected column?\nThis action can not be undone!"));
if (confirmation) {
ui.showBusyOverlay();
var selectedFile = trans.getCheckedFiles();
if (selectedFile.length == 0) selectedFile = trans.getAllFiles();
trans.paddingTranslation(selectedFile, selectedValue);
$(this).dialog("close");
ui.hideBusyOverlay();
}
}
}
]
});
}
$container = $("#ToU");
$container.find(".columnSelector").html(ui.generateColMultiSelector({skipFirstCol:true}));
$container.dialog("open");
return $container;
}
// ==============================================================
//
// F R E E E D I T I N G C O M P O N E N T
//
// ==============================================================
ui.generateDirSelector = function() {
var $container = $("#directoryList");
if (!trans.project) return;
if (!trans.project.files) return;
var reg = {};
for (var filename in trans.project.files) {
if (!trans.project.files[filename].dirname) continue;
if (reg[trans.project.files[filename].dirname]) continue;
reg[trans.project.files[filename].dirname] = true;
let $template = $('<option value="'+common.htmlEntities(trans.project.files[filename].dirname)+'">')
$container.append($template);
}
return $container;
}
ui.addNewObjectDialog = function(defaultDir, options) {
options = options || {};
var $dialog = $("#dialogAddObject");
defaultDir = defaultDir || ""
$("#addObjDirName").val(defaultDir);
ui.generateDirSelector();
if ($dialog.hasClass("initialized") == false) {
$dialog.dialog({
autoOpen: false,
modal:true,
//width:Math.round($(window).width()/100*80),
//height:Math.round($(window).height()/100*80),
width:800,
height:460,
minWidth:600,
minHeight:460,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Create"),
icon: "ui-icon-plus",
click: function() {
var filename = $('#addObjName').val()
var dirname = $('#addObjDirName').val()
var options = {}
var result = trans.createFile(filename, dirname, options);
if (result.error) return alert(result.msg);
$(this).dialog( "close" );
}
}
]
});
$dialog.addClass("initialized");
}
$dialog.dialog("open");
return $dialog;
}
// ==============================================================
//
// M A I N M E N U
//
// ==============================================================
ui.MainMenu = function() {
}
ui.MainMenu.prototype.drawRecentFiles = function() {
if (typeof sys.config == 'undefined') return false;
if (typeof sys.config.historyOpenedFiles == 'undefined') return false;
var childTemplate = $("#mainMenu .recentFiles ul li").eq(0).clone(true, true);
childTemplate.removeClass("ui-state-disabled");
$("#mainMenu .recentFiles ul").empty();
for (var id=0; id<sys.config.historyOpenedFiles.length; id++) {
var thisTemplate = childTemplate.clone(true, true);
//console.log(sys.config.historyOpenedFiles[id].path);
thisTemplate.removeAttr("id");
var num = id+1;
thisTemplate.find("div").text(num+": "+common.cropLongText(sys.config.historyOpenedFiles[id].path, 70));
thisTemplate.attr("title", sys.config.historyOpenedFiles[id].path);
thisTemplate.data("id", id);
$("#mainMenu .recentFiles ul").append(thisTemplate);
}
}
ui.MainMenu.prototype.open = function() {
if ($("#mainMenu").hasClass("rendered") == false) {
this.init();
} else {
this.drawRecentFiles();
$("#mainMenu").menu( "refresh" );
}
$("#mainMenu").removeClass("hidden");
$("#mainMenu").show({
effect:"fade",
duration:100
});
$("#button-translatorplus").addClass("active");
$(document).on("mouseup.mainmenu", function(e) {
var container = $("#mainMenu");
if (!container.is(e.target) && container.has(e.target).length === 0) {
//container.addClass("hidden");
//ui.closeMainMenu();
ui.mainMenu.close();
$(document).off("mouseup.mainmenu");
}
});
}
ui.MainMenu.prototype.close = function() {
$("#button-translatorplus").removeClass("active");
$("#mainMenu").menu("collapseAll");
$("#mainMenu").hide({
effect:"fade",
duration:100
});
}
/**
* @param {} key
* @param {} object
* {
* id
* label
* }
*/
ui.MainMenu.prototype.addChild = function(parentKey, object) {
var $rootObj = $("#mainMenu");
var $thisMenu = $rootObj.find("[data-menuid="+parentKey+"]");
var $ul = $thisMenu.find(">ul")
if ($ul.length == 0) {
$ul = $("<ul></ul>");
$thisMenu.append($ul);
}
var $newMenu = $(`<li><div>${object.label}</div></li>`);
if (object.id) $newMenu.attr("data-menuid", object.id);
$ul.append($newMenu);
return $newMenu;
}
ui.MainMenu.prototype.addBefore = function(siblingKey, object) {
var $rootObj = $("#mainMenu");
var $thisMenu = $rootObj.find("[data-menuid="+siblingKey+"]");
var $newMenu = $(`<li><div>${object.label}</div></li>`);
if (object.id) $newMenu.attr("data-menuid", object.id);
$thisMenu.before($newMenu);
return $newMenu;
}
ui.MainMenu.prototype.addAfter = function(siblingKey, object) {
var $rootObj = $("#mainMenu");
var $thisMenu = $rootObj.find("[data-menuid="+siblingKey+"]");
var $newMenu = $(`<li><div>${object.label}</div></li>`);
if (object.id) $newMenu.attr("data-menuid", object.id);
$thisMenu.after($newMenu);
return $newMenu;
}
ui.MainMenu.prototype.unInit = function() {
if ($("#mainMenu").hasClass("rendered") == false) return;
var $mainMenu = $("#mainMenu");
$mainMenu.menu("destroy");
$mainMenu.removeClass("rendered");
}
ui.MainMenu.prototype.init = function() {
if ($("#mainMenu").hasClass("rendered") == true) return false;
this.drawRecentFiles();
$("#mainMenu").removeClass("hidden");
$("#mainMenu").menu({
position: {
my: "right top",
at: "left+5 top"
},
select: function(e, thisUi) {
console.log("menu selected");
console.log(arguments);
if (thisUi.item.hasClass('ui-state-disabled')) return false;
if (thisUi.item.find(".ui-menu").length == 0) ui.mainMenu.close();
if (thisUi.item.attr("data-delegate")) {
$(thisUi.item.attr("data-delegate")).trigger("click");
return true;
}
var initiate = thisUi.item.attr("data-initiate");
switch(initiate) {
case "openHistory" :
if (typeof thisUi.item.data('id') == 'undefined') return alert(t("Unable to open that file!"));
if (typeof sys.config.historyOpenedFiles[thisUi.item.data('id')] == 'undefined') return alert(t("Unable to open that file!"));
var thisInfo = sys.config.historyOpenedFiles[thisUi.item.data('id')];
var conf = confirm("Open "+thisInfo.path+"?\nTitle: "+thisInfo.gameTitle);
if (conf) {
sys.loadFileHistory(thisUi.item.data('id'));
}
break;
case "wordwrap" :
ui.batchWrapingDialog();
break;
case "trim" :
ui.openTrimWindow();
break;
case "padding" :
ui.openPaddingWindow();
break;
case "importSpreadsheet":
ui.openImportSpreadsheetDialog();
break;
case "importRPGMTrans":
ui.openImportRPGMTransDialog();
break;
case "contextTool":
ui.showBusyOverlay();
setTimeout(function() {
ui.contextToolDialog();
}, 250);
break;
case "closeProject":
// eslint-disable-next-line
var conf = confirm(t("Are you sure want to close the project?\nYou will lost any unsaved changes!"));
if (!conf) return;
trans.closeProject();
break;
case "exit" :
// eslint-disable-next-line
var conf = confirm(t("Are you sure want to exit Translator++?\nYou will lost any unsaved changes!"));
if (!conf) return;
window.close();
break;
}
$(thisUi.item).trigger("select", thisUi);
}
});
$("#mainMenu").hide();
$("#mainMenu").addClass("rendered");
}
ui.mainMenu = new ui.MainMenu();
ui.getCurrentEditedCellElm = function() {
if (typeof trans.lastSelectedCell == 'undefined') return false;
if (ui.isRowVisible(trans.lastSelectedCell[0]) == false) return false;
var rowOffset = trans.lastSelectedCell[0]-trans.grid.rowOffset();
var colOffset = trans.lastSelectedCell[1]-trans.grid.colOffset();
ui.selectedCell = $(".ht_master .htCore tbody tr").eq(rowOffset).find("td").eq(colOffset);
return ui.selectedCell;
}
ui.togglePreWhitespaces = function(toggle) {
if ($("#css_togglePreWhitespaces").length == 0) {
$("head").append($('<style id="css_togglePreWhitespaces"></style>'))
}
var cssElm = $("#css_togglePreWhitespaces");
sys.config.wordWrapTable = sys.config.wordWrapTable||false;
if (typeof toggle == 'undefined') {
if (cssElm.hasClass("active")) {
toggle = false;
} else {
toggle = true;
}
}
if (Boolean(toggle) == false) {
cssElm.text("#table tbody td { }");
cssElm.removeClass("active");
trans.grid.render()
$(".menu-button.wordWrapTable").removeClass("checked");
sys.config.wordWrapTable = false;
return false;
} else {
cssElm.text("#table tbody td { white-space: pre; }");
cssElm.addClass("active");
trans.grid.render()
$(".menu-button.wordWrapTable").addClass("checked");
sys.config.wordWrapTable = true;
return true;
}
}
ui.toggleMonoSpace = function(toggle) {
if ($("#css_toggleMonoSpace").length == 0) {
$("head").append($('<style id="css_toggleMonoSpace"></style>'))
}
var cssElm = $("#css_toggleMonoSpace");
sys.config.monoSpaceTable = sys.config.monoSpaceTable||false;
if (typeof toggle == 'undefined') {
if (cssElm.hasClass("active")) {
toggle = false;
} else {
toggle = true;
}
}
if (Boolean(toggle) == false) {
cssElm.text("#table tbody td { }");
cssElm.removeClass("active");
trans.grid.render();
sys.config.monoSpaceTable = false;
$(".menu-button.monospace").removeClass("checked");
return false;
} else {
//cssElm.text("#table tbody td { font-family: monospace; }");
cssElm.text("#table tbody td { font-family: mPlusRegular; }");
cssElm.addClass("active");
$("body").one("mouseover", function() {
trans.grid.render();
})
trans.grid.render();
sys.config.monoSpaceTable = true;
$(".menu-button.monospace").addClass("checked");
return true;
}
}
ui.renderColorTagSelector = function($selector) {
$selector = $selector||$(".colorTagSelector");
if ($selector.hasClass("rendered")) return $selector;
for (var colorName in consts.tagColor) {
var $temp = $('<input type="checkbox" value="'+colorName+'" />');
$temp.addClass("colorTagSelector tagSelector");
$temp.addClass(colorName);
$temp.css("background-color", consts.tagColor[colorName]);
$temp.attr("title", colorName)
$temp.attr("name", "tagSelector");
$selector.append($temp);
}
$selector.addClass("rendered")
return $selector;
}
ui.blurAll = function() {
$(".toolbar, .panel-wrapper, #cellSelectionInfo, .footer").addClass("blur");
}
ui.unBlurAll = function() {
$(".toolbar, .panel-wrapper, #cellSelectionInfo, .footer").removeClass("blur");
}
ui.pathNotAccessibleDialog = function() {
if ($("#pathNotAccessible").hasClass("initialized") == false) {
$("#pathNotAccessible").dialog({
autoOpen: false,
modal:true,
minWidth:480,
minHeight:320,
maxWidth:640,
maxHeight:420,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
});
$("#pathNotAccessible").addClass("initialized");
}
$("#pathNotAccessible").dialog("open");
return $("#pathNotAccessible");
}
// ===========================================================
// New project class
// ===========================================================
ui.showPopup = async function(name, content, options) {
this.popups = this.popups||{};
//this.popups[name] = this.popups[name]
options = options||{};
options.onDone = options.onDone||function(){}
options.title = options.title||"Info";
options.allExternal = options.allExternal || false; // makes all a elm to open in external browser
options.HTMLcleanup = options.HTMLcleanup || false; // cleanup HTML data from unsave tags
options.rebuild = options.rebuild || false;
options.onClose = options.onClose || function(){}
options.isUnpreventable = options.isUnpreventable || false;
options.buttons = options.buttons || [
{
text: "Close",
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
}
]
sys.config.popupData = sys.config.popupData||{};
sys.config.popupData[name] = sys.config.popupData[name]||{};
var thisID = "popup_"+name;
if ($("#"+thisID).length == 0 || options.rebuild == true) {
if ($("#"+thisID).length > 0) $("#"+thisID).remove();
$("#template").append("<div id='"+thisID+"' data-popupid='"+thisID+"' class='"+thisID+" autoPopupGenerator'>\
<div class='popupContent'></div>\
</div>");
$("#"+thisID).data("name", name);
$("#"+thisID).dialog({
autoOpen: false,
modal:true,
title:options.title||"Info",
width:options.width||Math.round($(window).width()/100*50),
height:options.height||Math.round($(window).height()/100*60),
minWidth:options.minWidth||640,
minHeight:options.minHeight||320,
classes:options.classes,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
close: function( event, ui ) {
// window closed
var $thisPopup = $(this);
var thisName = $(this).data('name');
if (typeof options.onClose == "function") options.onClose.call(this);
if ($thisPopup.closest('.ui-dialog').find(".doNotShowAgain").prop("checked")) {
console.log("do not show again is checked");
console.log(thisName);
sys.config.popupData[thisName] = sys.config.popupData[thisName] || {};
sys.config.popupData[thisName].isDeny = true;
sys.saveConfig();
}
},
buttons:options.buttons
});
var $toolBar = $("<div class='popupToolbar'><label><input type='checkbox' class='doNotShowAgain' /> "+t("Do not show this message again!")+"</label></div>");
var $thisDialog = $("[aria-describedby='"+CSS.escape(thisID)+"']");
$thisDialog.find(".ui-dialog-title").prepend("<span class='icon-info-circled-1'></span>");
$thisDialog.addClass("popup generatedPopup");
$thisDialog.find(".ui-dialog-buttonpane").prepend($toolBar);
if (Boolean(sys.config.popupData[name].isDeny) == true) $toolBar.find(".doNotShowAgain").prop("checked", true)
$toolBar.find(".doNotShowAgain").off("change")
$toolBar.find(".doNotShowAgain").on("change", function() {
//var name = $(this).closest(".autoPopupGenerator").data("name");
sys.config.popupData[name].isDeny = $(this).prop("checked")
sys.saveConfig();
})
if (options.isUnpreventable) $toolBar.addClass("hidden");
}
$("#"+thisID).data("onClose", options.onDone);
if (options.HTMLcleanup) {
var $content = $(content);
$content.find("style, script, iframe, webview").remove();
$("#"+thisID).find(".popupContent").html($content);
} else {
$("#"+thisID).find(".popupContent").html(content);
}
if (options.allExternal) {
$("#"+thisID).find(".popupContent a").off("click")
$("#"+thisID).find(".popupContent a").on("click", function(e) {
var href = $(this).attr("href");
if (href[0] == "#") return;
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
} else {
$("#"+thisID).find("a.externalLink, a[external]").on("click", function(e) {
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
}
/*
$("#"+thisID).find("a.externalLink, a[external]").on("click", function(e) {
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
*/
if (Boolean(sys.config.popupData[name].isDeny)==true && Boolean(options.force) == false) {
console.log("Popup '"+name+"' is denied by user!");
return $("#"+thisID)
}
return new Promise((resolve, reject) => {
$("#"+thisID).dialog("open");
$("#"+thisID).one( "dialogclose", function( event, ui ) {
resolve($("#"+thisID));
});
})
}
ui.openFileDialog = async function(options) {
return new Promise((resolve, reject) => {
options = options||{};
options.onSelect = options.onSelect || function(path) { console.log(path)};
options.accept = options.accept || "";
options.multiple = options.multiple || false;
options.dir = options.dir || false;
options.save = options.save || undefined;
options.default = options.default || "";
var $elm = $("<input type='file' style='display:none' class='hidden __pseudoFileDlg1' />");
$elm.on("input", function() {
var thisVal = $(this).val();
console.log("input")
resolve(thisVal)
$(this).remove();
options.onSelect.call(this, thisVal);
});
$(window).one("focus", async function() {
await common.wait(3000);
if (!$elm?.length) return;
$elm.remove();
resolve("");
})
if (options.accept.length > 0) $elm.attr("accept", options.accept)
if (options.default.length > 0) $elm.attr("nwworkingdir", options.default)
if (options.dir) $elm.attr("nwdirectory", "nwdirectory")
if (options.multiple) $elm.attr("multiple", "multiple")
if (typeof options.save !== 'undefined') $elm.attr("nwsaveas", options.save)
//$("body").append($elm);
$elm.trigger("click")
})
}
ui.initFileSelectorDragSelect = function() {
var DragSelect = DragSelect||require("dragselect");
window.ds = new DragSelect({
selectables: document.getElementsByClassName('data-selector'),
autoScrollSpeed: 15,
area : document.getElementById("fileList"),
callback : function(elm) {
//console.log($(elm));
//console.log(this);
var $elm = $(elm);
// ignore selection if selecting less than 2 row
var orig = this._initialCursorPos.x+","+this._initialCursorPos.y;
var after = this._newCursorPos.x+","+this._newCursorPos.y;
if (orig == after) return false;
if ($elm.length <= 1) return false;
$elm.each(function() {
var $input = $(this).find("input");
$(this).removeClass("ds-hover");
$input.prop("checked", true)
$input.trigger("change");
window.ds.clearSelection();
})
}
});
}
/**
* Create a nwjs native menu from object
* More info about nwjs's native menu at : https://docs.nwjs.io/en/latest/References/Menu/
* @param {Obj[]} menuObj - Array of menu object
*/
ui.createMenu = function(menuObj) {
if (!menuObj) throw new Error("You must specify a menu object as the first parameter")
if (menuObj.constructor.name == "Menu") return menuObj;
var menu = new nw.Menu();
for (let thisMenu of menuObj) {
if (!thisMenu) continue;
menu.append(new nw.MenuItem(thisMenu));
}
return menu;
}
// ===========================================================
// Toolbar group class
// ===========================================================
ui.Toolbar = function(id, options) {
if (typeof id == 'object') {
options = id;
id = options.id || common.generateId();
}
this.options = options || {};
this.isVisible = this.options.isVisible || false;
this.buttons = {};
this.groups = {};
this.id = id||common.generateId();
this.defaultGroup = "group0";
this.init();
}
ui.Toolbar.list = {}
ui.Toolbar.getById = function(id) {
return this.list?.[id];
}
ui.Toolbar.prototype.onReady = function(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
ui.Toolbar.prototype.init = function(){
this.onReady(()=> {
this.container = $(".toolbarGroup")
if (this.container.find(".toolbar[data-id='"+this.id+"']").length > 0) {
this.elm = this.container.find(".toolbar[data-id='"+this.id+"']");
} else {
this.elm = $('<div class="toolbar" data-id="'+this.id+'">')
if (this.isVisible == false) this.elm.addClass("hidden");
this.container.append(this.elm);
}
if (this.elm.find(".toolbar-content").length == 0) {
this.addButtonGroup(this.defaultGroup);
}
this.options.buttons = this.options.buttons || {};
for (var i in this.options.buttons) {
//console.log("adding buttons", this.options.buttons[i]);
this.addButton(this.options.buttons[i]);
}
ui.Toolbar.list[this.id] = this;
})
}
ui.Toolbar.prototype.getButtonGroupElm = function(id) {
if (this.groups[id]?.elm) return this.groups[id].elm;
return this.elm.find(`.toolbar-content[data-id="${CSS.escape(id)}"]`)
}
ui.Toolbar.prototype.addButtonGroup = function(id) {
this.groups[id] = {
elm : $('<div class="toolbar-content" data-id="'+id+'"></div>')
}
this.elm.append(this.groups[id].elm);
return this.groups[id];
}
ui.Toolbar.prototype.addButton = function(buttonObj) {
buttonObj = buttonObj || {};
buttonObj.id = buttonObj.id || common.generateId();
buttonObj.group = buttonObj.group || this.defaultGroup;
buttonObj.title = buttonObj.title || "";
buttonObj.checked = buttonObj.checked || false;
buttonObj.img = buttonObj.img || "";
buttonObj.icon = buttonObj.icon || "";
buttonObj.elm = buttonObj.elm || '<button class="menu-button" data-tranattr="title" title="'+buttonObj.title+'"></button>'
buttonObj.elm = $(buttonObj.elm);
buttonObj.checked = buttonObj.checked || false;
buttonObj.onClick = buttonObj.onClick || function(){};
buttonObj.elm.attr("data-id", buttonObj.id);
if (buttonObj.img !== '') {
buttonObj.elm.html('<img src="'+buttonObj.img+'" alt="" />')
} else if (buttonObj.icon !=='') {
buttonObj.elm.html('<i class="'+buttonObj.icon+'"></i>')
} else {
buttonObj.elm.html('<img src="img/transparent.png" alt="" />')
}
if (buttonObj.checked) buttonObj.elm.addClass('checked');
buttonObj.elm.on("click", function() {
buttonObj.onClick.apply(this, arguments);
})
if (this.buttons[buttonObj.id]) buttonObj.elm.remove();
//registering button
this.buttons[buttonObj.id] = buttonObj;
//addding to element
const $buttonGroup = this.getButtonGroupElm(buttonObj.group);
$buttonGroup.append(buttonObj.elm);
return buttonObj.elm;
}
ui.Toolbar.prototype.addButtonWithMenu = function(buttonObj, menu) {
buttonObj = buttonObj || {};
menu = ui.createMenu(menu);
buttonObj.id = buttonObj.id || common.generateId();
buttonObj.group = buttonObj.group || this.defaultGroup;
buttonObj.title = buttonObj.title || "";
buttonObj.checked = buttonObj.checked || false;
buttonObj.img = buttonObj.img || "";
buttonObj.icon = buttonObj.icon || "";
buttonObj.elm = buttonObj.elm || `<span class="menu-button buttonGroup"><button class="hasMenuSide mainButton" data-tranattr="title" title="${buttonObj.title}" ></button><button class="menuSide"></button></span>`
buttonObj.elm = $(buttonObj.elm);
buttonObj.checked = buttonObj.checked || false;
buttonObj.onClick = buttonObj.onClick || function(){};
buttonObj.onExpanderClick = buttonObj.onExpanderClick || function(){};
buttonObj.elm.attr("data-id", buttonObj.id);
if (buttonObj.img !== '') {
buttonObj.elm.find("button").eq(0).html('<img src="'+buttonObj.img+'" alt="" />')
} else if (buttonObj.icon !=='') {
buttonObj.elm.find("button").eq(0).html('<i class="'+buttonObj.icon+'"></i>')
} else {
buttonObj.elm.find("button").eq(0).html('<img src="img/transparent.png" alt="" />')
}
if (buttonObj.checked) buttonObj.elm.addClass('checked');
buttonObj.elm.find("button").eq(0).on("click", function() {
buttonObj.onClick.apply(this, arguments);
})
buttonObj.elm.find("button").eq(1).on("click", function(ev) {
ev.preventDefault();
var $wrapper = buttonObj.elm;
var left = parseInt($wrapper.offset().left);
var top = parseInt($wrapper.offset().top + $wrapper.outerHeight());
if (menu) menu.popup(left, top);
buttonObj.onExpanderClick.apply(this, arguments);
})
if (this.buttons[buttonObj.id]) buttonObj.elm.remove();
//registering button
this.buttons[buttonObj.id] = buttonObj;
//addding to element
const $buttonGroup = this.getButtonGroupElm(buttonObj.group);
$buttonGroup.append(buttonObj.elm);
return buttonObj.elm;
}
ui.Toolbar.prototype.addMenuButton = function(buttonObj, menu) {
buttonObj = buttonObj || {};
menu = ui.createMenu(menu);
buttonObj.id = buttonObj.id || common.generateId();
buttonObj.group = buttonObj.group || this.defaultGroup;
buttonObj.title = buttonObj.title || "";
buttonObj.checked = buttonObj.checked || false;
buttonObj.img = buttonObj.img || "";
buttonObj.icon = buttonObj.icon || "";
buttonObj.elm = buttonObj.elm || `<button class="menu-button buttonExpand" data-tranattr="title" title="${buttonObj.title}"></button>`
buttonObj.elm = $(buttonObj.elm);
buttonObj.checked = buttonObj.checked || false;
buttonObj.onClick = buttonObj.onClick || function(){};
buttonObj.onExpanderClick = buttonObj.onExpanderClick || function(){};
buttonObj.elm.attr("data-id", buttonObj.id);
if (buttonObj.img !== '') {
buttonObj.elm.html('<img src="'+buttonObj.img+'" alt="" />')
} else if (buttonObj.icon !=='') {
buttonObj.elm.html('<i class="'+buttonObj.icon+'"></i>')
} else {
buttonObj.elm.html('<img src="img/transparent.png" alt="" />')
}
if (buttonObj.checked) buttonObj.elm.addClass('checked');
buttonObj.elm.on("click", function(ev) {
ev.preventDefault();
var $wrapper = buttonObj.elm;
var left = parseInt($wrapper.offset().left);
var top = parseInt($wrapper.offset().top + $wrapper.outerHeight());
if (menu) menu.popup(left, top);
buttonObj.onClick.apply(this, arguments);
})
if (this.buttons[buttonObj.id]) buttonObj.elm.remove();
//registering button
this.buttons[buttonObj.id] = buttonObj;
//addding to element
const $buttonGroup = this.getButtonGroupElm(buttonObj.group);
$buttonGroup.append(buttonObj.elm);
return buttonObj.elm;
}
ui.Toolbar.prototype.getButtonElm = function(id) {
if (typeof id == "string") return this.elm.find(`.toolbar-content .menu-button[data-id="${CSS.escape(id)}"]`)
return $(id);
}
/**
* Overlay a small icon on icon
* @param {string} buttonId - Id of the button
* @param {string} iconName - name of the icon (see fontello documentation)
* @param {string} [color] - Color of the emblem
*/
ui.Toolbar.prototype.setButtonEmblem = function(buttonId, iconName, color="#ffa500") {
const btnElm = this.getButtonElm(buttonId);
btnElm.addClass("iOverlay")
btnElm.addClass(iconName)
btnElm.attr("data-overlay", iconName)
btnElm.css("--icon-overlay-color", color);
}
ui.Toolbar.prototype.unsetButtonEmblem = function(buttonId) {
const btnElm = this.getButtonElm(buttonId);
const overlay = btnElm.attr("data-overlay")
btnElm.removeClass("iOverlay")
btnElm.removeClass(overlay)
btnElm.removeAttr("data-overlay")
}
ui.Toolbar.prototype.remove = function() {
this.elm.remove();
}
ui.Toolbar.prototype.show = function(){
ui.onDOMReady(()=> {
this.container.find(".toolbar").addClass("hidden")
this.elm.removeClass("hidden")
})
}
// ===========================================================
// Ribbon menu class
// ===========================================================
ui.RibbonMenu = function() {
var that = this;
this.container;
this.ribbons = {};
this.defaultClickEvt = function() {
var thisId = $(this).data("id");
//console.log("clicking, this id : ", thisId);
that.ribbons[thisId].onClick = that.ribbons[thisId].onClick || function(){}
ui.ribbonMenu.select($(this), that.ribbons[thisId].onClick);
}
this.lastSelected = "";
this.init();
}
ui.RibbonMenu.prototype.init = function(){
this.onReady(()=> {
this.container = $("#applicationBar .appActionsLeft");
this.add("start", {
title : "Start",
locked : true,
onClick : function() {
if ($("#introWindow").not(":visible")) ui.introWindowShow();
}
})
this.add("home", {
title : "Home",
locked : true,
onClick : function() {
if ($("#introWindow").is(":visible")) ui.introWindowClose();
},
toolbar : new ui.Toolbar("home")
})
this.clear();
var $ribbons = $("#applicationBar .ribbonMenu");
//var that = this;
$ribbons.off("click.ribbonAct");
$ribbons.on("click.ribbonAct", this.defaultClickEvt);
})
}
ui.RibbonMenu.prototype.select = function($ribbon, trigger) {
if (typeof trigger == 'undefined') trigger = true;
if (typeof $ribbon == 'string') {
$ribbon = $("#applicationBar .ribbonMenu[data-id='"+$ribbon+"']");
}
var thisId = $ribbon.data("id");
var $ribbons = $("#applicationBar .ribbonMenu");
$ribbons.removeClass("active");
$ribbon.addClass("active");
this.lastSelected = thisId;
$(document).trigger("onRibbonSelect", thisId);
if (trigger == false) return;
if (this.ribbons[thisId].toolbar) this.ribbons[thisId].toolbar.show();
if (typeof this.ribbons[thisId].onClick !== 'function') return;
this.ribbons[thisId].onClick.call(this)
}
ui.RibbonMenu.prototype.onReady = function(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
ui.RibbonMenu.prototype.isExist = function(id) {
if (this.container.find(".ribbonMenu[data-id='"+id+"']").length > 0) return true;
return false;
}
ui.RibbonMenu.prototype.add = function(id, options) {
if (typeof id !== "string") return;
if (id == "") return;
options = options || {};
options.onClick = options.onClick || function(){};
options.title = options.title || options.id;
if (typeof options.toolbar == 'object' && !(options.toolbar instanceof ui.Toolbar)) {
options.toolbar = new ui.Toolbar(options.toolbar)
}
this.ribbons[id] = options;
this.onReady(()=>{
var $template = this.container.find(".ribbonMenu[data-id='"+id+"']")
if ($template.length == 0) {
$template = $('<div class="ribbonMenu"></div>');
$template.attr("data-id", id);
$template.html(options.title);
this.container.append($template);
}
$template.off("click");
$template.on("click", this.defaultClickEvt)
this.ribbons[id].elm = $template;
// select if last selection is this ribbon
if (this.lastSelected == id) {
this.select(id);
}
})
return this.ribbons[id]
}
ui.RibbonMenu.prototype.remove = function(id) {
if (!this.ribbons[id]) return;
if (this.ribbons[id].locked) return;
if (this.ribbons[id].toolbar) {
this.ribbons[id].toolbar.remove();
}
delete this.ribbons[id]
this.container.find(".ribbonMenu[data-id='"+id+"']").remove();
}
ui.RibbonMenu.prototype.clear = function() {
// remove all
for (var key in this.ribbons) {
if (this.ribbons[key].locked) continue;
this.remove(key);
}
}
ui.ribbonMenu = new ui.RibbonMenu();
// ===========================================================
// MENU BUTTONS
// ===========================================================
ui.addIconOverlay = function($elm, icon) {
// add icon overlay into a button
$elm.addClass('icon-'+icon);
$elm.addClass('iOverlay');
}
ui.clearIconOverlay = function($elm) {
$elm.removeClass (function (index, className) {
return (className.match (/(^|\s)icon-\S+/g) || []).join(' ');
});
$elm.removeClass('iOverlay');
}
/**
* Creates a form dialog with custom fields.
* @param {jQuery|Object} $elm - jQuery object or customField object representing the element to which the form will be appended.
* @param {Object} [options={}] - Options for customization.
* @param {boolean} [options.ignoreValidation=false] - Flag to submit the form regardless of validation errors.
* @returns {Promise<Object>} - A promise that resolves to the form field values when the form is submitted successfully, or rejects if an error occurs.
*/
ui.form = async function($elm, options={}) {
options ||= {};
// submit regardless validation error
options.ignoreValidation ||= false;
return new Promise((resolve, reject) => {
var result;
const $form = $(`<form class="uiCustomFields"></form>`);
const customFields = new CustomFields($form, $elm);
$form.data("customFields", customFields)
$form.on("submit", function(e) {
e.preventDefault();
console.log("form submitted!");
//$form.dialog("close");
let validate = {};
if (!options.ignoreValidation) {
validate = customFields.validate();
}
if (!validate?.errors) {
result = customFields.getValues();
$form.dialog("close");
}
});
const dialogOptions = {...{
title : options.title || t("Form"),
autoOpen: false,
modal :options.modal || true,
width :options.width ||800,
height :options.height ||600,
minWidth:options.minWidth ||640,
minHeight:options.minHeight ||320,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
close:function(event, ui) {
resolve(result);
common.wait(500)
.then(()=> {
console.log("removing elm");
$form.remove();
});
},
buttons:[
{
text: t("Cancel"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Ok"),
click: async function() {
$form.submit();
}
}
]
}, ...options}
$form.dialog(dialogOptions);
$form.dialog("open");
})
}
// ===========================================================
// New project class
// ===========================================================
const NewProjectDialog = function($elm) {
this.onInits = this.onInits||[];
this.$elm = $elm ;
this.isInitialized = false;
this._onInitCreateMenu = [];
this.slides = {};
}
NewProjectDialog.prototype.init =function() {
var that = this;
this.$elm = this.$elm || $("#dialogNewProject");
if (this.$elm.hasClass("initialized")) {
this.$elm.dialog( "destroy" );
this.$elm.removeClass("initialized");
}
this.$elm.dialog({
autoOpen: false,
modal:true,
minWidth:480,
minHeight:320,
width:Math.round($(window).width()/100*80),
height:Math.round($(window).height()/100*80),
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons: [
{
text: "Cancel",
//icon: "ui-icon-heart",
click: function() {
$(this).dialog( "close" );
}
}
]
});
this.reset();
this.$elm.find("[data-gotoSlide]").each(function() {
$(this).on("click.slideJumper", function() {
var targetSlide = $(this).attr("data-gotoSlide");
console.log("jump to slide", targetSlide);
if (!targetSlide) return;
that.gotoSlide(targetSlide, $(this).closest("[data-slideid]").attr("data-slideid"));
});
})
this.$elm.find("form").each(function() {
$(this).on("submit", function(e) {
e.preventDefault();
});
})
this.$elm.addClass("initialized");
// execute onInits
for (let i=0; i<this.onInits.length; i++) {
if (typeof this.onInits[i] !== 'function') continue;
try {
this.onInits[i].apply(this, arguments);
} catch (e) {
console.warn(e);
}
}
this.onInits = [];
this.isInitialized = true;
if (this._onInitCreateMenu.length > 0) {
for (let i=0; i<this._onInitCreateMenu.length; i++) {
this.addMenu(this._onInitCreateMenu[i]);
}
}
this.evalEvents();
}
NewProjectDialog.prototype.addMenu = function(options) {
if (this.isInitialized == false) {
console.log("this object", this);
this._onInitCreateMenu.push(options);
return;
}
var $mainSlide = this.$elm.find("[data-slideId=1]");
var that = this;
options = options||{};
options.icon = options.icon || "";
options.descriptionBar = options.descriptionBar || "";
options.actionBar = options.actionBar || [];
options.goToSlide = options.goToSlide || 0;
// slides can be html element, jquery, or object {html: 'html element'}
options.slides = options.slides||{}
options.at = options.at||undefined;
options.at = Math.min(options.at, $mainSlide.children().length);
var $slide1 = $('<a href="#" class="dialogSelection" data-gotoSlide="'+options.goToSlide+'">\
<div class="iconBar"><img src="'+options.icon+'" alt="" /></div>\
<div class="descriptionBar"></div>\
<div class="actionBar"></div>\
</a>');
$slide1.find(".descriptionBar").append(options.descriptionBar);
$slide1.find(".actionBar").append(options.actionBar);
$slide1.on("click.slideJumper", function() {
var targetSlide = $(this).attr("data-gotoSlide");
console.log("jump to slide", targetSlide);
if (!targetSlide) return;
that.gotoSlide(targetSlide, $(this).closest("[data-slideid]").attr("data-slideid"));
});
if (typeof options.at == 'undefined') {
$mainSlide.append($slide1);
} else {
$slide1.insertAt(options.at,$mainSlide)
}
for (var slideId in options.slides) {
if (options.slides[slideId] instanceof jQuery) {
let $content = options.slides[slideId]
this.newSlide(slideId, $content);
} else if (options.slides[slideId] instanceof HTMLElement) {
let $content = $(options.slides[slideId])
this.newSlide(slideId, $content);
} else if (typeof options.slides[slideId] == 'object' && Boolean(options.slides[slideId]) == true) {
this.newSlide(slideId, $(options.slides[slideId].html), options.slides[slideId]);
}
}
}
NewProjectDialog.prototype.evalEvents = function() {
var that = this;
var $thisElm = this.$elm;
if (this.isInitialized == false) {
$thisElm = $("#dialogNewProject");
}
$thisElm.find('[data-slideId]').not('.eventRendered').each(function() {
var $this = $(this);
var thisId = $this.attr('data-slideId');
if (Boolean(that.slides[thisId])==false) return;
if (Boolean(that.slides[thisId].options)==false) return;
if (typeof that.slides[thisId].options.onActive == 'function') {
$this.on("active", that.slides[thisId].options.onActive)
}
if (typeof that.slides[thisId].options.onBeforeActive == 'function') {
$this.on("beforeActive", that.slides[thisId].options.onActive)
}
if (typeof that.slides[thisId].options.onInactive == 'function') {
$this.on("inactive", that.slides[thisId].options.onActive)
}
$this.addClass("eventRendered");
});
}
NewProjectDialog.prototype.newSlide = function(slideId, $content, options) {
if (typeof $content == "object" && $content.schema) {
let customField = new CustomFields($content);
$content = customField.$elm
}
if (!slideId) return console.warn("id must not blank");
options = options || $content.data("options") || {};
var $thisElm = this.$elm;
if (this.isInitialized == false) {
$thisElm = $("#dialogNewProject");
}
var makeSlide = (slideId, $content, options)=> {
var $currentSlide = $thisElm.find("[data-slideId="+slideId+"]");
if ($currentSlide.length == 0 ){
$currentSlide = $('<div class="dialogSection" data-slideid="'+slideId+'">');
$thisElm.append($currentSlide);
}
$currentSlide.empty();
ui.render($content);
$currentSlide.append($content);
this.slides[slideId] = {
options : options || {},
html : $currentSlide
};
}
makeSlide(slideId, $content, options);
this.evalEvents();
}
NewProjectDialog.prototype.resetNav = function() {
this.$elm.dialog( "option", "buttons", [{
text: t("Cancel"),
click: function() {
$(this).dialog( "close" );
}
}]);
}
NewProjectDialog.prototype.gotoSlide = function(targetSlide, sourceSlide) {
if (!targetSlide) return;
var $previousSlide = this.$elm.find("[data-slideid].active");
this.$elm.find("[data-slideid].active").trigger("inactive", this);
var $thisSlide = this.$elm.find("[data-slideid="+targetSlide+"]")
$thisSlide.trigger("beforeActive", this);
$(document).trigger("newProjectSlideChange", {id:targetSlide, elm:$thisSlide, prev:$previousSlide.attr("[data-slideid]")});
console.log("changing slide : ", targetSlide);
this.$elm.find("[data-slideid]").addClass("hidden");
this.$elm.find("[data-slideid]").removeClass("active");
$thisSlide.removeClass("hidden");
$thisSlide.addClass("active");
// cache the path
if (sourceSlide) {
$thisSlide.data("previous", sourceSlide)
}
// running onActive
console.log("triggering event : 'active' on elm ", $thisSlide);
$thisSlide.trigger("active", this);
sourceSlide = sourceSlide || $thisSlide.data("previous");
// rendering navigation buttons
var that = this;
if (targetSlide == "1") {
this.resetNav();
return;
}
var buttons = []
if (sourceSlide) {
buttons.push({
text: t("Back"),
click: function() {
that.gotoSlide(sourceSlide);
}
})
}
buttons.push({
text: t("Cancel"),
click: function() {
$(this).dialog( "close" );
}
});
if (this.slides[targetSlide]) {
this.slides[targetSlide].options = this.slides[targetSlide].options ||{}
if (Array.isArray(this.slides[targetSlide].options.buttons)) {
buttons = buttons.concat(this.slides[targetSlide].options.buttons)
}
}
this.$elm.dialog( "option", "buttons", buttons);
}
NewProjectDialog.prototype.reset = function() {
this.$elm.find("[data-slideid]").addClass("hidden");
this.$elm.find("[data-slideid]").removeClass("active");
this.$elm.find("[data-slideid=1]").removeClass("hidden");
this.$elm.find("[data-slideid=1]").addClass("active");
this.$elm.dialog( "option", "width", Math.round($(window).width()/100*80));
this.$elm.dialog( "option", "height", Math.round($(window).height()/100*80));
this.$elm.dialog( "option", "buttons",
[
{
text: t("Cancel"),
//icon: "ui-icon-heart",
click: function() {
$(this).dialog("close");
}
}
]
);
this.$elm.find("form").each(function() {
$(this)[0].reset();
})
}
NewProjectDialog.prototype.getSlide = function(slideID) {
return this.$elm.find(`[data-slideid="${CSS.escape(slideID)}"]`);
}
NewProjectDialog.prototype.getFormValues = function(slideIds) {
if (!Array.isArray(slideIds)) slideIds = [slideIds];
var result = {}
for (let i in slideIds) {
let $thisSlide = this.getSlide(slideIds[i]);
if (!$thisSlide.length) continue;
let $forms = $thisSlide.find("form");
if (!$forms.length) continue;
if ($forms.length > 1) {
let formVals = []
$forms.each(function() {
let fd = new FormData($(this));
formVals.push(Object.fromEntries(fd));
})
result[slideIds[i]] = formVals;
} else {
let fd = new FormData($forms[0]);
result[slideIds[i]] = Object.fromEntries(fd);
}
}
return result;
}
NewProjectDialog.prototype.open = function() {
ui.introWindowClose();
if (!this.isInitialized) {
this.init();
}
this.reset();
this.$elm.dialog("open");
}
NewProjectDialog.prototype.close = async function() {
return new Promise((resolve, reject) => {
this.$elm.one("dialogclose", function(e, ui) {
resolve();
})
if (this.isInitialized) {
this.$elm.dialog("close");
} else {
resolve();
}
})
}
ui.newProjectDialog = new NewProjectDialog();
ui.newProjectDialog.onInits.push(function() {
var $sheetTab = this.$elm.find("[data-slideid=spreadsheet]")
$sheetTab.one("active", async ()=>{
console.log("Initializing spreadsheet new Window");
var getOptions = ()=>{
var result = {
fetchType : $sheetTab.find("input[name='spreadSheetFetchType']:checked").val(),
calcValue : $sheetTab.find("input[name='spreadSheetCalculateValue']").prop("checked"),
calcFormat : $sheetTab.find("input[name='spreadSheetCalculateFormatting']").prop("checked"),
csvExcel : $sheetTab.find("input[name='csvExcelFormat']").prop("checked")
}
var skipHeader = parseInt($sheetTab.find("input[name='skipHeader']").val());
if (skipHeader) result.skipHeader = skipHeader;
if (result.fetchType == "custom") {
var colPair = [];
$sheetTab.find(".sheetCustomOptTable tbody tr").each(function() {
var $thisRow = $(this);
colPair.push({
source: parseInt($thisRow.find(".sourceText").val()),
target: parseInt($thisRow.find(".translation").val())
})
})
result.model = {
columnPairs: colPair
}
if ($sheetTab.find("input[name='enableRowHeaderTextColumn']").prop("checked")) {
result.model.rowHeaderTextColumn = parseInt($sheetTab.find("input[name='rowHeaderTextColumn']").val())
}
}
return result;
}
$sheetTab.find('input[type=radio][name=spreadSheetFetchType]').change(function() {
$sheetTab.find(".customOptions").addClass("hidden")
if ($(this).val() == "custom") $sheetTab.find(".customOptions").removeClass("hidden")
});
var $rowTpl = $sheetTab.find(".sheetCustomOptTable tbody tr").clone(true, true);
var resetTable = () => {
var $tbody = $sheetTab.find(".sheetCustomOptTable tbody")
$tbody.empty();
$tbody.append($rowTpl.clone(true, true))
}
$rowTpl.find(".sameWithSourceColumn").on("click", function() {
$(this).closest("td").find(".translation").val($(this).closest("tr").find(".sourceText").val());
});
$rowTpl.find(".sourceText").on("input", function() {
$(this).closest("tr").find(".translation").val($(this).val());
});
$rowTpl.find(".removeRow").on("click", function() {
$(this).closest("tr").remove();
//console.log("TR length", $sheetTab.find(".sheetCustomOptTable tbody tr").length);
if ($sheetTab.find(".sheetCustomOptTable tbody tr").length == 0) resetTable();
})
$rowTpl.find(".addRow").on("click", function() {
$(this).closest("tr").after($rowTpl.clone(true, true));
})
resetTable();
var $theFld = this.$elm.find(".newSpreadsheetFiles");
$theFld.on("change", function() {
console.log("value changed!");
console.log($(this).val());
var thisPaths = $(this).val(); // if more than one file is selected than each file are separated by ";"
var paths = $(this).val().split(";");
// get game folder from the folder of the first file.
console.log(thisPaths, paths);
var gameFolder = paths[0].match(/(.*)[\/\\]/)[1]||''; // eslint-disable-line
trans.procedureCreateProject(gameFolder, {
selectedFile:thisPaths,
gameEngine:"spreadsheet",
options: getOptions()
});
});
// handling folder selector
$theFld = this.$elm.find(".newSpreadsheetDir");
console.log($theFld);
$theFld.on("change", function() {
console.log("value changed!");
console.log($(this).val());
var thisPaths = $(this).val(); // if more than one file is selected than each file are separated by ";"
var gameFolder = thisPaths;
console.log(gameFolder);
trans.procedureCreateProject(gameFolder, {
selectedFile:thisPaths,
gameEngine:"spreadsheet",
options: getOptions()
});
});
})
$sheetTab.on("active", async ()=>{
$sheetTab.find('input[type=radio][name=spreadSheetFetchType]:checked').trigger("change")
});
});
ui.textAreaTabSupport = function(fld) {
fld = $(fld);
if (fld.length < 0) return;
if (fld[0].nodeName !== 'TEXTAREA') return;
console.log("initializing tab support");
var enabled = true;
fld.keydown(function(e) {
// Escape key toggles tab on/off
if (e.keyCode==27)
{
enabled = !enabled;
return false;
}
//console.log("tab key is pressed");
if ($(".textcomplete-dropdown").is(":visible")) {
return false;
}
// Enter Key?
if (e.keyCode === 13 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// find start of the current line
var sel = this.selectionStart;
let text = $(this).val();
while (sel > 0 && text[sel-1] != '\n')
sel--;
var lineStart = sel;
while (text[sel] == ' ' || text[sel]=='\t')
sel++;
if (sel > lineStart)
{
// Insert carriage return and indented text
document.execCommand('insertText', false, "\n" + text.substr(lineStart, sel-lineStart));
// Scroll caret visible
this.blur();
this.focus();
return false;
}
}
}
// Tab key?
if(e.keyCode === 9 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// These single character operations are undoable
if (!e.shiftKey)
{
document.execCommand('insertText', false, "\t");
}
else
{
let text = this.value;
if (this.selectionStart > 0 && text[this.selectionStart-1]=='\t')
{
document.execCommand('delete');
}
}
}
else
{
// Block indent/unindent trashes undo stack.
// Select whole lines
var selStart = this.selectionStart;
var selEnd = this.selectionEnd;
var text = $(this).val();
while (selStart > 0 && text[selStart-1] != '\n')
selStart--;
while (selEnd > 0 && text[selEnd-1]!='\n' && selEnd < text.length)
selEnd++;
// Get selected text
var lines = text.substr(selStart, selEnd - selStart).split('\n');
// Insert tabs
for (var i=0; i<lines.length; i++)
{
// Don't indent last line if cursor at start of line
if (i==lines.length-1 && lines[i].length==0)
continue;
// Tab or Shift+Tab?
if (e.shiftKey)
{
if (lines[i].startsWith('\t'))
lines[i] = lines[i].substr(1);
else if (lines[i].startsWith(" "))
lines[i] = lines[i].substr(4);
}
else
lines[i] = "\t" + lines[i];
}
lines = lines.join('\n');
// Update the text area
this.value = text.substr(0, selStart) + lines + text.substr(selEnd);
this.selectionStart = selStart;
this.selectionEnd = selStart + lines.length;
}
return false;
}
enabled = true;
return true;
});
}
ui.render = function($html) {
// render portion of html
var dvField = new DVField($html);
dvField.init();
$html.find("a.externalLink, a[external]").on("click", function(e) {
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
return $html;
}
ui.startProject = async function(file) {
console.log("ui.startProject", arguments);
file = file || "";
if (!file) return false;
var gameFolder = file.match(/(.*)[\/\\]/)[1]||''; // eslint-disable-line
var checkPath = php.checkPathSync(gameFolder);
if (checkPath.accessible == false) {
return ui.pathNotAccessibleDialog();
}
ui.showBusyOverlay();
php.spawn("checkProjectExist.php", {
args:{
'gameFolder':gameFolder
},
onDone : async function(data) {
console.log(data);
ui.hideBusyOverlay();
var selType = $("#dialogNewProject [data-slideid='rpgmaker'] .detectedType").val();
var devType = $("#dialogNewProject [data-slideid='rpgmaker'] .devLocationType").val();
var detType = devType || selType; // determined type
if (detType) {
console.log("detType is:", detType);
if (typeof engines[detType].onCheckProjectExist == 'function') {
console.log("handler exist");
var halt = await engines[detType].onCheckProjectExist.apply(this, [file, detType, data]);
console.log("Is process halt?", halt);
if (common.isHalt(halt)) return;
}
}
// end of handle rmmv
if (Array.isArray(data) == false) return trans.procedureCreateProject(gameFolder, {selectedFile:file});
if (data.length <= 0) return trans.procedureCreateProject(gameFolder, {selectedFile:file});
ui.dialogProjectIsExist(data, {
'gameFolder': gameFolder
});
}
})
}
ui.alert = function(msg, targetWindow) {
if (!ui.windows[targetWindow]) return;
ui.windows[targetWindow].alert(msg);
}
ui.fileObjectTooltip = {}
ui.fileObjectTooltip.open = async function($content, $targetElm) {
console.log("ui.fileObjectTooltip.open", arguments);
var $myElm = $('#fileObjectTooltip');
if (typeof $content.on == "function") {
$content.on("mouseout", () => {
console.log("mouse leave");
ui.fileObjectTooltip.close();
})
}
if ($myElm.length < 1) {
$myElm = $('<div id="fileObjectTooltip" title=""></div>').appendTo("#template");
$myElm.attr("title", "");
$myElm.tooltip({
content:function() {
return $content;
},
tooltipClass: "fileObjTooltipWrapper",
show: {
effect: "none",
duration: 1
},
hide: {
effect: "none",
delay: 1
},
position: {
my: "left top",
at: "right+6 top-16",
of: $targetElm
},
open: function( event, ui ) {
/*
setTimeout(function(){
$myElm.tooltip("close");
}, timeout);
*/
}
});
} else {
$myElm.attr("title", "");
$myElm.tooltip("option", "content", function() {
return $content;
});
$myElm.tooltip("option", "position", {
my: "left top",
at: "right+6 top-16",
of: $targetElm
});
}
$myElm.tooltip("open");
}
ui.fileObjectTooltip.close = function() {
var $myElm = $('#fileObjectTooltip');
if ($myElm.length < 1) return;
try {
$myElm.tooltip("close");
} catch(e) {
// do nothing
}
}
/**
* Class for handling Cell Info Tab
* (Bottom left window section)
* @class
*/
ui.CellInfoTab = function(root, options) {
this.options = options || {}
this.root = root || $(".cellInfoPartsA");
this.options.eventName = this.options.eventName || "cellInfoTabChange";
this.init();
}
ui.CellInfoTab.prototype.getActiveTab = function() {
return this.activeTab ;
}
ui.CellInfoTab.prototype.select = function(tabName) {
console.log("selecting tab", tabName);
this.buttons.removeClass("active");
this.root.find(`[data-fortab="${tabName}"]`).addClass("active");
this.contents.addClass("hidden");
console.log("removing hidden for", tabName);
this.root.find(`[data-tabname="${tabName}"]`).removeClass("hidden");
this.activeTab = tabName;
$(document).trigger(this.options.eventName, tabName);
trans.grid.selectCell(trans.lastSelectedCell[0], trans.lastSelectedCell[1]);
}
ui.CellInfoTab.prototype.init = function() {
this.buttons = this.root.find('[data-fortab]');
this.contents = this.root.find('[data-tabname]');
var cellInfoTab = this;
this.buttons.not(".initialized").on("click", function() {
console.log("Tab clicked");
var tabName = $(this).attr("data-fortab");
cellInfoTab.select(tabName);
})
this.buttons.addClass("initialized")
}
// =======================================================
// AUTOCOMPLETE
// =======================================================
ui.autoCompleteSet = function(state) {
trans.project.options = trans.project.options || {};
trans.project.options.autoComplete = Boolean(state)
}
ui.autoCompleteGet = function() {
if (!trans.project.options) return false;
if (typeof trans.project.options.autoComplete == 'undefined') return true;
return Boolean(trans.project.options.autoComplete)
}
ui.autoCompleteIsEnabled = function() {
if (!trans.project.options) return false;
if (typeof trans.project.options.autoComplete == 'undefined') return true;
return Boolean(trans.project.options.autoComplete)
}
ui.autoCompleteClear = function() {
this.words = [];
}
ui.changeEditorLanguage = async function(lang) {
return new Promise((resolve, reject) => {
lang= lang||"en-US"
chrome.settingsPrivate.setPref('spellcheck.dictionaries', [lang], "null", resolve(lang));
})
}
ui.onReady(function() {
ui.dvField = new DVField();
ui.dvField.init();
})
ui.init = function() {
ui.togglePreWhitespaces(sys.config.wordWrapTable)
ui.toggleMonoSpace(sys.config.monoSpaceTable)
//ui.textAreaTabSupport($("#currentCellText"));
var RawViewer = require("www/js/RawViewer.js").RawViewer;
ui.rawViewer = new RawViewer();
/*
now loaded at trans.drawFileSelector
var TranslationByContext = require("www/js/TranslationByContext.js");
ui.translationByContext = new TranslationByContext();
*/
var negativeHeight = $(".panel-wrapper").height() + 100;
$(".cellInfoTabContent").css("height", "calc(100vh - "+negativeHeight+"px)");
if (typeof sys.getConfig("wordWrapCurrentCellPane") !== "undefined") ui.toggleWordWrapCurrentCellPane(sys.getConfig("wordWrapCurrentCellPane"));
if (typeof sys.getConfig("wordWrapRomajiPane") !== "undefined") ui.toggleWordWrapRomajiPane(sys.getConfig("wordWrapRomajiPane"));
// tooltip for cellEmblems
$(".cellEmblems > i").tooltip({
show: {
effect: "none",
delay: 0
},
hide: {
effect: "none",
delay:0
}
})
}
ui.highlightLastSelected = function() {
console.log("highlight selected");
$("#table .current").removeClass("current");
var scrolled = ui.scrollToView(trans.lastSelectedCell[0], trans.lastSelectedCell[1], function(newRow, newCol) {
$("#table .current").removeClass("current");
var targetRow = newRow-this.rowOffset();
var targetCol = newCol-this.colOffset();
console.log("target", targetRow, targetCol);
ui.selectedCell = $(".ht_master .htCore tbody tr").eq(targetRow).find("td").eq(targetCol);
ui.selectedCell.addClass("current highlight");
});
console.log("Scrolled?", scrolled);
//if (!scrolled) {
var rowOffset = trans.lastSelectedCell[0]-trans.grid.rowOffset();
var colOffset = trans.lastSelectedCell[1]-trans.grid.colOffset();
console.log("Offset", rowOffset, colOffset);
ui.selectedCell = $(".ht_master .htCore tbody tr").eq(rowOffset).find("td").eq(colOffset);
ui.selectedCell.addClass("current highlight");
var overlay;
overlay = $(".ht_clone_left .htCore tbody tr").eq(rowOffset).find("td").eq(colOffset);
overlay.addClass("current highlight");
//}
}
ui.selectNextRow = function(natural) {
if (natural) {
var selected = trans.grid.getSelected() || [[]]
var row = selected[0][0] || 0
var col = selected[0][1] || 0
console.log("Select next:", row, col);
if (row < trans.grid.getData().length) {
trans.grid.selection.setRangeStart({col:col, row:row+1})
return true;
}
} else {
trans.doAfterSelection(trans.lastSelectedCell[0]+1,trans.lastSelectedCell[1]);
ui.highlightLastSelected();
}
}
ui.currentCellTextFocus = async function() {
$("#currentCellText").val(trans.data[trans.lastSelectedCell[0]][trans.lastSelectedCell[1]]);
if (ui.autoCompleteIsEnabled()) {
if (typeof trans[trans.gameEngine] !=='undefined') trans[trans.gameEngine].setAutocompleteData();
}
$("#currentCellText").focus();
}
ui.openScriptEditor = async function(id, options={}) {
id ||= "scriptEditor";
options ||= {};
options.id ||= id;
options.script ||= ""; // script to be edited
options.file ||= ""; // file. script and file can not be exist in the same time
options.readOnly ||= false;
options.language ||= "javascript"
if (options.script && options.file) throw new Error("script and file can not be exist in the same time");
var {showModalDialog} = require("www/js/modalDialog.js");
await showModalDialog("www/scriptEditor.html", options, {id:id, width:800, height:600});
console.log("script editor closed");
}
ui.openAutomationEditor = async function(id, options) {
id = id || "codeEditor_common";
options = options || {};
options.id = options.id || id;
options.workspaceType = "automation";
var {showModalDialog} = require("www/js/modalDialog.js");
await showModalDialog("www/automationEditor.html", options, {id:id, width:800, height:600});
console.log("script editor closed");
}
ui.openJSONForm = async function(id, options) {
id = id || "jsonform";
options = options || {};
options.id = options.id || id;
options.workspaceType = "automation";
var {showModalDialog} = require("www/js/modalDialog.js");
await showModalDialog("www/jsonform.html", options, {id:id, width:800, height:600});
console.log("script editor closed");
}
ui.openFormBuilder = async function(id, options) {
id = id || "formBuilder";
options = options || {};
options.id = options.id || id;
options.workspaceType = "automation";
var {showModalDialog} = require("www/js/modalDialog.js");
await showModalDialog("www/formbuilder.html", options, {id:id, width:800, height:600});
console.log("script editor closed");
}
ui.openFormWindow = async function(schema, def={}, id="", options={}) {
if (!schema) return;
if (!schema.components?.length) return;
id = id || "formWindow";
options = options || {};
options.id = options.id || id;
options.workspaceType = "automation";
await common.localStorage.set("formIOLastSchema", schema)
await common.localStorage.set("formIOLastValue", def);
var {showModalDialog} = require("www/js/modalDialog.js");
await showModalDialog("www/form.html", options, {id:id, width:480, height:520});
console.log("script editor closed");
return await common.localStorage.get("formIOLastValue");
}
/**
* Open a modal and blocking save as dialog
* @since 4.3.16
* @async
* @param {String} filePath - Default path of the file
* @returns {Promise<string>} - Path of the file. Empty when canceled
*/
ui.saveAs = async function(filePath="") {
console.log("UI saveas");
if (!filePath) {
console.log("setting default path", filePath)
if (trans.project.loc) {
var baseName = trans.project.gameTitle || "translation"
filePath = nwPath.join(trans.project.loc, common.filterFilename(baseName+".trans"))
console.log("suggested filePath:", filePath);
}
}
filePath = common.changeExtension(filePath, "trans");
return new Promise((resolve, reject) => {
var $elm = $(`<input type="file" id="saveAs" class="saveAs hidden" nwsaveas="translation.trans" accept=".trans,application/trans" autocomplete="off" />`)
console.log("Default path is:", filePath);
if (filePath) {
$elm.attr("nwsaveas", nwPath.basename(filePath));
$elm.attr("nwworkingdir", nwPath.dirname(filePath));
}
$elm.on("input", function(e) {
console.log("Input received");
$(window).off("focus.saveAs");
resolve($(this).val());
});
$(window).one("focus.saveAs", async function(e) {
console.log("elm length:", $elm.length);
await common.wait(3000);
if (!$elm.val()) {
console.log("Field canceled");
resolve("");
}
});
$elm.click();
});
}
/**
* Open a modal and blocking save as dialog
* @since 5.1.6
* @async
* @param {String} filePath - Default path of the file
* @returns {Promise<string>} - Path of the file. Empty when canceled
*/
ui.saveAsTPP = async function(filePath) {
console.log("UI saveas TPP");
if (filePath) {
filePath = common.changeExtension(filePath, "tpp");
}
return new Promise((resolve, reject) => {
var $elm = $(`<input type="file" class="saveAs hidden" nwsaveas="project.tpp" accept=".tpp,application/tpp" autocomplete="off" />`)
console.log("Default path is:", filePath);
if (filePath) {
$elm.attr("nwsaveas", nwPath.basename(filePath));
$elm.attr("nwworkingdir", nwPath.dirname(filePath));
}
$elm.on("input", function(e) {
console.log("Input received");
$(window).off("focus.saveAs");
resolve($(this).val());
});
$(window).one("focus.saveAsTPP", async function(e) {
console.log("elm length:", $elm.length);
await common.wait(3000);
if (!$elm.val()) {
console.log("Field canceled");
resolve("");
}
});
$elm.click();
});
}
ui.deleteFiles = function() {
if (trans.getCheckedFiles().length < 1) return;
var conf = confirm(t("Remove selected objects?"));
if (!conf) return;
trans.one("afterDeleteFile", async (e, files) => {
var conf = confirm(t("Do you wish to remove related staging files too?\nWarning: This is can not be undone!"))
console.log("Files removed", files);
if (!conf) return;
trans.stagingFilesRemove(files);
})
trans.deleteFile(trans.getCheckedFiles());
}
ui.animateCSS = ($element, animation, prefix = '') =>
// We create a Promise and return it
new Promise((resolve, reject) => {
const animationName = `${prefix}${animation}`;
const node = $($element)[0];
node.classList.add(`${prefix}animated`, animationName);
// When the animation ends, we clean the classes and resolve the Promise
function handleAnimationEnd(event) {
event.stopPropagation();
node.classList.remove(`${prefix}animated`, animationName);
resolve('Animation ended');
}
node.addEventListener('animationend', handleAnimationEnd, {once: true});
});
$(document).ready(function() {
console.log("%c UI loaded", "color:yellow");
if ($('body').is('[data-window="trans"]') == false) return;
// ==============================================================
//
// E V E N T S
//
// ==============================================================
ui.disableButtons();
ui.on("optionsWindowClosed", function() {
console.log("optionsWindowClosed triggered");
sys.saveConfig();
});
ui.setWindowTitle();
ui.ribbonMenu.init();
// ==============================================================
// B U T T O N S
// ==============================================================
$("#button-translatorplus").on("click", function() {
ui.mainMenu.open();
});
// ==================================================
// MAIN MENU
// ==================================================
$(".button-save").on("click", function(e) {
trans.save();
});
$(".button-save-as").on("click", async function(e) {
trans.saveAs();
});
$(".button-save-as-side").on("click", function(ev) {
ev.preventDefault();
// Popup the native context menu at place you click
console.log(ev.originalEvent);
var $wrapper = $(this).closest(".buttonGroup");
var left = Math.round($wrapper.offset().left);
var top = Math.round($wrapper.offset().top + $wrapper.outerHeight());
console.log(left, top)
//ui.menus.saveAs.popup(parseInt(ev.originalEvent.x), parseInt(ev.originalEvent.y));
ui.menus.saveAs.popup(left, top);
return false;
});
$(".button-open").on("click", function(e) {
$("#openFile").trigger("click");
});
$(".button-new").on("click", function(e) {
//var accept = confirm("Creating new project will close current project.\nAll unsaved data will be lost\n\nAre you sure?");
//if (accept) {
//$("#startProject").trigger("click");
//}
ui.newProjectDialog.open()
});
// RPG Maker's new project's slide
$("#dialogNewProject [data-slideid=rpgmaker]").on("active", async function(e) {
console.log("initializing slide");
var $this = $(this);
$this.find(".rpgMakerLocation").val("");
$this.find(".devLocation").val("");
$this.find(".devLocationWrapper").addClass("hidden");
$this.find(".detectedTypeWrapper").addClass("hidden");
$this.find(".devLocationTypeWrapper").addClass("hidden");
$this.find(".devLocationExeWrapper").addClass("hidden");
// initializing create a copy
$this.find(".createCopyWrapper").addClass("hidden");
$this.find(".createCopy").prop("checked", false);
$this.find(".createCopy").prop("disabled", false);
$this.find(".copyIsRequired").addClass("hidden");
$this.find(".detectedType").val("");
$this.find(".devLocationType").val("");
$this.find(".devLocationExe").val("");
$this.find(".devLocationWrapper").removeClass("mandatory");
$this.find(".createProjectFromRPGM").prop("disabled", true);
});
$("#dialogNewProject .rpgMakerLocation").on("change", async function(e) {
var loc = $(this).val();
var $slide = $("#dialogNewProject [data-slideid=rpgmaker]");
console.log("analyzing path : ", loc);
var projectType = await Engines.detect(loc);
$slide.find(".detectedTypeWrapper").removeClass("hidden");
// create a copy
$slide.find(".createCopyWrapper").removeClass("hidden");
$slide.find(".detectedType").val(projectType);
$slide.find(".devLocation").val("");
if (!projectType) return alert(t("Error!\r\nTranslator++ is unable to detect the type of ")+loc);
if (projectType == "enigma") {
console.log("Is Enigma");
// create a copy is mandatory
$slide.find(".createCopy").prop("checked", true);
$slide.find(".createCopy").prop("disabled", true);
$slide.find(".copyIsRequired").removeClass("hidden");
$slide.find(".devLocationWrapper").addClass("mandatory");
$slide.find(".createCopy").trigger("change");
return;
} else if (["rmvxace", "rmvx", "rmxp"].includes(projectType)) {
if (thirdParty.isInstalled("rpgmakertrans") == false) {
var conf = confirm(t(`Required application to parse ${projectType} is not installed.\nPlease install it through Third party application installer.\nDo you want to open Third Party Application Installer window?`));
if (conf) {
thirdParty.check({
popup:true,
force:true
});
}
return;
}
console.log("RPG Maker - RSS Variant");
ui._thisGame = new window.RMRGSS(loc);
if (await ui._thisGame.isPacked()) {
// create a copy is mandatory
$slide.find(".createCopy").prop("checked", true);
$slide.find(".createCopy").prop("disabled", true);
$slide.find(".copyIsRequired").removeClass("hidden");
$slide.find(".devLocationWrapper").addClass("mandatory");
$slide.find(".createCopy").trigger("change");
return;
}
}
// not enigma
$slide.find(".createProjectFromRPGM").prop("disabled", false);
});
$("#dialogNewProject .createCopy").on("change", async function(e) {
var $slide = $("#dialogNewProject [data-slideid=rpgmaker]");
if ($(this).prop("checked")) {
$slide.find(".devLocationWrapper").removeClass("hidden");
} else {
$slide.find(".devLocationWrapper").addClass("hidden");
}
})
$("#dialogNewProject .devLocation").on("change", async function(e) {
var to = $(this).val();
var from = $("#dialogNewProject .rpgMakerLocation").val();
var $slide = $("#dialogNewProject [data-slideid=rpgmaker]");
var detectedType = $slide.find(".detectedType").val().toLowerCase()
if (detectedType == "enigma") {
let conf = confirm(t("The game is packed with Enigma.\r\nDo you want to extract the package?\r\nThis will take minutes, depend on the size of your game."))
if (!conf) {
$(this).val("");
return
}
ui.showBusyOverlay();
await php.extractEnigma(from, to);
let thisEngine = await Engines.detect(to);
let executable;
if (thisEngine == "rmmz") {
executable = await window.RMMZ.getExe(nwPath.join(to));
} else { // rmmv
executable = await window.RMMV.getExe(nwPath.join(to));
}
$slide.find(".devLocationTypeWrapper").removeClass("hidden");
$slide.find(".devLocationType").val(thisEngine);
$slide.find(".devLocationExeWrapper").removeClass("hidden");
$slide.find(".devLocationExe").val(nwPath.join(to, executable));
ui.hideBusyOverlay();
} else if (["rmvxace", "rmvx", "rmxp"].includes(detectedType)) {
if (thirdParty.isInstalled("rpgmakertrans") == false) {
let conf = confirm(t(`Required application to parse ${detectedType} is not installed.\nPlease install it through Third party application installer.\nDo you want to open Third Party Application Installer window?`));
if (conf) {
thirdParty.check({
popup:true,
force:true
});
}
return;
}
let conf = confirm(t("Copy & extract data into ")+to+" ?")
if (!conf) {
$(this).val("");
return
}
ui.showBusyOverlay();
ui._thisGame = ui._thisGame || new window.RMRGSS(from);
let thisEngine = $slide.find(".detectedType").val();
let devExecutable = nwPath.join(to, nwPath.basename(from));
await ui._thisGame.extractTo(to);
$slide.find(".devLocationTypeWrapper").removeClass("hidden");
$slide.find(".devLocationType").val(thisEngine);
$slide.find(".devLocationExeWrapper").removeClass("hidden");
$slide.find(".devLocationExe").val(devExecutable);
ui.hideBusyOverlay();
}
$slide.find(".createProjectFromRPGM").prop("disabled", false)
});
$("#dialogNewProject .createProjectFromRPGM").on("click", async function(e) {
if ($(this).prop("disabled")) return;
var master = $("#dialogNewProject .rpgMakerLocation").val();
var devExe = $("#dialogNewProject .devLocationExe").val();
var loc = devExe || master;
console.log("processing location : ", loc);
await ui.startProject(loc);
});
$(".selectRPGExe").on("click", function(e) {
//var accept = confirm("Creating new project will close current project.\nAll unsaved data will be lost\n\nAre you sure?");
//if (accept) {
$("#startProject").trigger("click");
//}
//ui.newProjectDialog.open()
});
$(".openFile").on("change", function(e) {
//trans.currentFile = $(this).val();
trans.open($(this).val());
console.log($(this).val());
});
/*
$(".saveAs").on("change", function(e) {
trans.currentFile = $(this).val();
trans.save();
console.log($(this).val());
});
*/
$("#startProject").on("click", function() {
$(this).val("");
});
$("#startProject").on("change", async function() {
if ($(this).val() == "") return false;
if (typeof $(this).val() == "undefined") return false;
await ui.startProject($(this).val());
});
$("#export").on("click", function(e) {
$(this).val("");
})
$("#exportDir").on("click", function(e) {
$(this).val("");
})
/**
$("#exportTpp").on("click", function(e) {
$(this).val("");
})
**/
$("#exportTrans").on("click", function(e) {
$(this).val("");
})
$("#exportCSV").on("click", function(e) {
$(this).val("");
})
$("#exportXLS").on("click", function(e) {
$(this).val("");
})
$("#exportXLSX").on("click", function(e) {
$(this).val("");
})
$("#exportHTML").on("click", function(e) {
$(this).val("");
})
$("#exportODS").on("click", function(e) {
$(this).val("");
})
$("#export").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {
useTagSelection:true,
wordWrapOption:true,
onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"zip",
onDone: function() {
ui.closeExportDialog();
},
'options':options
});
}
})
});
$("#exportDir").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {
useTagSelection:true,
wordWrapOption:true,
onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"dir",
onDone: function() {
ui.closeExportDialog();
},
'options':options
});
}})
});
/**
$("#exportTpp").on("change", function(e) {
if ($(this).val() == "") return false;
trans.exportTPP($(this).val(), {
onDone: function() {
ui.closeExportDialog();
}
});
});
*/
$("#exportTrans").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"RPGMakerTrans",
onDone: function() {
ui.closeExportDialog();
},
'options':options
});
}})
})
$("#exportCSV").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"csv",
onDone: function() {
ui.closeExportDialog();
},
options:options
});
},
sheetOption:true
})
})
$("#exportXLSX").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"xlsx",
onDone: function() {
ui.closeExportDialog();
},
options:options
});
},
sheetOption:true
})
})
$("#exportXLS").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"xls",
onDone: function() {
ui.closeExportDialog();
},
options:options
});
},
sheetOption:true
})
})
$("#exportHTML").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"html",
onDone: function() {
ui.closeExportDialog();
},
options:options
});
},
sheetOption:true
})
})
$("#exportODS").on("change", function(e) {
if ($(this).val() == "") return false;
var currentValue = $(this).val();
ui.exportPreparationDialog(currentValue, {onDone:function(options) {
// ver 3 change
options = options || {};
var optionData = $("#dialogExport").data("options");
if (typeof optionData == "object") options.files = options.files || optionData.files;
// end of ver 3 change
trans.export(currentValue, {
mode:"ods",
onDone: function() {
ui.closeExportDialog();
},
options:options
});
},
sheetOption:true
})
})
$(".button-export").on("click", function() {
ui.openExportDialog({files:[]});
})
$(".button-import").on("click", function() {
ui.openImportDialog();
})
$(".button-inject").on("click", function() {
ui.openInjectDialog({ignoreSelection: true});
})
$("#importTpp").on("click", function() {
$(this).val("");
})
$("#importTpp").on("input", function() {
console.log("importing TPP file : "+$(this).val());
trans.importTpp($(this).val());
})
$("#importTrans").on("click", function() {
$(this).val("");
})
$("#importTrans").on("input", function() {
//var conf = confirm("Do you want to import : \n"+$(this).val());
ui.openImportTrans($(this).val());
})
$(".menu-button.batch-translate").on("click", function() {
ui.translateAllDialog();
});
$(".menu-button.contextTool").on("click", function() {
ui.showBusyOverlay();
setTimeout(function() {
ui.contextToolDialog();
}, 250);
});
$(".menu-button.executeScript").on("click", function() {
var options = {
workspace: "global"
}
ui.openAutomationEditor("codeEditor_global", options);
})
$(".menu-button.toggle-activeCellInfo").on("click", function() {
ui.toggleActiveCellInfo()
});
$(".button-clipboard").on("click", function() {
$(this).toggleClass("checked");
sys.toggleAutoClipboard($(this).hasClass("checked"));
});
$(".button-options").on("click", function() {
//$(this).toggleClass("checked");
ui.openOptionsWindow();
});
$(".button-properties").on("click", function() {
ui.openProjectProperties();
});
$(".button-help").on("click", function() {
nw.Shell.openExternal('http://dreamsavior.net/docs/translator/');
});
$("#dialogImport .importSpreadsheet").on("click", function() {
ui.openImportSpreadsheetDialog();
});
$("#dialogImport .importRPGMTrans").on("click", function() {
ui.openImportRPGMTransDialog();
});
// File selection panel bottom bar
$(".bottomToolbar .controlCheck").on("click", function() {
console.log("clicking 3 state checkbox");
var state = $(this).data("state")||0;
if (Boolean(state) == false) { //default
ui.fileSelectorState = [];
var $fileSelector = $(".fileList .data-selector .fileCheckbox:checked");
for (var i=0; i<$fileSelector.length; i++) {
ui.fileSelectorState.push($fileSelector.eq(i).attr("value"));
}
}
state++;
if (state > 2) state=0;
$(this).data("state", state);
console.log(state);
var stateClass = ["ovDefault", "ovCheck", "ovNoCheck"];
$(this).find(".ovLine").removeClass("ovNoCheck");
$(this).find(".ovLine").removeClass("ovCheck");
$(this).find(".ovLine").removeClass("ovDefault");
console.log(stateClass[state]);
$(this).find(".ovLine").addClass(stateClass[state]);
$(this).find(".ovLine").removeClass("icon-check-empty");
$(this).find(".ovLine").removeClass("icon-check");
$(this).find(".ovLine").removeClass("icon-minus-squared-alt");
if (stateClass[state] == "ovCheck") {
$(this).find(".ovLine").addClass("icon-check");
} else if (stateClass[state] == "ovNoCheck") {
$(this).find(".ovLine").addClass("icon-check-empty");
} else {
$(this).find(".ovLine").addClass("icon-minus-squared-alt");
}
if (stateClass[state] == 'ovCheck') {
let $fileSelector = $(".fileList .data-selector .fileCheckbox");
$fileSelector.prop("checked", true);
} else if (stateClass[state] == 'ovNoCheck') {
let $fileSelector = $(".fileList .data-selector .fileCheckbox");
$fileSelector.prop("checked", false);
} else if (stateClass[state] == 'ovDefault') {
let $fileSelector = $(".fileList .data-selector .fileCheckbox");
$fileSelector.prop("checked", false);
for (let i=0; i<$fileSelector.length; i++) {
if (ui.fileSelectorState.includes($fileSelector.eq(i).attr("value"))) {
$fileSelector.eq(i).prop("checked", true);
}
}
}
$(".data-selector input[type=checkbox]").trigger("change");
});
$(".bottomToolbar .invertSelection").on("click", function() {
trans.invertSelection();
});
$(".bottomToolbar .removeSelected").on("click", function() {
ui.deleteFiles();
});
$(".bottomToolbar .addObject").on("click", function() {
ui.addNewObjectDialog();
});
$(".resizeFont").on("click", function(e) {
ui.openTextResizer($(this), $($(this).attr("data-for")));
});
$(".gotoCurrentCell").on("click", function(e) {
if (empty(trans.lastSelectedCell)) return;
trans.grid.scrollViewportTo(trans.lastSelectedCell[0],trans.lastSelectedCell[1]);
})
$(".menu-button.addNewKey").on("click", function(e) {
trans.goToNewKey();
});
$(".menu-button.filePropertiesMenu").on("click", function(e) {
ui.openFileProperties(trans.getSelectedId());
});
$(".menu-button.importHere").on("click", function(e) {
if (Boolean(trans.getSelectedId()) == false) return;
ui.openFileDialog({
accept:".trans",
onSelect : function(path) {
ui.openImportTrans(path, {
mode:1,
defaultSelection:[trans.getSelectedId()]
})
}
})
});
$(".menu-button.addNote").on("click", function(e) {
if ($(this).hasClass("checked")) {
ui.closeFileNote();
} else {
ui.openFileNote();
}
});
$(".menu-button > .find").on("click", function(e){
ui.openSearchWindow();
});
$(".menu-button > .button-find.menuSide").on("click", function(ev) {
ev.preventDefault();
ui.openSearchMenu();
});
$(".menu-button > .button-gridInfo.gridInfo").on("click", function(ev) {
ev.preventDefault();
ui.toggleGridInfo();
});
$(".menu-button > .button-gridInfo.menuSide").on("click", function(ev) {
ev.preventDefault();
ui.openGridInfoMenu();
});
$(".menu-button.wordWrapTable").on("click", function(e){
ui.togglePreWhitespaces();
});
$(".menu-button.monospace").on("click", function(e){
ui.toggleMonoSpace();
});
$(".menu-button.removeTranslation").on("click", function(e) {
var conf= confirm(t("Are you realy sure want to delete all translation on current page?\nWarning: this is irreversible action!"));
if (conf) {
trans.removeAllTranslation(trans.getSelectedId(), {refreshGrid:true});
}
});
$(".menu-button.removeFile").on("click", function(e) {
var conf= confirm(t("Are you realy sure want to delete current file?\nWarning: this is irreversible action!"));
if (conf) {
trans.deleteFile(trans.getSelectedId());
}
});
$(".panelLeftTabHandler").on("click", function() {
ui.resize.toggleCollapse();
});
/* LEFT PANE */
$("#currentCoordinate").on("change", function() {
console.log("selecting cell : ", $(this).val());
var $this = $(this);
var value = $this.val();
var coord = value.split(",");
var row = parseInt(coord[0]-1);
var col = parseInt(coord[1]-1);
if (trans.selectCell(row, col) == false) {
// do nothing
}
});
$(".panel-left .panel-switcher").on("click", function(e) {
ui.switchLeftPane($(this).attr("data-for"));
});
$(".menu-button.undockPane").on("click", function(e) {
ui.toggleDockTranslatorPane();
});
$(".menu-button.connectTranslator").on("click", function(e) {
if ($(this).hasClass("checked")) {
$(this).removeClass("checked");
trans.config.autoTranslate = false;
$(this).find("img").attr("src", "img/connect_icon.png");
$(this).find("span").text("Connect");
} else {
$(this).addClass("checked");
trans.config.autoTranslate = true;
$(this).find("img").attr("src", "img/connected_icon.png");
$(this).find("span").text("Connected");
}
});
$(".currentCellTextCtrl .wordWrap").on("click", function() {
$(this).toggleClass("checked");
ui.toggleWordWrapCurrentCellPane($(this).hasClass("checked"));
});
$(".cellInfoCtrl .wordWrap").on("click", function() {
$(this).toggleClass("checked");
ui.toggleWordWrapRomajiPane($(this).hasClass("checked"));
});
$(".ceOptions").on("click", function() {
ui.currentCellTextOptionsOpen();
})
$(".speakOriginalText").on("click", function() {
window.synth.speakOriginal();
})
$(".copyOriginal").on("click", function() {
var thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][0]) document.querySelector("#currentCellText").insertAtCaret(trans.data[thisRow][0]);
$("#currentCellText").trigger("change")
})
$(".speakTranslatedText").on("click", function() {
window.synth.speakTranslated();
})
$(".speakCurrent").on("click", function() {
window.synth.speakCurrent();
})
$(".contextTranslateHelp").on("click", function() {
nw.Shell.openExternal('https://dreamsavior.net/docs/translator/getting-started/translation-by-context/');
})
$("#introWindow .closeIntroWindow").on("click", function() {
ui.introWindowClose();
})
$("#introWindow .newProject").on("click", function() {
//$("#startProject").trigger("click");
//ui.introWindowClose();
ui.newProjectDialog.open();
});
$("#introWindow .openProject").on("click", function() {
$("#openFile").trigger("click");
ui.introWindowClose();
});
$("#introWindow .nextTips").on("click", function() {
ui.showRandomTip();
});
$(".pathinfoWrapper > i").on("click", function() {
$(".data-selector.selected")[0].scrollIntoView({
behavior: "smooth",
block:"center"
})
})
$(".actionCreateNewTrans").on("click", function() {
var gameEngine = $("input.gameEngines").val();
var gameTitle = $("input.gameTitle").val();
if (gameTitle == "") return alert(t("Please enter the title"));
var transData = {
project : {
gameEngine : gameEngine,
gameTitle : gameTitle
}
}
trans.openFromTransObj(transData, {
isNew:true,
onSuccess : () => {
ui.newProjectDialog.close();
}
});
})
$("#mainMenu .checkThirdParty").on("click", function() {
thirdParty.check({
popup:true,
force:true
})
})
$(document).on("windowResizeStop", function() {
var maxHeight = $(window).height()-120;
$(".panel-wrapper").resizable( "option", "maxHeight", maxHeight );
var negativeHeight = $(".panel-wrapper.ui-resizable").height() + 100;
$(".cellInfoTabContent").css("height", "calc(100vh - "+negativeHeight+"px)");
ui.fixCellInfoSize();
});
// ==============================================================
// TABLE
// ==============================================================
$("#currentCellText").on("change", function(e){
console.log("text editor changed");
if ($(this).data("column") == 0) {
if (trans.isLastRow($(this).data("row")) == false) return false;
}
if (typeof $(this).data("row") == 'undefined') return false;
trans.grid.setDataAtCell($(this).data("row"),$(this).data("column"),$(this).val());
})
$("#currentCellText").on("focus", function(e) {
if (typeof trans.lastSelectedCell == 'undefined') return false;
// starting from 3.7.14
//$("#table .currentCell").removeClass("currentCell");
//$("#table .current.highlight").addClass("currentCell");
/*
$("#table .currentCell").removeClass("currentCell");
var scrolled = ui.scrollToView(trans.lastSelectedCell[0], trans.lastSelectedCell[1], function(newRow, newCol) {
var targetRow = newRow-this.rowOffset();
var targetCol = newCol-this.colOffset();
console.log("target", targetRow, targetCol);
ui.selectedCell = $(".ht_master .htCore tbody tr").eq(targetRow).find("td").eq(targetCol);
ui.selectedCell.addClass("currentCell");
});
if (!scrolled) {
var rowOffset = trans.lastSelectedCell[0]-trans.grid.rowOffset();
var colOffset = trans.lastSelectedCell[1]-trans.grid.colOffset();
console.log("Offset", rowOffset, colOffset);
ui.selectedCell = $(".ht_master .htCore tbody tr").eq(rowOffset).find("td").eq(colOffset);
ui.selectedCell.addClass("currentCell");
var overlay;
overlay = $(".ht_clone_left .htCore tbody tr").eq(rowOffset).find("td").eq(colOffset);
overlay.addClass("currentCell");
}
*/
// adding common autocomplete by same cols
if (ui.autoCompleteIsEnabled()) {
ui.words ||= [];
if (typeof trans[trans.gameEngine] !=='undefined') trans[trans.gameEngine].setAutocompleteData();
for (var i=0; i< trans.data[trans.lastSelectedCell[0]].length; i++) {
var thisCell = trans.data[trans.lastSelectedCell[0]][i]||"";
if (typeof thisCell !== "string") continue;
thisCell = thisCell.replace(/[.,]/g, "");
var newAutoCorrect = thisCell.split(" ");
for (var x=0; x<newAutoCorrect.length; x++) {
if (newAutoCorrect[x].length < 3) continue;
if (ui.words.includes(newAutoCorrect[x])) continue;
ui.words.push(newAutoCorrect[x]);
}
}
}
});
$("#currentCellText").on("blur", function(e) {
console.log("currentCellTextBlur");
//$(".ht_master .htCore tbody tr .currentCell").removeClass("currentCell");
$("#table tbody tr .current").removeClass("current highlight");
//trans.grid.selectCell(trans.lastSelectedCell[0], trans.lastSelectedCell[1])
});
// ==============================================================
// HANDLING DROP EVENTS
// ==============================================================
// // prevent default behavior from changing page on dropped file
// window.ondragover = function(e) { e.preventDefault(); return false };
// // NOTE: ondrop events WILL NOT WORK if you do not "preventDefault" in the ondragover event!!
// window.ondrop = function(e) { e.preventDefault(); return false };
// const holder = $("body")[0];
// holder.ondragover = function () { this.className = 'hover'; return false; };
// holder.ondragleave = function () { this.className = ''; return false; };
// holder.ondrop = function (e) {
// e.preventDefault();
// console.log("drop");
// for (let i = 0; i < e.dataTransfer.files.length; ++i) {
// console.log(e.dataTransfer.files[i].path);
// if (trans.isFileSupported(e.dataTransfer.files[i].path)) {
// console.log("file is supported !");
// trans.openFile(e.dataTransfer.files[i].path);
// } else {
// console.log("file is not supported !");
// }
// }
// return false;
// };
const dropFileToMainWindow = new (require("www/js/DropFileToWindow.js"))($("#mainArea"), {
hoverText: "Drop .trans, .tpp, .json file here!",
supportedFiles: [".trans", ".tpp", ".json"],
onSupportedFileDrop: (filePath)=> {
trans.openFile(filePath);
}
});
dropFileToMainWindow.init();
const dropFileToIntroWindow = new (require("www/js/DropFileToWindow.js"))($("#introWindow"), {
hoverText: "Drop .trans, .tpp, .json file here!",
supportedFiles: [".trans", ".tpp", ".json"],
onSupportedFileDrop: (filePath)=> {
trans.openFile(filePath);
}
});
dropFileToIntroWindow.init()
// ==============================================================
// HANDLING KEYBOARD SHORTCUTS
// ==============================================================
// Disable midle click from opening new application window
document.addEventListener("auxclick", function(e){
if (e.button === 1) {
// Check if it is a link (a) element; if so, prevent the execution.
if (e.target.tagName.toLowerCase() === "a") {
console.log("middle click on A element");
e.preventDefault();
}
}
});
$(document).on('keydown', function(e) {
var keyCode = e.keyCode || e.which;
switch (keyCode) {
case 112 : //F1, about
e.preventDefault();
console.log("opening help command");
nw.Shell.openExternal('http://dreamsavior.net/docs/translator/');
break;
case 27 : //esc, close active windows
e.preventDefault();
ui.introWindowClose();
break;
case 122 : //F11, Full screen
var win = win || nw.Window.get();
win.maximize();
break;
}
// EDITING COMMAND
if (e.ctrlKey && e.shiftKey ) {
switch(keyCode) {
case 67 : //SHIFT+c
e.preventDefault();
console.log("Pressing CTRL+shift+c");
var text = trans.getSelectedTextsAsOneLine();
var clipboard = nw.Clipboard.get();
clipboard.set(text);
break;
case 71 : //SHIFT+g
e.preventDefault();
console.log("Pressing CTRL+shift+g");
trans.translateSelectionAsOneLine();
break;
}
} else if (e.ctrlKey) {
switch(keyCode) {
case 79 : //o
e.preventDefault();
console.log("Pressing CTRL+o");
trans.open();
break;
case 83 : //s
e.preventDefault();
console.log("Pressing CTRL+s");
trans.save();
//saveData();
break;
case 70 : //f
e.preventDefault();
(async () => {
//await common.wait(200);
console.log("Pressing CTRL+f");
ui.openSearchWindow();
})();
break;
case 71 : //g
e.preventDefault();
console.log("Pressing CTRL+g");
trans.translateSelection();
//trans.translateSelectionByLine();
break;
case 72 : //h
e.preventDefault();
console.log("Pressing CTRL+h");
ui.openSearchWindow("replace");
break;
case 68 : //d
e.preventDefault();
console.log("Pressing CTRL+d");
trans.appendTextToReference(common.getSelectionText());
break;
case 76 : //l
e.preventDefault();
trans.translateAllBySelectedCells();
break;
case 84 : //t
e.preventDefault();
ui.taggingDialog(trans.grid.getSelectedRange());
break;
}
} else if (e.altKey) {
switch(keyCode) {
case 46 : //alt delete (remove context translation)
e.preventDefault();
$(document).trigger("clearContextTranslationByRow", {file:trans.getSelectedId(), row:trans.grid.getSelectedRange(), type:"range"});
break;
}
} else if (e.shiftKey) {
switch(keyCode) {
case 46 : //shift delete (remove selected row)
e.preventDefault();
var conf = confirm(t("Do you want to remove the currently selected row(s)?"));
if (!conf) return;
trans.removeRow(trans.getSelectedId(), common.gridSelectedRows());
trans.grid.render();
trans.grid.deselectCell();
break;
}
}
});
// ==================================================
// numpad enter everywhere on screen
window.onkeydown=function(ev) {
var e= ev || window.event;
var key = e.keyCode
if ((key===13) && (e.location===3)) {
e.preventDefault();
// go to next row
if (typeof trans.lastSelectedCell == 'undefined') return false;
var editorHasFocus = false;
if ($("#currentCellText").is(":focus")) {
$("#currentCellText").trigger("blur");
editorHasFocus = true;
trans.grid.addHookOnce('afterSelectionEnd', function() {
ui.currentCellTextFocus()
})
}
ui.selectNextRow(true);
if (editorHasFocus) {
ui.currentCellTextFocus()
}
} else if (key == 27) {
trans.grid.deselectCell()
} else if (key == 40 && e.altKey) {
console.log("alt down pressed");
e.preventDefault();
trans.goToNextUntranslated();
} else if (key == 38 && e.altKey) {
console.log("alt up pressed");
e.preventDefault();
trans.goToPreviousUntranslated();
}
}
$("#currentCellText").on('input', function(e) {
var $that = $(this);
ui._cache = ui._cache || {};
ui._cache.lastCellLineNumber = ui._cache.lastCellLineNumber || 0;
if (ui._cache.bgNumberProcessing) {
clearTimeout(ui._cache.bgNumberProcessing);
ui._cache.bgNumberProcessing = setTimeout(function() {
var currentLineNumber = $that.val().split("\n").length;
if (ui._cache.lastCellLineNumber !== currentLineNumber) {
ui._cache.lastCellLineNumber = currentLineNumber;
ui.generateBackgroundNumber($that, currentLineNumber);
}
//console.log("input delayer triggered");
ui._cache.bgNumberProcessing = undefined;
}, 200);
return;
}
ui._cache.bgNumberProcessing = setTimeout(function() {
var currentLineNumber = $that.val().split("\n").length;
if (ui._cache.lastCellLineNumber !== currentLineNumber) {
ui._cache.lastCellLineNumber = currentLineNumber;
ui.generateBackgroundNumber($that, currentLineNumber);
}
//console.log("input delayer triggered");
ui._cache.bgNumberProcessing = undefined;
}, 200);
});
$("#currentCellText").on('keydown', function(e) {
var keyCode = e.keyCode || e.which;
// EDITING COMMAND
if (e.ctrlKey) {
var thisRow;
switch(keyCode) {
case 48 : //0
e.preventDefault();
console.log("Pressing CTRL+0");
//var thisRow = $("#currentCellText").data("row");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][0]) document.activeElement.insertAtCaret(trans.data[thisRow][0]);
$("#currentCellText").trigger("change")
break;
case 49 : //1
e.preventDefault();
console.log("Pressing CTRL+1");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][1]) document.activeElement.insertAtCaret(trans.data[thisRow][1]);
$("#currentCellText").trigger("change")
break;
case 50 : //2
e.preventDefault();
console.log("Pressing CTRL+2");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][2]) document.activeElement.insertAtCaret(trans.data[thisRow][2]);
$("#currentCellText").trigger("change")
break;
case 51 : //3
e.preventDefault();
console.log("Pressing CTRL+3");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][3]) document.activeElement.insertAtCaret(trans.data[thisRow][3]);
$("#currentCellText").trigger("change")
break;
case 52 : //4
e.preventDefault();
console.log("Pressing CTRL+4");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][4]) document.activeElement.insertAtCaret(trans.data[thisRow][4]);
$("#currentCellText").trigger("change")
break;
case 53 : //5
e.preventDefault();
console.log("Pressing CTRL+5");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][5]) document.activeElement.insertAtCaret(trans.data[thisRow][5]);
$("#currentCellText").trigger("change")
break;
case 54 : //6
e.preventDefault();
console.log("Pressing CTRL+6");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][6]) document.activeElement.insertAtCaret(trans.data[thisRow][6]);
$("#currentCellText").trigger("change")
break;
case 55 : //7
e.preventDefault();
console.log("Pressing CTRL+7");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][7]) document.activeElement.insertAtCaret(trans.data[thisRow][7]);
$("#currentCellText").trigger("change")
break;
case 56 : //8
e.preventDefault();
console.log("Pressing CTRL+8");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][8]) document.activeElement.insertAtCaret(trans.data[thisRow][8]);
$("#currentCellText").trigger("change")
break;
case 57 : //9
e.preventDefault();
console.log("Pressing CTRL+9");
thisRow = trans.lastSelectedCell[0];
if (trans.data[thisRow][9]) document.activeElement.insertAtCaret(trans.data[thisRow][9]);
$("#currentCellText").trigger("change")
break;
}
}
if (e.altKey) {
switch(keyCode) {
case 48 : //0
e.preventDefault();
console.log("Pressing ALT+0");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(0));
$(document.activeElement).trigger('change');
break;
case 49 : //1
e.preventDefault();
console.log("Pressing ALT+1");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(1));
$(document.activeElement).trigger('change');
break;
case 50 : //2
e.preventDefault();
console.log("Pressing ALT+2");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(2));
$(document.activeElement).trigger('change');
break;
case 51 : //3
e.preventDefault();
console.log("Pressing ALT+3");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(3));
$(document.activeElement).trigger('change');
break;
case 52 : //4
e.preventDefault();
console.log("Pressing ALT+4");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(4));
$(document.activeElement).trigger('change');
break;
case 53 : //5
e.preventDefault();
console.log("Pressing ALT+5");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(5));
$(document.activeElement).trigger('change');
break;
case 54 : //6
e.preventDefault();
console.log("Pressing ALT+6");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(6));
$(document.activeElement).trigger('change');
break;
case 55 : //7
e.preventDefault();
console.log("Pressing ALT+7");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(7));
$(document.activeElement).trigger('change');
break;
case 56 : //8
e.preventDefault();
console.log("Pressing ALT+8");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(8));
$(document.activeElement).trigger('change');
break;
case 57 : //9
e.preventDefault();
console.log("Pressing ALT+9");
document.activeElement.insertAtCaret(trans.getTranslationByIndex(9));
$(document.activeElement).trigger('change');
break;
}
}
});
// Open .externalLink anchor to native browser
$("a.externalLink, a[external]").on("click", function(e) {
e.preventDefault();
nw.Shell.openExternal($(this).attr("href"));
})
// =============================================================
// HANDLING TEXTAREA SUGGESTION
// =============================================================
/*
window.elements = ['span', 'div', 'h1', 'h2', 'h3'];
$('#currentCellText').textcomplete([
{ // html
match: /<(\w*)$/,
search: function (term, callback) {
callback($.map(elements, function (element) {
return element.indexOf(term) === 0 ? element : null;
}));
},
index: 1,
replace: function (element) {
return ['<' + element + '>', '</' + element + '>'];
}
}
]);
*/
// window.elements = ['span', 'div', 'h1', 'h2', 'h3'];
$('#currentCellText').textcomplete([
{
match: /(^|\b)(\w{1,})$/,
//match: /(^|\b)(.*?)$/,
search: function (term, callback) {
callback($.map(ui.words || [], function (word) {
return word.indexOf(term) === 0 ? word : null;
}));
},
replace: function (word) {
return word + ' ';
}
},
// { // html
// match: /<(\w*)$/,
// search: function (term, callback) {
// callback($.map(window.elements, function (element) {
// return element.indexOf(term) === 0 ? element : null;
// }));
// },
// index: 1,
// replace: function (element) {
// return ['<' + element + '>', '</' + element + '>'];
// }
// },
{ // html
//mentions: ['yuku_t'],
match: /\B\\(\w*)$/,
search: function (term, callback) {
//callback($.map(this.mentions, function (mention) {
callback($.map(ui.autoComplateData, function (mention) {
return mention.indexOf(term) === 0 ? mention : null;
}));
},
index: 1,
replace: function (mention) {
return mention + '';
}
}
]);
// =============================================================
// FILTERABLE
// =============================================================
window.commandOption = {
valueNames: [
'filterable',
{ data: ['id'] }
]
};
ui.fileList = new window.List('menuPanel', window.commandOption);
ui.isLoaded = true;
ui.cellInfoTab = new ui.CellInfoTab($(".cellInfoPartsA"));
ui.cellTranslationTab = new ui.CellInfoTab($(".cellInfoPartsB"), {eventName:"translationOnTabChange"});
// initialization
ui.resize.init();
$("#busyOverlay").removeClass("pitchBlack");
//$("#busyOverlay").addClass("hidden");
ui.fixCellInfoSize();
// close all child window in initialization
//ui.closeAllChildWindow(true);
sys.onReady(function() {
ui.init();
})
ui.initTextResizer();
ui.isInitialized = true;
ui.introWindowShow();
ui.onReady(function() {});
ui.trigger("ready");
console.warn("Removing busy overlay");
if (!window.addonLoader) {
ui.hideBusyOverlay();
} else {
window.addonLoader.onReady(() => {
ui.hideBusyOverlay();
});
}
});