/**=====LICENSE STATEMENT START=====
Translator++
CAT (Computer-Assisted Translation) tools and framework to create quality
translations and localizations efficiently.
Copyright (C) 2018 Dreamsavior<dreamsavior@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
=====LICENSE STATEMENT END=====*/
var nwPath = require("path"); // eslint-disable-line
const Search = function() {
try {
this.config = JSON.parse(localStorage.getItem('search.config'));
} catch (e) {
// do nothing.
}
this.config = this.config || {};
if (typeof this.config.alwaysOnTop == 'undefined') this.config.alwaysOnTop = true;
this.config.blurOpacity = this.config.blurOpacity || 0.7
};
var search = new Search();
search.setConfig = function(key, value) {
this.config[key] = value;
this.saveConfig();
}
search.getConfig = function(key) {
return this.config[key];
}
search.saveConfig = function() {
localStorage.setItem('search.config', JSON.stringify(this.config));
}
search.blurOpacity = search.getConfig('blurOpacity');
var win = nw.Window.get();
win.restore(); // restore if minimized
win.show(); // show if hidden
win.setResizable(true);
win.height = 340;
win.width = 640;
if (win.y < 0) win.y = 0;
if (win.x < 0) win.x = 0;
//win.setResizable(false);
console.log("current Y", win.y, win.y < 0);
setTimeout(()=>{
if (win.y < 0) win.y = 0;
win.setMinimumSize(640, 340)
console.log("current Y", win.y);
try {
var lastPos = window.localStorage.getItem("searchWindowPossition");
if (!lastPos) return;
lastPos = JSON.parse(lastPos);
console.log("Setting window position", lastPos);
win.x = lastPos.x;
win.y = lastPos.y;
} catch(e) {
//do nothing
}
}, 200)
win.setAlwaysOnTop(search.getConfig('alwaysOnTop'));
win.setShowInTaskbar(false);
win.setMinimumSize(530, 260);
var sys = window.opener.sys;
var trans = window.opener.trans;
var ui = window.opener.ui;
var UiTags = window.opener.UiTags;
search.getSelectedResult = function() {
var $activeTab = $(".ui-tabs-panel[aria-hidden=false]")
var $selected = $activeTab.find(".findItemSelector:checked");
var data = [];
$selected.each(function() {
var $this = $(this);
var thisData = $this.data();
thisData.file = $this.closest(".resultContext").data("id")
data.push(thisData);
})
return data;
}
/**
* Replaces \r\n\t with carriage return, new line or tab
* @param {String} text
* @returns {String} transpiled text
*/
search.transpileText = function(text) {
console.log("Transpiling text", text);
text = text || "";
text = text.replaceAll("\\r", "\r");
text = text.replaceAll("\\n", "\n");
text = text.replaceAll("\\t", "\t");
console.log("After transpile:", text);
return text;
}
search.initFileSelectorDragSelect = function() {
var DragSelect = DragSelect||require("dragselect");
const toggleCheck = 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");
if ($input.prop("disabled")) return;
if (search.shiftPressed) {
$input.prop("checked", false);
} else {
$input.prop("checked", true);
}
$input.trigger("change");
window.ds.clearSelection();
})
}
const $fileSelectors = $(".fileSelector")
for (let i=0; i<$fileSelectors.length; i++) {
let thisSelector = $fileSelectors[i]
window.ds = new DragSelect({
selectables : document.querySelectorAll('.selectable'),
autoScrollSpeed : 15,
area : thisSelector,
callback : toggleCheck
});
}
if (search.fileSelectorIsInitialized) return;
// tracking shift key
window.onkeyup = function(e) {
if (e.keyCode == 16) search.shiftPressed = false;
//console.log("canceled");
}
window.onkeydown = function(e) {
if (e.shiftKey) search.shiftPressed = true;
//console.log("do");
}
search.fileSelectorIsInitialized = true;
}
search.getKeyboardStatus = function(keyboard) {
if (keyboard == "shift") return search.shiftPressed;
}
search.checkGroup = function($selectFld, action) {
var $allCheckbox = $selectFld.closest('.resultContext').find("ul .findItemSelector");
var thisStatus = $selectFld.prop("checked");
$allCheckbox.each(function() {
$(this).prop("checked", thisStatus)
})
}
search.checkAll = function($selectFld, action) {
console.log($selectFld);
var $allHeaderCheckbox = $selectFld.closest('.actionResult').find(".headerGroupCheckbox");
var thisStatus = $selectFld.prop("checked");
$allHeaderCheckbox.each(function() {
$(this).prop("checked", thisStatus);
$(this).trigger("input");
})
}
search.getTags = function(file, row) {
// results : array of tags;
var result = [];
try {
result = trans.project.files[file].tags[row];
} catch (err) {
// do nothing
}
return result;
}
search.drawTags = function($resultLine, file, row, options) {
options = options||{};
options.force = options.force||false;
try {
var tags = search.getTags(file, row);
if (options.force == false) {
if (Array.isArray(tags) == false) return $resultLine;
if (tags.length == 0) return $resultLine;
}
var $resultInfo = $resultLine.find(".resultInfo");
$resultInfo.find(".tags").remove();
var $tagContainer = $("<span class='tags'></span>");
$resultInfo.append($tagContainer);
if (Array.isArray(tags) == false) return $resultLine;
for (var i=0; i<tags.length; i++) {
let $thisIcon = $("<i class='tagIcon icon-circle "+tags[i]+"' title='"+tags[i]+"'></i>");
$thisIcon.css("color", consts.tagColor[tags[i]]);
$tagContainer.append($thisIcon);
}
} catch (err) {
console.log("Error drawing tags", err);
}
return $resultLine;
}
search.appendTags = function(file, row, tags, $actionResult) {
try {
if (Array.isArray(tags) == false) tags = [tags];
trans.appendTags(file, parseInt(row), tags);
} catch (err) {
console.warning("Failed to handle appendTags", err);
}
}
search.appendTagsOnSelected = function(tags, $actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var startTime = performance.now();
var $lines = $actionResult.find(".findItemSelector:checked");
$lines.each(function() {
var $this = $(this);
var $resultItem = $this.closest(".resultItem");
var $resultContext = $this.closest(".resultContext");
search.appendTags($resultContext.data("id"), $resultItem.attr("data-row"), tags);
search.drawTags($resultItem, $resultContext.data("id"), $resultItem.attr("data-row"));
});
var endTime = performance.now()
console.log(`Append tags done! It took ${endTime - startTime} ms `);
trans.grid.render();
}
search.setTags = function(file, row, tags, $actionResult) {
try {
if (Array.isArray(tags) == false) tags = [tags];
trans.setTags(file, parseInt(row), tags);
} catch (err) {
console.warning("Failed to handle appendTags", err);
}
}
search.setTagsOnSelected = function(tags, $actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $lines = $actionResult.find(".findItemSelector:checked");
$lines.each(function() {
var $resultItem = $(this).closest(".resultItem");
var $resultContext = $(this).closest(".resultContext");
search.setTags($resultContext.data("id"), $resultItem.attr("data-row"), tags);
search.drawTags($resultItem, $resultContext.data("id"), $resultItem.attr("data-row"));
})
trans.grid.render();
}
search.removeTags = function(file, row, tags, $actionResult) {
try {
if (Array.isArray(tags) == false) tags = [tags];
trans.removeTags(file, parseInt(row), tags);
} catch (err) {
console.warning("Failed to handle appendTags", err);
}
}
search.removeTagsOnSelected = function(tags, $actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $lines = $actionResult.find(".findItemSelector:checked");
$lines.each(function() {
var $resultItem = $(this).closest(".resultItem");
var $resultContext = $(this).closest(".resultContext");
search.removeTags($resultContext.data("id"), $resultItem.attr("data-row"), tags);
search.drawTags($resultItem, $resultContext.data("id"), $resultItem.attr("data-row"));
});
trans.grid.render();
}
search.clearTags = function(file, row, $actionResult) {
try {
trans.clearTags(file, parseInt(row));
} catch (err) {
console.warning("Failed to handle clearTags", err);
}
}
search.clearTagsOnSelected = function($actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $lines = $actionResult.find(".findItemSelector:checked");
$lines.each(function() {
var $resultItem = $(this).closest(".resultItem");
var $resultContext = $(this).closest(".resultContext");
search.clearTags($resultContext.data("id"), $resultItem.attr("data-row"));
$resultItem.find(".tags").empty();
})
trans.grid.render();
}
search.openTagMenu = function() {
var $popup = $("#find_tagMenu");
if ($popup.length == 0) {
$popup = $("<div id='find_tagMenu'></div>");
$("#template").append($popup);
var tags = 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>
`)
});
this._uiTags = tags;
$popup.empty();
$popup.append(tags.element);
}
$popup.dialog({
title: t("Set tags"),
autoOpen: false,
modal:true,
width:480,
height:220,
minWidth:480,
minHeight:220,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 200
},
buttons:[
{
text: t("Close"),
icon: "ui-icon-close",
click: function() {
$(this).dialog( "close" );
}
},
{
text: t("Proceed"),
click: async function() {
var $this = $(this)
var tags = search._uiTags.getValue();
console.log(tags);
if (tags === false) return false;
$this.dialog( "close" );
if (tags.filterTagMode == "appendTags") {
search.appendTagsOnSelected(tags.filterTag);
} else if (tags.filterTagMode == "removeTags") {
search.removeTagsOnSelected(tags.filterTag);
} else {
search.setTagsOnSelected(tags.filterTag);
}
}
}
]
});
$popup.dialog("open");
}
search.loadKeywords = function() {
var $keywords = $("#keywords");
if (!localStorage.getItem("search.keywords")) return;
try {
var keywords = JSON.parse(localStorage.getItem("search.keywords"))
} catch (e) {
// do nothing
}
for (var i=0; i<keywords.length; i++) {
var $newOption = $("<option></option>");
$newOption.attr("value", keywords[i]);
$keywords.append($newOption);
}
}
search.addKeyword = function(keyword) {
var $keywords = $("#keywords");
try {
// remove existing keyword
var $exsit = $keywords.find(`[value="${CSS.escape(keyword)}"]`);
$exsit.remove();
} catch (e) {
console.warn(e)
}
var $newOption = $("<option></option>");
$newOption.attr("value", keyword);
$keywords.prepend($newOption);
$keywords = $keywords.find("option");
if ($keywords.length > 100) {
$keywords.eq($keywords.length - 1).remove();
}
// save keyword
var keywords = [];
for (var i=0; i<$keywords.length; i++) {
keywords.push($keywords.eq(i).attr("value"));
}
if (keywords.length>0) localStorage.setItem("search.keywords", JSON.stringify(keywords))
}
search.sendCommandFind = function(keyword) {
keyword = keyword||$("#fieldFind").val();
if (keyword.length < 1) return alert(t("Keyword too short!"));
this.addKeyword(keyword);
var caseSensitiveMode = $("#caseSensitive").prop("checked");
var $notFoundMsg = $("<div class='blockBox infoBlock withIcon'>"+t("Found nothing!<br />Don't forget to set the Target search field.")+"</div>")
var selectedFiles = "*";
if ($("#selectAllFile").prop("checked") == false) {
selectedFiles = [];
$("#find .fileSelector .filename:checked").each(function() {
selectedFiles.push($(this).attr("value"));
});
}
// transpile
if ($("#find .transpileCode").prop("checked")) {
keyword = this.transpileText(keyword);
}
console.log("Selected file is :");
console.log(selectedFiles);
// array of value
var searchLocations = $(".searchMode").val();
var result = trans.search(keyword, {
caseSensitive : caseSensitiveMode,
files : selectedFiles,
searchLocations : searchLocations,
isRegexp : $("#findIsRegexp").prop("checked")
});
search.toggleFileList(false);
$("#find .searchResult").empty();
var $template = $("<div class='searchResultHeader column2'>\
<div class='searchresultAction'>\
<input type='checkbox' value='' class='headerCheckbox' /> \
<span>Select all</span>\
</div>\
<div class='right searchResultData'>\
<i class='icon-docs'></i> <span class='numFile'>"+result.count+"</span>\
<i class='icon-hourglass-3'></i> "+result.executionTime+" ms\
</div>\
</div>");
$template.find(".headerCheckbox").on("input", function(e) {
search.checkAll.call(search, $(this));
});
$("#find .searchResult").append($template);
if (typeof result.files == "undefined" || result.count == 0) $("#find .searchResult").append($notFoundMsg);
for (var file in result.files) {
//var $lineFile = $("<div class='resultContext' data-id="+file+"><h2><input type='checkbox' value='1' class='headerGroupCheckbox' /> <i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
var $lineFile = $("<div class='resultContext' ><h2><input type='checkbox' value='1' class='headerGroupCheckbox' /> <i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
$lineFile.data("id", file);
$lineFile.find(".headerGroupCheckbox").on("input", function(e) {
search.checkGroup.call(search, $(this));
});
for(var i in result.files[file]) {
var currentLine = result.files[file][i];
var refference = "";
var foundStr = common.htmlEntities(currentLine.fullString);
if (result.isRegexp) {
var regExpKeyword = common.evalRegExpStr(keyword);
if (regExpKeyword !== false) {
foundStr = foundStr.replace(regExpKeyword,
function(){
return '<span class="highlight">'+arguments[0]+'</span>';
});
}
} else {
foundStr = foundStr.replaces(keyword, "<span class='highlight'>"+common.htmlEntities(keyword)+"</span>", !caseSensitiveMode);
}
//console.log(currentLine);
try {
var thisFileRef = trans.project.files[file].data[currentLine.row];
if (currentLine.col == 0) {
// this is key row, search translation for refference
for (var n=thisFileRef.length; n>0; n--) {
if (thisFileRef[n]) {
refference = thisFileRef[n];
break;
}
}
} else {
// this not a key row, search keyrow for refference
refference = thisFileRef[0];
}
}
catch (err) {
// do nothing
}
refference = common.htmlEntities(refference);
var lineTemplate = $("<li class='resultItem' title='click to go' data-row='"+currentLine.row+"' data-col='"+currentLine.col+"'>"+
"<div class='texts'>"+
"<h1>"+foundStr+"</h1>"+
"<h1 class='refference' title='refference'>"+refference+"</h1>"+
"</div>"+
`<div class='resultInfo'><span class='findItemSelectorWrapper'><input type='checkbox' data-row='${currentLine.row}' data-col='${currentLine.col}' class='findItemSelector' value='' /></span><span class='rowLabel' title='row'>${currentLine.row}</span><span class='colLabel' title='column'>${currentLine.col}</span></div></li>`);
lineTemplate.data("row", currentLine.row);
lineTemplate.data("col", currentLine.col);
lineTemplate.data("context", file);
lineTemplate.on("click", function(e) {
if ($(e.target).is("input[type=checkbox]")) {
return;
}
trans.goTo($(this).data("row"), $(this).data("col"), $(this).data("context"));
$(this).closest(".searchResult").find(".selected").removeClass("selected");
$(this).addClass("selected");
});
lineTemplate.find(".findItemSelector").on("change", function() {
search.find = search.find || {};
if ($(this).prop("checked") == true) {
search.find.$lastCheckedFile = $(this);
} else {
search.find.$lastCheckedFile = undefined;
}
});
lineTemplate.find(".findItemSelector").on("mousedown", function(e) {
search.find = search.find || {};
if (!search.find.$lastCheckedFile) return false;
if (e.shiftKey) {
console.log("The SHIFT key was pressed!");
var $checkBoxes = $(this).closest(".actionResult").find(".findItemSelector");
var lastIndex = $checkBoxes.index(search.find.$lastCheckedFile);
var thisIndex = $checkBoxes.index(this);
var chckFrom;
var chckTo;
if (lastIndex < thisIndex) {
chckFrom = lastIndex;
chckTo = thisIndex;
} else {
chckFrom = thisIndex;
chckTo = lastIndex;
}
console.log("check from index "+chckFrom+" to "+chckTo);
for (var i=chckFrom; i<chckTo; i++) {
$checkBoxes.eq(i).prop("checked", true).trigger("change");
}
}
});
search.drawTags(lineTemplate, file, currentLine.row);
$lineFile.find("ul").append(lineTemplate);
}
$("#find .searchResult").append($lineFile);
}
console.log(result);
}
search.sendCommandReplace = function() {
var keyword = $("#fieldReplaceFind").val();
var replacer = $("#fieldReplaceReplace").val();
if (keyword.length < 1) return alert("Keyword too short!");
this.addKeyword(keyword);
var $notFoundMsg = $("<div class='blockBox infoBlock withIcon'>"+t("Found nothing to replace!<br />Replace function doesn't replace anything on the key column.")+"</div>")
var conf = confirm(t("Replace '")+keyword+t("' with '")+replacer+t("'?\r\nWe still haven't create undo function for this thing!\nAre you sure want to proceed?"));
if (!conf) return false;
var caseSensitiveMode = $("#caseSensitiveReplace").prop("checked");
var selectedFiles = "*";
if ($("#selectAllFileReplace").prop("checked") == false) {
selectedFiles = [];
$("#replace .fileSelector .filename:checked").each(function() {
selectedFiles.push($(this).attr("value"));
});
}
// transpile
if ($("#replace .transpileCode").prop("checked")) {
keyword = this.transpileText(keyword);
replacer = this.transpileText(replacer);
}
console.log("Selected file is :");
console.log(selectedFiles);
var result = trans.replace(keyword, replacer, {
caseSensitive : caseSensitiveMode,
'files' : selectedFiles,
isRegexp : $("#replaceIsRegexp").prop("checked")
});
search.toggleFileList(false);
$(".replaceResult").empty();
if (typeof result.files == "undefined") $(".replaceResult").html($notFoundMsg);
if (result.count == 0) $(".replaceResult").html($notFoundMsg);
var $template = $("<div class='searchResultHeader column2'>\
<div class='searchresultAction'>\
<input type='checkbox' value='' class='headerCheckbox' /> \
<span>Select all</span>\
</div>\
<div class='right searchResultData'>\
<i class='icon-docs'></i> <span class='numFile'>"+result.count+"</span>\
<i class='icon-hourglass-3'></i> "+result.executionTime+" ms\
</div>\
</div>");
$template.find(".headerCheckbox").on("input", function(e) {
search.checkAll.call(search, $(this));
});
$(".replaceResult").prepend($template);
for (var file in result.files) {
//var $lineFile = $("<div class='resultContext' data-id="+file+"><h2><input type='checkbox' value='1' class='headerGroupCheckbox' /><i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
var $lineFile = $("<div class='resultContext' ><h2><input type='checkbox' value='1' class='headerGroupCheckbox' /><i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
$lineFile.data("id", file);
$lineFile.find(".headerGroupCheckbox").on("input", function(e) {
search.checkGroup.call(search, $(this));
});
for(var i in result.files[file]) {
var currentLine = result.files[file][i];
var foundStr = common.htmlEntities(currentLine.originalString);
if (result.isRegexp) {
var regExpKeyword = common.evalRegExpStr(keyword);
if (regExpKeyword !== false) {
foundStr = foundStr.replace(regExpKeyword,
function(){
return '<span class="highlight2">'+arguments[0]+'</span>';
});
}
} else {
foundStr = foundStr.replaces(keyword, "<span class='highlight2'>"+keyword+"</span>", !caseSensitiveMode);
}
var replacedString = common.htmlEntities(currentLine.fullString).replaces(replacer, "<span class='highlight'>"+replacer+"</span>");
//var foundStr = currentLine.fullString.replaces(keyword, "<span class='highlight'>"+keyword+"</span>", !caseSensitiveMode);
var lineTemplate = $("<li class='resultItem' title='"+t("click to go")+"' data-row='"+currentLine.row+"' data-col='"+currentLine.col+"'>"+
"<div class='texts'>"+
"<h1 class='refference' title='refference'>"+foundStr+"</h1>"+
"<span><i class='icon-right-big'> </i></span>"+
"<h1>"+replacedString+"</h1>"+
"</div>"+
`<div class='resultInfo'><span class='findItemSelectorWrapper'><input type='checkbox' data-row='${currentLine.row}' data-col='${currentLine.col}' class='findItemSelector' value='' /></span><span class='rowLabel' title='row'>${currentLine.row}</span><span class='colLabel' title='column'>${currentLine.col}</span></div></li>`);
lineTemplate.data("row", currentLine.row);
lineTemplate.data("col", currentLine.col);
lineTemplate.data("context", file);
lineTemplate.on("click", function(e) {
if ($(e.target).is("input[type=checkbox]")) {
return;
}
trans.goTo($(this).data("row"), $(this).data("col"), $(this).data("context"));
});
lineTemplate.find(".findItemSelector").on("change", function() {
search.repl = search.repl || {};
if ($(this).prop("checked") == true) {
search.repl.$lastCheckedFile = $(this);
} else {
search.repl.$lastCheckedFile = undefined;
}
});
lineTemplate.find(".findItemSelector").on("mousedown", function(e) {
search.repl = search.repl || {};
if (!search.repl.$lastCheckedFile) return false;
if (e.shiftKey) {
console.log("The SHIFT key was pressed!");
var $checkBoxes = $(this).closest(".actionResult").find(".findItemSelector");
var lastIndex = $checkBoxes.index(search.repl.$lastCheckedFile);
var thisIndex = $checkBoxes.index(this);
var chckFrom;
var chckTo;
if (lastIndex < thisIndex) {
chckFrom = lastIndex;
chckTo = thisIndex;
} else {
chckFrom = thisIndex;
chckTo = lastIndex;
}
console.log("check from index "+chckFrom+" to "+chckTo);
for (let i=chckFrom; i<chckTo; i++) {
$checkBoxes.eq(i).prop("checked", true).trigger("change");
}
}
});
search.drawTags(lineTemplate, file, currentLine.row);
$lineFile.find("ul").append(lineTemplate);
}
$(".replaceResult").append($lineFile);
}
console.log(result);
}
search.sendCommandPut = function() {
var conf = confirm(t("This will replace any translation found in target colum,\nAre you sure?"));
if (!conf) return false;
var keyword = $("#findPut .fldFind").val();
if (keyword.length < 1) return alert(t("Keyword too short!"));
var put = $("#findPut .fldPut").val();
var caseSensitiveMode = $("#findPut .caseSensitive").prop("checked");
var targetCol = parseInt($("#findPut .targetSelector select").val());
targetCol = parseInt(targetCol);
var selectedFiles = "*";
if ($("#findPut .selectAllFile").prop("checked") == false) {
selectedFiles = [];
$("#findPut .fileSelector .filename:checked").each(function() {
selectedFiles.push($(this).attr("value"));
});
}
console.log("Selected file is :");
console.log(selectedFiles);
var result = trans.findPut(keyword, put, targetCol, {
caseSensitive : caseSensitiveMode,
files : selectedFiles,
lineMatch : true
});
console.log("result is", result);
search.toggleFileList(false);
$("#findPut .searchResult").empty();
if (typeof result.files == "undefined") $("#findPut .searchResult").html(t("Not found!"));
if (result.count == 0) $("#findPut .searchResult").html(t("Not found!"));
var $template = $("<div class='searchResultHeader column2'>\
<div class='searchresultAction'>\
<input type='checkbox' value='' class='headerCheckbox' /> \
<span>Select all</span>\
</div>\
<div class='right searchResultData'>\
<i class='icon-docs'></i> <span class='numFile'>"+result.count+"</span>\
<i class='icon-hourglass-3'></i> "+result.executionTime+" ms\
</div>\
</div>");
$template.find(".headerCheckbox").on("input", function(e) {
search.checkAll.call(search, $(this));
});
$("#findPut .searchResult").prepend($template);
for (var file in result.files) {
//var $lineFile = $("<div class='resultContext' data-id="+file+"><h2><i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
var $lineFile = $("<div class='resultContext' ><h2><i class='icon-doc'></i>"+file+" <span class='contextCount'>"+result.files[file].length+"</span></h2><ul></ul></div>");
$lineFile.data("id", file);
for(var i in result.files[file]) {
var currentLine = result.files[file][i];
var foundStr = currentLine.fullString.replaces(keyword, "<span class='highlight'>"+keyword+"</span>", !caseSensitiveMode);
var refference = "";
//console.log(currentLine);
try {
var thisFileRef = trans.project.files[file].data[currentLine.row];
refference = thisFileRef[targetCol];
}
catch (err) {
// do nothing
}
var lineTemplate = $("<li class='resultItem' title='click to go' data-row='"+currentLine.row+"' data-col='"+currentLine.col+"'>"+
"<div class='texts'>"+
"<h1>"+foundStr+"</h1>"+
"<h1 class='refference' title='refference'>"+refference+"</h1>"+
"</div>"+
`<div class='resultInfo'><span class='findItemSelectorWrapper'><input type='checkbox' data-row='${currentLine.row}' data-col='${currentLine.col}' class='findItemSelector' value='' /></span><span class='rowLabel' title='row'>${currentLine.row}</span><span class='colLabel' title='column'>${currentLine.col}</span></div></li>`);
lineTemplate.data("row", currentLine.row);
lineTemplate.data("col", currentLine.col);
lineTemplate.data("context", file);
lineTemplate.on("click", function(e) {
if ($(e.target).is("input[type=checkbox]")) {
return;
}
trans.goTo($(this).data("row"), $(this).data("col"), $(this).data("context"));
});
lineTemplate.find(".findItemSelector").on("change", function() {
search.find = search.find || {};
if ($(this).prop("checked") == true) {
search.find.$lastCheckedFile = $(this);
} else {
search.find.$lastCheckedFile = undefined;
}
});
lineTemplate.find(".findItemSelector").on("mousedown", function(e) {
search.find = search.find || {};
if (!search.find.$lastCheckedFile) return false;
if (e.shiftKey) {
console.log("The SHIFT key was pressed!");
var $checkBoxes = $(this).closest(".actionResult").find(".findItemSelector");
var lastIndex = $checkBoxes.index(search.find.$lastCheckedFile);
var thisIndex = $checkBoxes.index(this);
var chckFrom;
var chckTo;
if (lastIndex < thisIndex) {
chckFrom = lastIndex;
chckTo = thisIndex;
} else {
chckFrom = thisIndex;
chckTo = lastIndex;
}
console.log("check from index "+chckFrom+" to "+chckTo);
for (let i=chckFrom; i<chckTo; i++) {
$checkBoxes.eq(i).prop("checked", true).trigger("change");
}
}
});
search.drawTags(lineTemplate, file, currentLine.row);
$lineFile.find("ul").append(lineTemplate);
}
$("#findPut .searchResult").append($lineFile);
}
}
search.drawFileSelector = function() {
if (typeof trans.project == 'undefined') return false;
var project = trans.project;
for (var file in project.files) {
var template = $("<label class='selectable'><input type='checkbox' class='filename' value='"+file+"' /><span>"+file+"</span></label>");
template.attr("title", file)
$(".fileSelector").append(template);
}
search.initFileSelectorDragSelect();
}
search.toggleFileList = function(stat) {
if (typeof stat == 'undefined') {
stat = !$(".toggleFileSelector").hasClass("opened");
}
if (!stat) {
$(".fileSelector").addClass("hidden");
$(".toggleFileSelector").removeClass("opened");
} else {
$(".fileSelector").removeClass("hidden");
$(".toggleFileSelector").addClass("opened");
}
return stat;
}
// ======================================================================
// context menu handler
// ======================================================================
search.selectAll = function($actionResult) {
//select all by given actionResult
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $headerCheckbox = $actionResult.find(".headerCheckbox");
$headerCheckbox.prop("checked", true);
$headerCheckbox.trigger("input");
//search.checkAll($actionResult.find(".headerCheckbox"));
}
search.unSelectAll = function($actionResult) {
//select all by given actionResult
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $headerCheckbox = $actionResult.find(".headerCheckbox");
$headerCheckbox.prop("checked", false);
$headerCheckbox.trigger("input");
//search.checkAll($actionResult.find(".headerCheckbox"));
}
search.clearTranslationOnSelected = function($actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $lines = $actionResult.find(".findItemSelector:checked");
$lines.each(function() {
var $resultItem = $(this).closest(".resultItem");
var $resultContext = $(this).closest(".resultContext");
var fileId = $resultContext.data("id");
var row = $resultItem.attr("data-row");
try {
var thisRow = trans.project.files[fileId].data[row];
trans.project.files[fileId].data[row] = thisRow.fill("", 1);
} catch (e) {
//do nothing
}
//search.appendTags($resultContext.data("id"), $resultItem.attr("data-row"), tags);
})
trans.grid.render();
}
search.removeSelectedElement = function($actionResult) {
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $files = $actionResult.find(".resultContext");
$files.each(function() {
var $thisFile = $(this);
var $thisLines = $thisFile.find(".findItemSelector:checked");
if ($thisLines.length < 1) return;
$thisLines.each(function() {
$(this).closest("li").remove();
})
if($thisFile.find("li.resultItem").length < 1) $thisFile.remove();
})
$actionResult.find(".numFile").text( $actionResult.find("li.resultItem").length)
}
search.deleteSelected = function($actionResult) {
// should make the row, col & file id unique
$actionResult = $actionResult||$(".ui-tabs-panel[aria-hidden=false] .actionResult");
var $files = $actionResult.find(".resultContext");
for (var i=0; i<$files.length; i++) {
var $thisFile = $files.eq(i);
var $thisLine = $thisFile.find(".findItemSelector:checked");
if ($thisLine.length < 1) continue;
var fileId = $thisFile.data("id");
var rows = [];
for (var x=0; x<$thisLine.length; x++) {
rows.push($thisLine.eq(x).data("row"));
}
console.log(`trans.removeRow()`, fileId, rows);
trans.removeRow(fileId, rows)
}
this.removeSelectedElement($actionResult);
trans.grid.render();
}
search.openAutomationEditor = async function() {
var options = {
workspace : "foundCells",
foundCells : search.getSelectedResult()
}
ui.openAutomationEditor("codeEditor_foundCells", options);
}
search.automationMenu = function() {
console.log("Creating automation menu");
var subMenu = new nw.Menu();
const configPath = "codeEditor/foundCells"
var menuConfig = sys.getConfig(configPath);
if (!menuConfig) {
sys.setConfig(configPath, {quickLaunch:[]});
menuConfig = sys.getConfig(configPath);
}
menuConfig["quickLaunch"] = menuConfig["quickLaunch"] || [];
for (var i=0; i<menuConfig["quickLaunch"].length; i++) {
(()=>{
var filePath = menuConfig["quickLaunch"][i];
var filename = common.getFilename(filePath);
subMenu.append(new nw.MenuItem({
label: filename,
type: "normal",
click: function(){
const searchResult = search.getSelectedResult();
var conf = confirm(t("Are you sure want to execute the following script?")+"\n"+filename+"\n"+
t("For ")+searchResult.length+t(" selected item(s)?")
);
if (!conf) return;
trans.runCustomScript("foundCells", filePath, {
foundCells: searchResult
});
}
}));
})()
}
return subMenu;
}
search.searchResultContextMenu = function() {
console.log("trans.fileSelectorContextMenuInit");
if (this.searchResultContextMenuIsInitialized) return false;
this.menu = new nw.Menu();
// Add some items with label
this.menu.append(new nw.MenuItem({
label: t(' Select all'),
type: "normal",
click: function() {
search.selectAll();
}
}));
this.menu.append(new nw.MenuItem({
label: t(' Clear selection'),
type: "normal",
click: function() {
search.unSelectAll();
}
}));
this.menu.append(new nw.MenuItem({
type: 'separator'
}));
var tagging = new nw.Menu();
tagging.append(new nw.MenuItem({
label: t(' Set Red tag'),
type: "normal",
icon: "www/img/red.png",
click: function() {
search.appendTagsOnSelected("red");
}
}));
tagging.append(new nw.MenuItem({
label: t(' Set Yellow tag'),
type: "normal",
icon: "www/img/yellow.png",
click: function() {
search.appendTagsOnSelected("yellow");
}
}));
tagging.append(new nw.MenuItem({
label: t(' Set Green tag'),
type: "normal",
icon: "www/img/green.png",
click: function() {
search.appendTagsOnSelected("green");
}
}));
tagging.append(new nw.MenuItem({
label: t(' Set Blue tag'),
type: "normal",
icon: "www/img/blue.png",
click: function() {
search.appendTagsOnSelected("blue");
}
}));
tagging.append(new nw.MenuItem({
label: t(' Set Gold tag'),
type: "normal",
icon: "www/img/gold.png",
click: function() {
search.appendTagsOnSelected("gold");
}
}));
tagging.append(new nw.MenuItem({
label: t(' More tags...'),
type: "normal",
click: function() {
search.openTagMenu();
}
}));
tagging.append(new nw.MenuItem({
type: 'separator'
}));
tagging.append(new nw.MenuItem({
label: t(' Clear tags'),
type: "normal",
click: function() {
search.clearTagsOnSelected();
}
}));
tagging.append(new nw.MenuItem({
type: 'separator'
}));
tagging.append(new nw.MenuItem({
label: t(' Create Automation'),
type: "normal",
click: function() {
search.openAutomationEditor();
}
}));
tagging.append(new nw.MenuItem({
label: t(' Run Automation'),
type: "normal",
submenu: search.automationMenu()
}));
tagging.append(new nw.MenuItem({
label: t(' Clear Automation'),
type: "normal",
click: function() {
var conf = confirm(t("Are you sure want to clear all quick launch scripts?"));
if (!conf) return;
sys.setConfig("codeEditor/foundCells", {quickLaunch:[]});
sys.saveConfig();
}
}));
tagging.append(new nw.MenuItem({
type: 'separator'
}));
tagging.append(new nw.MenuItem({
label: t(' Clear translation'),
type: "normal",
icon: "www/img/brush_icon.png",
click: function() {
var conf = confirm(t("Do you want to clear translations of the selected items?"));
if (!conf) return;
search.clearTranslationOnSelected();
}
}));
tagging.append(new nw.MenuItem({
label: t(' Delete rows'),
type: "normal",
icon: "www/img/trash_icon.png",
click: function() {
var conf = confirm(t("Do you want to remove selected rows?\nYou can not undo this action!"));
if (!conf) return;
search.deleteSelected();
}
}));
/*
var withSelection = new nw.Menu();
withSelection.append(new nw.MenuItem({
label: 'Tagging',
submenu: tagging
}))
*/
this.menu.append(new nw.MenuItem({
label: t(' With selection ...'),
icon: "www/img/checkmark.png",
submenu: tagging
}));
var that = this;
$(document.body).on("contextmenu", ".actionResult", function(ev) {
ev.preventDefault();
// Popup the native context menu at place you click
//console.log(ev);
console.log(ev.originalEvent);
that.menu.popup(parseInt(ev.originalEvent.x), parseInt(ev.originalEvent.y));
return false;
})
/*
document.body.addEventListener('contextmenu', function(ev) {
// Prevent showing default context menu
//console.log(ev);
if ($(ev.target).is(".actionResult") == false) return false;
ev.preventDefault();
// Popup the native context menu at place you click
that.menu.popup(ev.x, ev.y);
return false;
}, false);
*/
this.searchResultContextMenuIsInitialized = true;
}
search.optionsMenu = function(x, y) {
console.log("search.optionsMenu");
var uncheckBlurMenu = () => {
for (var id in this.menuOpacityItem) {
if (Boolean(this.menuOpacityItem[id]) == false) continue;
this.menuOpacityItem[id].checked = false;
}
}
this.menuOptions = new nw.Menu();
// Add some items with label
this.menuAlwaysOnTop = new nw.MenuItem({
label: t('Always on top'),
type: "checkbox",
checked: win.isAlwaysOnTop,
click: function(){
var currentState = win.isAlwaysOnTop;
win.setAlwaysOnTop(!currentState);
this.checked = !currentState;
search.setConfig('alwaysOnTop', !currentState);
}
})
this.menuOptions.append(this.menuAlwaysOnTop);
//this.menuOptions.append(new nw.MenuItem({ type: 'separator' }));
var opacity = new nw.Menu();
this.menuOpacityItem = {};
for (let i=10; i>0; i--) {
void function() {
var z = i;
var percent = z*10;
var current = search.blurOpacity*100;
var isChecked = false;
if (current == percent) isChecked = true;
var thisMenu = new nw.MenuItem({
label: percent+'%',
type: "checkbox",
checked: isChecked,
click: function(){
uncheckBlurMenu();
this.checked = true;
search.blurOpacity = z/10;
search.setConfig('blurOpacity', z/10);
}
});
search.menuOpacityItem[percent] = thisMenu;
opacity.append(thisMenu);
}()
}
opacity.append(new nw.MenuItem({ type: 'separator' }));
var isChecked = false;
if (search.blurOpacity == 0.6) isChecked = true;
this.menuOpacityItem['default'] = new nw.MenuItem({
label: t('Default'),
type: "checkbox",
checked: isChecked,
click: function(){
console.log(this, arguments)
uncheckBlurMenu();
this.checked = true;
search.blurOpacity = 0.6;
search.setConfig('blurOpacity', 0.6);
}
})
opacity.append(this.menuOpacityItem['default']);
/*
var withSelection = new nw.Menu();
withSelection.append(new nw.MenuItem({
label: 'Tagging',
submenu: tagging
}))
*/
this.menuOptions.append(new nw.MenuItem({
label: t('Blur opacity'),
submenu: opacity
}));
var that = this;
if (this.optionsMenuIsInitialized) return false;
$(".application-menu-button").on("click", function(ev) {
ev.preventDefault();
// Popup the native context menu at place you click
var thisOffset = $(this).offset();
//that.menu.popup(ev.originalEvent.x, ev.originalEvent.y);
that.menuOptions.popup(parseInt(thisOffset.left) - 80, 32);
return false;
})
this.optionsMenuIsInitialized = true;
}
search.getBlurOpacity = function() {
return this.blurOpacity;
}
search.initialize = function() {
this.appMenu = new nw.Menu();
this.appMenu.append(new nw.MenuItem({
label: t('Close'),
type: "normal",
click: function() {
}
}));
var that = this;
$(document.body).on("contextmenu", ".findWrapper", function(ev) {
ev.preventDefault();
// Popup the native context menu at place you click
//console.log(ev);
that.appMenu.popup(parseInt(ev.originalEvent.x), parseInt(ev.originalEvent.y));
return false;
})
this.optionsMenu();
this.loadKeywords();
}
// =======================================================
// EVENTS
// =======================================================
$(document).ready(function() {
search.searchResultContextMenu();
$(document).on('keydown', function(e) {
var keyCode = e.keyCode || e.which;
switch (keyCode) {
case 13 : //Enter
if (e.altKey || e.shiftKey) break;
e.preventDefault();
console.log("Searching");
if ($("div[aria-hidden=false]").attr("id") == "find") {
search.sendCommandFind();
} else if ($("div[aria-hidden=false]").attr("id") == "replace"){
search.sendCommandReplace();
} else {
search.sendCommandPut();
}
//$(".button-about").trigger("click");
break;
}
});
// INITIALIZING TAB
var type = window.location.hash.substr(1);
var mode = 0;
if (type == "replace") mode = 1;
console.log("tab index : "+mode);
$("#tabs").tabs({
active: mode,
activate: function(e, thisUi) {
console.log(thisUi);
if (thisUi.newPanel.attr("id") == 'findPut') {
$("#findPut .targetSelector").empty();
ui.generateColSelector({
skipFirstCol:true
}).appendTo($("#findPut .targetSelector"));
}
}
});
if (mode == 0) {
$("#fieldFind").focus();
} else {
$("#fieldReplaceFind").focus();
}
$(".toggleFileSelector").on("click", function(e) {
var $thisTab = $(this).closest(".ui-tabs-panel");
$(this).toggleClass("opened");
if ($(this).hasClass("opened")) {
$thisTab.find(".fileSelector").removeClass("hidden");
} else {
$thisTab.find(".fileSelector").addClass("hidden");
}
});
$(".selectAllFile").on("change", function(e) {
var $thisTab = $(this).closest(".ui-tabs-panel");
if ($(this).prop("checked")) {
$thisTab.find(".fileSelector").addClass("hidden");
$thisTab.find(".toggleFileSelector").removeClass("opened");
$thisTab.find(".fileSelector .filename").each(function() {
//console.log($(this));
$(this).prop("disabled", true);
});
} else {
$thisTab.find(".fileSelector").removeClass("hidden");
$thisTab.find(".toggleFileSelector").addClass("opened");
$thisTab.find(".fileSelector .filename").each(function() {
$(this).prop("disabled", false);
});
}
});
$(".application-bar .application-close-button").on("click", function(e) {
win.close();
})
$("#replaceIsRegexp").on("change", function() {
let $this = $(this);
if ($this.prop("checked")) {
$("#fieldReplaceFind").attr("placeholder", t("Type regex with the modifier"))
$("#fieldReplaceReplace").attr("placeholder", t("Use $n to replace a group. e.g. $1"))
} else {
$("#fieldReplaceFind").attr("placeholder", t("Find"))
$("#fieldReplaceReplace").attr("placeholder", t("Replace"))
}
})
search.initialize();
search.drawFileSelector();
$(".selectAllFile").trigger("change");
}); // document ready
win.on('blur', function() {
$("body").css("opacity", search.getBlurOpacity())
})
win.on('focus', function() {
$("body").css("opacity", "1")
})
win.on('close', function() {
// Hide the window to give user the feeling of closing immediately
this.hide();
window.localStorage.setItem("searchWindowPossition", JSON.stringify({
x: Math.round(win.x),
y: Math.round(win.y)
}));
// unregister this window on parent window.
if (typeof ui.windows.search !== 'undefined') ui.windows.search = undefined;
// After closing the new window, close the main window.
this.close(true);
});