Scripts collection

Discuss and announce AkelPad plugins
  • Author
  • Message
KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Brackets - go to or select between nearest brackets.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9923#p9923
// Version: 2013-08-23
// Author: KDJ
//
// *** Go to or select between nearest brackets ***
//
// Usage:
//   Call("Scripts::Main", 1, "BracketsGoTo.js", "l") - go to left to opening bracket
//   Call("Scripts::Main", 1, "BracketsGoTo.js", "r") - go to right to closing bracket
//   Call("Scripts::Main", 1, "BracketsGoTo.js", "L") - select between the brackets from left
//   Call("Scripts::Main", 1, "BracketsGoTo.js", "R") - select between the brackets from right
//
// Remarks:
//   To change a set of brackets, change the value nABrackets variable.
//   Can assign shortcut keys, eg: Ctrl+<, Ctrl+>, Ctrl+Shift+<, Ctrl+Shift+>.

var nABrackets = 1;
var aOpen;
var aClose;

if (nABrackets == 0)
{
  aOpen  = ["(", "[", "{", "<", "'", "\"", "/"];
  aClose = [")", "]", "}", ">", "'", "\"", "/"];
}
else if (nABrackets == 1)
{
  aOpen  = ["(", "[", "{", "'", "\""];
  aClose = [")", "]", "}", "'", "\""];
}
else if (nABrackets == 2)
{
  aOpen  = ["(", "[", "{"];
  aClose = [")", "]", "}"];
}
else if (nABrackets == 3)
{
  aOpen  = ["'", "\""];
  aClose = ["'", "\""];
}

var hEditWnd = AkelPad.GetEditWnd();
var sAction;

if (! hEditWnd)
  WScript.Quit();
if (WScript.Arguments.length)
  sAction = WScript.Arguments(0);
if (! sAction)
  WScript.Quit();

var nCarPos   = GetOffset(hEditWnd, 5 /*AEGI_CARETCHAR*/);
var nLastChar = GetOffset(hEditWnd, 2 /*AEGI_LASTCHAR*/);
var sTxt      = AkelPad.GetTextRange(0, nLastChar, 1 /*\r*/);
var sCarChar  = AkelPad.GetTextRange(nCarPos, nCarPos + 1);
var bSelAll   = false;
var nPos;
var nBrack;
var nBrackPos;
var nBegSel;
var nEndSel;
var i;

if ((sAction == "l") && (nCarPos > 0))
{
  nBrackPos = -1;
  for (i = 0; i < aOpen.length; ++i)
  {
    nPos = sTxt.lastIndexOf(aOpen[i], nCarPos - 1);
    if (nPos > nBrackPos)
      nBrackPos = nPos;
  }
  if (nBrackPos > -1)
    AkelPad.SetSel(nBrackPos, nBrackPos);
}

else if ((sAction == "r") && (nCarPos < nLastChar - 1))
{
  nBrackPos = nLastChar;
  for (i = 0; i < aClose.length; ++i)
  {
    nPos = sTxt.indexOf(aClose[i], nCarPos + 1);
    if ((nPos > -1) && (nPos < nBrackPos))
      nBrackPos = nPos;
  }
  if (nBrackPos < nLastChar)
    AkelPad.SetSel(nBrackPos, nBrackPos);
}

else if (sAction == "L")
{
  nBrack = ArraySearch(aOpen, sCarChar);

  if (nBrack < 0)
  {
    nBrackPos = -1;
    for (i = 0; i < aOpen.length; ++i)
    {
      nPos = sTxt.lastIndexOf(aOpen[i], nCarPos - 1);
      if (nPos > nBrackPos)
      {
        nBrackPos = nPos;
        nBrack    = i;
      }
    }
    if (nBrackPos > -1)
      nBegSel = nBrackPos + 1;
  }
  else
  {
    nBegSel = nCarPos;
    bSelAll = true;
  }

  if (nBrack > -1)
  {
    nBrackPos = sTxt.indexOf(aClose[nBrack], nCarPos + bSelAll);
    if (nBrackPos > -1)
    {
      if ((nBrackPos == nCarPos) && (! bSelAll))
      {
        --nBegSel;
        bSelAll = true;
      }
      nEndSel = (bSelAll) ? (nBrackPos + 1) : (nBrackPos);
      AkelPad.SetSel(nEndSel, nBegSel);
    }
  }
}

else if ((sAction == "R") && (nCarPos > 0))
{
  nBrack = ArraySearch(aClose, sCarChar);

  if (nBrack < 0)
  {
    nBrackPos = nLastChar;
    for (i = 0; i < aClose.length; ++i)
    {
      nPos = sTxt.indexOf(aClose[i], nCarPos + 1);
      if ((nPos > -1) && (nPos < nBrackPos))
      {
        nBrackPos = nPos;
        nBrack    = i;
      }
    }
    if (nBrackPos < nLastChar)
      nBegSel = nBrackPos;
  }
  else
  {
    nBegSel = nCarPos + 1;
    bSelAll = true;
  }

  if (nBrack > -1)
  {
    nBrackPos = sTxt.lastIndexOf(aOpen[nBrack], nCarPos - bSelAll);
    if (nBrackPos > -1)
    {
      if ((nBrackPos == nCarPos) && (! bSelAll))
      {
        ++nBegSel;
        bSelAll = true;
      }
      nEndSel = (bSelAll) ? (nBrackPos) : (nBrackPos + 1);
      AkelPad.SetSel(nEndSel, nBegSel);
    }
  }
}

function ArraySearch(aArray, sChar)
{
  var nPos = -1;
  var i;

  for (i = 0; i < aArray.length; ++i)
  {
    if (aArray[i] == sChar)
    {
      nPos = i;
      break;
    }
  }
  return nPos;
}

function GetOffset(hWnd, nFlag)
{
  var nOffset = -1;
  var lpIndex;

  if (lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/))
  {
    AkelPad.SystemFunction().Call("User32::SendMessage" + _TCHAR, hWnd, 3130 /*AEM_GETINDEX*/, nFlag, lpIndex);
    nOffset = AkelPad.SystemFunction().Call("User32::SendMessage" + _TCHAR, hWnd, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
    AkelPad.MemFree(lpIndex);
  }
  return nOffset;
}

Last edited by KDJ on Sat Dec 20, 2014 6:32 pm, edited 3 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

toggleComments.js <download | development version>

Adds/removes comments.

Sorry, you have been blocked
You are unable to access sourceforge.net

Why have I been blocked?
This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?
You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.


Alternative download: Infocatcher.zip (all in one).
Last edited by Infocatcher on Sat Oct 01, 2022 7:39 pm, edited 20 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Some my old (and not much :)) scripts... Entire list here: akelpad_scripts.html + github.com/Infocatcher/AkelPad_scripts
Note: some scripts are in beta stage...

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/punctuationFixer.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/punctuationFixer.js

// (c) Infocatcher 2008-2009, 2014
// version 0.0.3.1 - 2014-10-18

//== Settings
var fixerDash = "–";
var fixerForceUpperCase = true;
// Use
// Call("Scripts::Main", 1, "punctuationFixer.js", "-ignorecase", 0)
// to override this setting
var fixerCommas = ["«", "»"]; // var fixerCommas = null;
var fixerSaveSelPos = true;
//== End of settings

if(WScript.Arguments.length && WScript.Arguments(0) == "-ignorecase")
	fixerForceUpperCase = false;

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

function PunctuationFixer(dash, forceUpper, commas) {
	this.dash = dash || "-";
	this.forceUpper = forceUpper;
	this.convCommas = commas instanceof Array;
	if(this.convCommas) {
		this.openComma = commas[0];
		this.closeComma = commas[1];
	}
}
PunctuationFixer.prototype = {
	notConv: [],
	subst: "",
	init: function() { // Get random string for replacing exclusions
		function rnd() {
			return Math.random().toString().substr(2);
		}
		this.subst = "_" + rnd() + rnd() + "_";
	},
	getSubst: function(n) {
		return this.subst + n + "_";
	},
	convert: function(txt) {
		if(!txt)
			return "";
		this.init();

		var _this = this;

		//== Exclusions:
		var excCnt = -1;
		var subst;
		// URLs like http://example.com/
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/[a-z]+:\/\/+([^\/\\.\s'"<>]+[.\/])+[^\/\\.\s'"<>]+/ig,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[0]);
				return subst;
			}
		);
		// Time "10:43:01"
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/(^|\D)([0-2]?\d:[0-6]?\d(:[0-6]?\d)?)(\D|$)/mg,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[2]);
				return a[1] + subst + a[4];
			}
		);
		// Dates "19.03.2009"
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/(^|\D)([0-3]?\d\.[0-1]\d\.\d\d(\d\d)?|\d\d(\d\d)?\.[0-1]\d\.[0-3]?\d)(\D|$)/mg,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[2]);
				return a[1] + subst + a[5];
			}
		);
		// Numbers like "10.9" or "10,9"
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/(^|[^\d.,])(\d+[.,]\d+)([^\d.,]|$)/g,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[2]);
				return a[1] + subst + a[3];
			}
		);
		// Smileys like ":)"
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/[ \t]*(:-?[D\(\)\\\/][\(\)]{0,2})[\(\)]*[ \t]*/g,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(" " + a[1] + " ");
				return subst;
			}
		);
		// "->", "=>", "<=>"
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/<?[-=]+>/g,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[0]);
				return subst;
			}
		);
		// Acronyms
		this.notConv[++excCnt] = [], subst = this.getSubst(excCnt);
		txt = txt.replace(
			/([^а-яёa-z]([а-яёa-z]\.[ \t]*[а-яёa-z]\.|[а-яёa-z]{2}\.))/g,
			function() {
				var a = arguments;
				_this.notConv[excCnt].push(a[1].replace(/[ \t]+/, " "));
				return subst;
			}
		);
		//== End of exclusions

		// Del spaces:
		txt = txt.replace(/(\S)([ \t])[ \t]+/g, "$1$2"); // "\t  " -> "\t", " \t\t" -> " "

		// Fix punctuation:
		txt = txt
			.replace(/((\) ?){1,3})(\) ?)*/g, "$1 ")   // ")))))" -> ")))"
			.replace(/[\t ]*([.?!])([^"])/g, "$1 $2") // "  !  !  !  " -> "! ! ! "
			.replace(/[\t ]*([:,;])[\t ]*/g, "$1 ") // " , " -> ", "
			.replace(/([,;:]) ?([,;:] ?)+/g, "$1 ")    // ",, ,, " -> ", "
			.replace(
				/(([.?!] *){1,3})([.?!] *)*(.|$)/mg, // "! !! ! " -> "!!! "
				function($0, $1, $2, $3, $4) {
					var noSp = $3 && /\S$/.test($3) && $4 == '"';
					return $1.replace(/\s+/g, "") + (noSp ? "" : " ") + $4;
				}
			)
			.replace(/([\(\{\[<])[\t ]+/, "$1")
			.replace(/[\t ]+([\)\}\]>])/, "$1")
			.replace(/[\t ]*([+=])[\t ]*/g, " $1 ");

		// Fix brackets:
		txt = txt
			.replace(/(\S)[\t ]*\([\t ]*/g, "$1 (")  // text(text -> text (text
			.replace(/[\t ]*\)[\t ]*([^.!?:;,()])/g, ") $1"); // text)text -> text) text

		// Fix lower case letters:
		if(this.forceUpper) { // end. begin -> end. Begin
			txt = txt.replace(
				/(^|[^.][.?!] )([а-яёa-z])/mg,
				function($0, $1, $2) { return $1 + $2.toUpperCase(); }
			);
		}

		// Fix dashes:
		txt = txt // " -", "- " -> " - "
			.replace(/"[\t ]*-[\t ]*/g, "\" - ") // text"-text -> text" - text
			.replace(/([^\s-])[\t ]*-[\t ]*"/g, "$1 - \"") // text-"text -> text - "text
			.replace(/([^\s-])[\t ]*-\([\t ]*/g, "$1 - (") // text-(text -> text - (text
			.replace(/([^\s-])[\t ]*\)-[\t ]*/g, "$1) - ") // text)-text -> text) - text
			.replace(/([^\s-])[\t ]*-[\t ]+/g, "$1 - ")    // text- text -> text - text
			.replace(/([^\s-])[\t ]+-[\t ]*/g, "$1 - ")    // text -text -> text - text
			.replace(/^([\t ]*)-{1,3}[\t ]*/mg, "$1- ") // \n-text -> \n- text
			.replace(/([^\s-])[\t ]*---?[\t ]*/g, "$1 - ")   // text--text -> text - text
			.replace(/ - /g, " " + this.dash + " ");

		// Fix commas:
		if(this.convCommas) {
			txt = txt
				.replace(/^[\t ]*"[\t ]*/mg, this.openComma)  // \n" -> \n«
				.replace(/[\t ]*"[\t ]*$/mg, this.closeComma) // "\n -> »\n
				.replace(/([.?!])"(\s)/g, "$1" + this.closeComma + "$2") // 'text!" ' -> 'text!» '
				.replace(/([а-яёa-z])"([-+\s.?!,;:\)\}\]\>]|$)/img, "$1" + this.closeComma + "$2") // text". -> text».
				.replace(/[\t ]*"[\t ]*([-+.?!,;:\)\}\]\>]|$)/mg, this.closeComma + "$1")          // ' " .' -> '».'
				.replace(/(^|[\s\(\{\[<])"[\t ]*/mg, "$1" + this.openComma)
				.replace(new RegExp(this.openComma + "[\\t ]+", "g"), this.openComma)
				.replace(new RegExp("[\\t ]+" + this.closeComma, "g"), this.closeComma);
		}

		// Fix dashes (end):
		txt = txt.replace(/- /g, this.dash + " ");

		// Replace exclusions:
		while(excCnt > -1) {
			txt = txt.replace(
				new RegExp(this.subst + excCnt + "_", "g"),
				function() {
					return _this.notConv[excCnt].shift();
				}
			);
			excCnt--;
		}

		// Del spaces:
		txt = txt
			.replace(/(\S)([ \t])[ \t]+/g, "$1$2") // "\t  " -> "\t", " \t\t" -> " "
			.replace(/[ \t]+$/mg, ""); // "text  \n" -> "text\n"

		return txt;
	}
};

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit)) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(lpPoint) {
		setRedraw(hWndEdit, false);
		var selParams = getSelParams();
		AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

		// Get selection or all text and save fullTxt flag:
		var txt = AkelPad.GetSelText();
		var fullTxt = !txt;
		if(fullTxt)
			txt = AkelPad.SetSel(0, -1) || AkelPad.GetSelText();

		var selStart = AkelPad.GetSelStart();
		var err;
		try {
			var fixer = new PunctuationFixer(fixerDash, fixerForceUpperCase, fixerCommas);
			txt = fixer.convert(txt);
			AkelPad.ReplaceSel(txt);
			if(!fixerSaveSelPos || !fullTxt)
				selParams = [selStart, selStart + txt.length];
		}
		catch(e) {
			err = e;
		}

		restoreSelParams(selParams);
		AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
		setRedraw(hWndEdit, true);
		AkelPad.MemFree(lpPoint);

		if(err)
			throw err;
	}
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	if(bRedraw)
		oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getSelParams() {
	return [AkelPad.GetSelStart(), AkelPad.GetSelEnd()];
}
function restoreSelParams(selParams) {
	AkelPad.SetSel(selParams[0], selParams[1]);
}
<download | mirror | development version>

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/colorsConverter.js

// (c) Infocatcher 2010-2011
// version 0.1.2 - 2011-12-20

function _localize(s) {
	var strings = {
		"Color:": {
			ru: "Цвет:"
		},
		"Color from “%S”:": {
			ru: "Цвет из «%S»:"
		},
		"Invalid color format!": {
			ru: "Некорректный формат цвета!"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();

if(hMainWnd)
	convColor(AkelPad.GetSelText());

function convColor(color, forceAsk) {
	if(!color || forceAsk)
		color = askColor(_localize("Color:"), color);
	if(!color)
		return;
	var newColor;
	if(/^\W*#?([0-9a-f]{3}|[0-9a-f]{6})\W*$/i.test(color)) // #aaa or #aaaaaa
		newColor = h2d(RegExp.$1);
	else if(/^\D*(\d{1,3}\D+\d{1,3}\D+\d{1,3})\D*$/.test(color)) // rgb(170, 170, 170)
		newColor = d2h.apply(this, RegExp.$1.split(/\D+/));

	if(!newColor) {
		AkelPad.MessageBox(hMainWnd, _localize("Invalid color format!"), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
		convColor(color, true);
		return;
	}
	newColor = askColor(_localize("Color from “%S”:").replace("%S", color), newColor);
	newColor && convColor(newColor);
}
function askColor(caption, defaultValue) {
	return AkelPad.InputBox(
		hMainWnd, WScript.ScriptName,
		caption,
		defaultValue || ""
	);
}

function hex(n) {
	var h = (typeof n == "number" ? n : parseInt(n, 10)).toString(16);
	if(h.length > 2)
		return null;
	return "00".substr(h.length) + h;
}
function d2h() {
	var i, h, r = [], l = arguments.length;
	var same = /^([0-9a-f])\1$/i;
	var isSame = true;
	for(i = 0; i < l; i++) {
		h = hex(arguments[i]);
		if(!h)
			return null;
		if(isSame && !same.test(h))
			isSame = false;
		r.push(h);
	}
	if(isSame)
		for(i = 0; i < l; i++)
			r[i] = r[i].charAt(0);
	return /* "#" + */ r.join("");
}
function h2d(h) {
	var l = h.length;
	var s = l == 3 ? 1 : 2;
	var i, r = [], h2;
	for(var i = 0; i < l; i += s) {
		h2 = h.substr(i, s);
		if(s == 1)
			h2 += h2;
		r.push(parseInt(h2, 16));
	}
	return r.join(", ");
}
<download | mirror | development version>
Convert color between “#fee” and “rgb(255, 238, 238)” formats.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/copyPath.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/copyPath.js

// (c) Infocatcher 2010, 2014
// version 0.1.0.1 - 2014-07-30

// Usage:
//   -"Copy path to file"                Call("Scripts::Main", 1, "copyPath.js", `"%f"`)
// Or with template:
//   -"Copy path to file"                Call("Scripts::Main", 1, "copyPath.js", `"%f" "<path>/<file>.<ext>"`)
//   -"Copy path to file directory"      Call("Scripts::Main", 1, "copyPath.js", `"%f" "<path>"`)
//   -"Copy file name"                   Call("Scripts::Main", 1, "copyPath.js", `"%f" "<file>.<ext>"`)
//   -"Copy file name without extension" Call("Scripts::Main", 1, "copyPath.js", `"%f" "<file>"`)

var argsCount = WScript.Arguments.length;
var arg = argsCount
	? WScript.Arguments(0)
	: AkelPad.GetEditFile(0);
if(arg) {
	if(argsCount > 1) {
		var path = arg, sep = "", file = "", dot ="", ext = "";
		if(/([\\/])?([^\\/]*)$/.test(path)) {
			sep = RegExp.$1;
			file = RegExp.$2;
			path = path.substring(0, path.length - RegExp.lastMatch.length);
			if(/\.([^.]+)$/.test(file)) {
				dot = ".";
				ext = RegExp.$1;
				file = file.substring(0, file.length - RegExp.lastMatch.length);
			}
		}
		arg = WScript.Arguments(1)
			.replace("<path>", path)
			.replace("/", sep)
			.replace("<file>", file)
			.replace(".", dot)
			.replace("<ext>", ext);
	}
	AkelPad.SetClipboardText(arg);
}
<download | mirror | development version>
Copy path to file in configurable format.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/getLinks.js

// (c) Infocatcher 2009-2011
// version 0.1.7 - 2011-12-20

//===================
// Tries to extract links from any text

// Usage:
//   Call("Scripts::Main", 1, "getLinks.js")
//===================

function _localize(s) {
	var strings = {
		"Links not found!": {
			ru: "Ссылки не найдены!"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd) {
	var links = getLinks();
	if(links.length) {
		AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
		AkelPad.SetSel(0, 0);
		insertNoScroll(links.join("\n"), true);
	}
	else {
		AkelPad.MessageBox(
			hMainWnd,
			_localize("Links not found!"),
			WScript.ScriptName,
			48 /*MB_ICONEXCLAMATION*/
		);
	}
}

function getLinks() {
	// Get selection or all text
	var txt = AkelPad.GetSelText() || getAllText();

	// [url=http://example.com/]...[/url] => http://example.com/
	txt = txt.replace(/\[(\w+)=(['"]?)([^\[\]]+)\2\].*?\[\/\1\]/g, "\t$3\t");

	var links = txt.match(/[a-z]+:\/\/+([^\/\\.\s<>'":*?|&#\(\)\[\]\{\}]+\.)*[^\/\\.\s<>'":*?|&#\(\)\[\]\{\}]+(:\d+)?(\/[^\s"<>]*)?|mailto:[^@\s\\\/:*?"<>|]+@[^@.\s\\\/:*?"<>|&#]+(\.[^@.\s\\\/:*?"<>|&#]+)+|\\{2,}\w+(\\[^\\\/:*?"<>|\s]+)+\\?/ig);
	if(!links)
		return [];

	var linksObj = {};
	var link;
	for(var i = 0, len = links.length; i < len; i++) {
		link = links[i].replace(/[\(\{\[+,]$/, "");

		if(count(link, /\(/g) == 0 && count(link, /\)/g))
			link = link.replace(/\).*$/, "");
		if(count(link, /\[/g) == 0 && count(link, /\]/g))
			link = link.replace(/\].*$/, "");
		if(count(link, /\{/g) == 0 && count(link, /\}/g))
			link = link.replace(/\}.*$/, "");

		linksObj[decodeHTML(link)] = 1;
	}

	links = [];
	for(var h in linksObj)
		links.push(h);

	return links;
}
function count(s, re) {
	var m = s.match(re);
	return m ? m.length : 0;
}
function decodeHTML(s) {
	return s
		.replace(/&/g, "&")
		.replace(/</g, "<")
		.replace(/>/g, ">")
		.replace(/"/g, '"');
}

function getAllText() {
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return "";
	var hWndEdit = AkelPad.GetEditWnd();
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	AkelPad.SetSel(0, -1);
	var str = AkelPad.GetSelText();

	AkelPad.SetSel(ss, se);
	columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	AkelPad.MemFree(lpPoint);
	setRedraw(hWndEdit, true);
	return str;
}
function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	var hWndEdit = AkelPad.GetEditWnd();
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | mirror | development version>
Tries to extract links from any text.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926
// http://infocatcher.ucoz.net/js/akelpad_scripts/insertEval.js

// (c) Infocatcher 2010-2011
// version 0.1.9 - 2011-12-20

//===================
// Special expressions:
// =someExpression() => "someExpression() = result"

// Usage:
//   Call("Scripts::Main", 1, "insertEval.js")
//===================

function _localize(s) {
	var strings = {
		"Expression:": {
			ru: "Выражение:"
		},
		"Result:": {
			ru: "Результат:"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

var document = new ActiveXObject("htmlfile");
// Initialize document (we can't use something like document.documentElement without this):
document.open();
document.close();
var window = document.parentWindow;

var utils = {
	alert: function(msg, icon, addTitle) {
		AkelPad.MessageBox(hMainWnd, String(msg), dialogTitle + (addTitle ? " :: " + addTitle : ""), icon || 48 /*MB_ICONEXCLAMATION*/);
	},
	prompt: function(msg, defaultVel) {
		var ret = AkelPad.InputBox(hMainWnd, dialogTitle, String(msg), defaultVel);
		return ret == undefined ? null : ret;
	},
	confirm: function(msg) {
		return AkelPad.MessageBox(hMainWnd, String(msg), dialogTitle, 33 /*MB_OKCANCEL|MB_ICONQUESTION*/) == 1 /*IDOK*/;
	},
	setTimeout: function(func, delay) {
		return window.setTimeout(func, delay);
	},
	setInterval: function(func, delay) {
		return window.setInterval(func, delay);
	},
	document: {
		open: function() {},
		write: function(s) {
			utils.alert(s, null, "document.write");
		},
		writeln: function(s) {
			utils.alert(s, null, "document.writeln");
		},
		close: function() {}
	},
	print: function(s) {
		utils.alert(s, null, "print");
	},

	hex: function(n) {
		n = Number(n);
		return (n < 0 ? "-" : "") + "0x" + Math.abs(n).toString(16);
	},
	oct: function(n) {
		return "0" + Number(n).toString(8);
	},
	bin: function(n) {
		return "b" + Number(n).toString(2);
	},
	p: function(n) {
		return String(n).replace(/(\d)(?=(?:\d{3})+(?:\D|$))/g, "$1 ");
	},

	append: function(s) {
		var sep = "\n";
		s = String(s);

		var hWndEdit = AkelPad.GetEditWnd();
		setRedraw(hWndEdit, false);

		var se = AkelPad.GetSelEnd();
		AkelPad.SetSel(se, se);
		AkelPad.ReplaceSel(sep + s);
		se += sep.length;
		AkelPad.SetSel(se, se + s.length);

		setRedraw(hWndEdit, true);
	},

	_logMsgs: [],
	_log: function() {
		for(var i = 0, l = arguments.length; i < l; i++)
			this._logMsgs.push(arguments[i]);
	}
};
utils.window = utils;

function calc(expr, forceAsk) {
	if(!expr || forceAsk)
		expr = utils.prompt(_localize("Expression:"), expr);
	if(!expr)
		return;
	if(/^\s*=\s*/.test(expr)) {
		expr = expr.substr(RegExp.lastMatch.length);
		var extOutput = true;
	}
	var isHex = /^0x[\da-f]/i.test(expr);
	var res;
	try {
		with(Math) with(WScript) with(utils) with(AkelPad)
			res = eval(expr);
	}
	catch(e) {
		utils.alert(e.name + "\n" + e.message, 16 /*MB_ICONERROR*/);
		calc(expr, true);
		return;
	}
	if(isHex && typeof res == "number")
		res = utils.hex(res);
	else
		res = String(res);
	var newExpr = utils.prompt(_localize("Result:"), res);
	if(!newExpr)
		return; // Cancel
	if(newExpr != res) {
		calc(newExpr);
		return;
	}
	if(extOutput)
		res = expr + " = " + res;
	if(res == AkelPad.GetSelText())
		return;
	if(!AkelPad.GetEditReadOnly(AkelPad.GetEditWnd()))
		AkelPad.ReplaceSel(res);
}

if(hMainWnd) {
	calc(AkelPad.GetSelText());
	if(utils._logMsgs.length) {
		AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
		AkelPad.SetSel(0, 0);
		insertNoScroll(utils._logMsgs.join("\n"), true);
	}
}

function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	var hWndEdit = AkelPad.GetEditWnd();
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	AkelPad.ReplaceSel(str);
	AkelPad.SetSel(0, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | mirror | development version>
Script like built-in Calculator.js.

Code: Select all

// (c) Infocatcher 2009
// version 0.2.5 - 2010-06-21

// Usage:
// Call("Scripts::Main", 1, "newFileTemplate.js", "html", 0)
//   - use template for "html"
// Call("Scripts::Main", 1, "newFileTemplate.js", "", 0)
//   - use template for extension of current file
// Call("Scripts::Main", 1, "newFileTemplate.js", "?", 0)
//   - ask user about extension
// Call("Scripts::Main", 1, "newFileTemplate.js", `"%f"`, 0)
//   - use active file (e.g. in ContextMenu plugin)
//   - or `"c:\\path\to\my\file\myFile.ext"` instead of `"%f"`

// Settings begin
var templatesDir = "%a\\AkelFiles\\Plugs\\Scripts\\Params\\" + getScriptDirName();
// For "script.js" getScriptDirName() return "script".
var templateFileName = "template";
var selFlag = "%|";
var selTextFlag = "%s";
// Settings end

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

var locale = {
	lng: null,
	strings: {
		extRequired: {
			ru: "Расширение нового файла: ",
			en: "Extension of new file: "
		}
	},
	getStr: function(name) {
		if(!this.lng) {
			var nLangID = oSys.Call("kernel32::GetUserDefaultLangID");
			nLangID = nLangID & 0x3ff; //PRIMARYLANGID
			switch(nLangID) {
				case 0x19: this.lng = "ru"; break;
				default:   this.lng = "en";
			}
		}
		return this.strings[name][this.lng];
	}
};

function TemplateMaker(tDir, tFileName, selFlag, selTextFlag) {
	this.tDir = tDir;
	this.tFileName = tFileName;
	this.selFlag = selFlag;
	this.selTextFlag = selTextFlag;
}
TemplateMaker.prototype = {
	initTemplate: function() {
		this.ext = this.getExt();
		return this.getTemplate();
	},
	getExt: function() {
		var ext;
		if(WScript.Arguments.length) {
			ext = WScript.Arguments(0);
			if(ext == "?")
				return this.ackUserExt();
			else if(ext && /\\.*\.([^.]+)$/.test(ext)) { // ...\filename.ext
				this.tPath = ext;
				ext = RegExp.$1;
				this.precessTemplate = false;
			}
		}
		ext = ext || this.getCurrentExt() || this.ackUserExt();
		return ext && ext.toLowerCase();
	},
	ackUserExt: function() {
		var ext = AkelPad.InputBox(
			hMainWnd, WScript.ScriptName,
			locale.getStr("extRequired"),
			this.getCurrentExt() || regVal("lastExt") || ""
		);
		return ext && ext.toLowerCase();
	},
	getCurrentExt: function() {
		if(!this._getCurrentExt) {
			var cFile = AkelPad.GetEditFile(0);
			this._getCurrentExt = cFile && /\.([^.]+)$/i.test(cFile) && RegExp.$1;
		}
		return this._getCurrentExt;
	},
	tPath: null,
	tmpl: "",
	precessTemplate: true,
	selParams: null,
	getTemplate: function() {
		if(!this.ext)
			return false;
		var pFile = this.tPath
			|| this.tDir
				.replace("%a", AkelPad.GetAkelDir())
				.replace(/\\?$/, "\\")
				+ this.tFileName + "." + this.ext;
		if(!this.fileExist(pFile))
			return true;
		this.tmpl = AkelPad.ReadFile(pFile)
			.replace(/\r\n/g, "\n"); // For AkelPad 4.4.4
		if(!this.precessTemplate)
			return true;
		if(this.tmpl.indexOf(this.selTextFlag) != -1)
			this.tmpl = this.tmpl.replace(this.selTextFlag, AkelPad.GetSelText());
		var selStart = this.tmpl.indexOf(this.selFlag);
		this.delFlag(selStart);
		var selEnd = this.tmpl.lastIndexOf(this.selFlag);
		this.delFlag(selEnd);
		if(selStart != -1 && selEnd == -1)
			selEnd = selStart;
		this.selParams = selStart != -1
			? [selStart, selEnd]
			: null;
		return true;
	},
	fileExist: function(fName) {
		return new ActiveXObject("Scripting.FileSystemObject")
			.FileExists(fName);
	},
	delFlag: function(pos) {
		if(pos != -1)
			this.tmpl = this.tmpl.substring(0, pos)
				+ this.tmpl.substring(pos + this.selFlag.length, this.tmpl.length);
	},
	insTemplate: function() {
		AkelPad.ReplaceSel(this.tmpl);
		this.formatTemplate();
		regVal("lastExt", this.ext);
	},
	formatTemplate: function() {
		var ext = this.ext;
		if(ext) {
			//AkelPad.Call("HighLight::Main", 1, ext);
			//AkelPad.Call("AutoComplete::Main", 1, ext);
			AkelPad.Call("Coder::Settings", 1, ext);
		}
		var sp = this.selParams;
		if(sp)
			AkelPad.SetSel(sp[0], sp[1]);
		else
			AkelPad.SetSel(0, 0);
	}
};

if(hMainWnd) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(lpPoint) {
		var tm = new TemplateMaker(templatesDir, templateFileName, selFlag, selTextFlag);
		if(tm.initTemplate()) {
			AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
			var hWndEditNew = AkelPad.GetEditWnd();
			setRedraw(hWndEditNew, false);
			AkelPad.SendMessage(hWndEditNew, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

			tm.insTemplate();

			AkelPad.SendMessage(hWndEditNew, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
			setRedraw(hWndEditNew, true);
			AkelPad.MemFree(lpPoint);
		}
	}
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	if(bRedraw)
		oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getScriptDirName() {
	return WScript.ScriptName.replace(/\.js$/i, "");
}
function regVal(name, val) {
	name = "HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\newFileTemplate\\" + name;
	var ws = new ActiveXObject("WScript.shell");
	if(typeof val != "undefined")
		return ws.RegWrite(name, val, "REG_SZ");
	try { return ws.RegRead(name); }
	catch(e) { return ""; }
}
<download | mirror | development version>

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9926#p9926

// (c) Infocatcher 2009-2011
// version 0.3.2 - 2011-12-20

// Works with ShowMenuEx.js http://akelpad.sourceforge.net/forum/viewtopic.php?p=8153#p8153

// Usage:
// Call("Scripts::Main", 1, "newFileTemplate.js", "html")
//   - use template for "html"
// Call("Scripts::Main", 1, "newFileTemplate.js")
//   - use template for extension of current file
// Call("Scripts::Main", 1, "newFileTemplate.js", "?")
//   - ask user about extension
// Call("Scripts::Main", 1, "newFileTemplate.js", `"%f"`)
//   - use active file (e.g. in ContextMenu plugin)
//   - or `"c:\\path\to\my\file\myFile.ext"` instead of `"%f"`
// Call("Scripts::Main", 1, "newFileTemplate.js", "?edit")
//   - edit template
// Call("Scripts::Main", 1, "newFileTemplate.js", "?edit:html")
//   - edit template for "html"

//== Settings begin
var templatesDir = "%a\\AkelFiles\\Plugs\\Scripts\\Params\\" + getScriptDirName();
// For "script.js" getScriptDirName() return "script".
var templateFileName = "template";
var selFlag = "%|";
var selTextFlag = "%s";
//== Settings end

function _localize(s) {
	var strings = {
		"Extension of new file:": {
			ru: "Расширение нового файла:"
		},
		"Edit template for extension:": {
			ru: "Редактировать шаблон для расширения:"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var argAsk = "?";
var argEdit = "?edit";

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var wsh = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

function TemplateMaker(tDir, tFileName, selFlag, selTextFlag, argAsk, argEdit) {
	this.tDir = tDir;
	this.tFileName = tFileName;
	this.selFlag = selFlag;
	this.selTextFlag = selTextFlag;
	this.argAsk = argAsk;
	this.argEdit = argEdit;
}
TemplateMaker.prototype = {
	initTemplate: function() {
		this.ext = this.getExt();
		return this.getTemplate();
	},
	getExt: function() {
		var ext;
		if(WScript.Arguments.length) {
			ext = this.parseSpecialExts(WScript.Arguments(0));
			return ext && ext.toLowerCase();
		}
		ext = ext || this.getCurrentExt() || this.askUserExt();
		return ext && ext.toLowerCase();
	},
	parseSpecialExts: function(ext, retExt) {
		if(ext == this.argAsk)
			return this.askUserExtInput();
		else if(ext && ext.indexOf(this.argEdit) == 0) {
			this.createTemplate(ext.substr(this.argEdit.length + 1));
			return "";
		}
		else if(ext && /\\.*\.([^.]+)$/.test(ext)) { // ...\filename.ext
			this.tPath = ext;
			ext = RegExp.$1;
			this.precessTemplate = false;
			return ext && ext.toLowerCase();
		}
		return retExt ? ext : "";
	},
	askUserExt: function() {
		if(this.asked)
			return "";
		var ext;
		var showMenuPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Plugs\\Scripts\\ShowMenuEx.js";
		if(fso.FileExists(showMenuPath)) {
			eval(AkelPad.ReadFile(showMenuPath));
			ext = getSelectedMenuItem(POS_CURSOR, "INI", 0);
			ext = this.parseSpecialExts(ext, true);
		}
		else {
			ext = this.askUserExtInput();
		}
		return ext && ext.toLowerCase();
	},
	asked: false,
	askUserExtInput: function(newFlag) {
		this.asked = true;
		var ext = AkelPad.InputBox(
			hMainWnd, WScript.ScriptName,
			_localize(
				newFlag
					? "Edit template for extension:"
					: "Extension of new file:"
			),
			this.getCurrentExt() || regVal("lastExt") || ""
		);
		return ext && ext.toLowerCase();
	},
	getCurrentExt: function() {
		if(!this._getCurrentExt) {
			var cFile = AkelPad.GetEditFile(0);
			this._getCurrentExt = cFile && /\.([^.]+)$/i.test(cFile) && RegExp.$1;
		}
		return this._getCurrentExt;
	},
	createTemplate: function(ext) {
		ext = ext || this.askUserExtInput(true /* newFlag */);
		if(!ext)
			return;
		var path = this.getTemplatePath(ext);

		var dir = fso.GetParentFolderName(path);
		if(!fso.FolderExists(dir))
			fso.CreateFolder(dir);

		AkelPad.OpenFile(path);
	},
	tPath: "",
	tmpl: "",
	precessTemplate: true,
	selParams: null,
	getTemplate: function() {
		if(!this.ext)
			return false;
		var pFile = this.tPath || this.getTemplatePath(this.ext);
		if(!fso.FileExists(pFile))
			return true;
		this.tmpl = AkelPad.ReadFile(pFile)
			.replace(/\r\n/g, "\n"); // For AkelPad 4.4.4+
		if(!this.precessTemplate)
			return true;
		if(this.tmpl.indexOf(this.selTextFlag) != -1)
			this.tmpl = this.tmpl.replace(this.selTextFlag, AkelPad.GetSelText());
		var selStart = this.tmpl.indexOf(this.selFlag);
		this.delFlag(selStart);
		var selEnd = this.tmpl.lastIndexOf(this.selFlag);
		this.delFlag(selEnd);
		if(selStart != -1 && selEnd == -1)
			selEnd = selStart;
		this.selParams = selStart != -1
			? [selStart, selEnd]
			: null;
		return true;
	},
	getTemplatePath: function(ext) {
		return wsh.ExpandEnvironmentStrings(
			this.tDir
				.replace(/^%a/, AkelPad.GetAkelDir())
				.replace(/\\$/, "")
				+ "\\" + this.tFileName + "." + ext
		);
	},
	delFlag: function(pos) {
		if(pos != -1)
			this.tmpl = this.tmpl.substring(0, pos)
				+ this.tmpl.substring(pos + this.selFlag.length, this.tmpl.length);
	},
	insTemplate: function() {
		AkelPad.ReplaceSel(this.tmpl);
		this.formatTemplate();
		regVal("lastExt", this.ext);
	},
	formatTemplate: function() {
		var ext = this.ext;
		if (ext && AkelPad.IsPluginRunning("Coder::HighLight") == true) {
			AkelPad.Call("Coder::Settings", 1, ext);
		}
		var sp = this.selParams;
		if(sp)
			AkelPad.SetSel(sp[0], sp[1]);
		else
			AkelPad.SetSel(0, 0);
	}
};

if(hMainWnd) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(lpPoint) {
		var tm = new TemplateMaker(templatesDir, templateFileName, selFlag, selTextFlag, argAsk, argEdit);
		if(tm.initTemplate()) {
			AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
			var hWndEditNew = AkelPad.GetEditWnd();
			setRedraw(hWndEditNew, false);
			AkelPad.SendMessage(hWndEditNew, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

			tm.insTemplate();

			AkelPad.SendMessage(hWndEditNew, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
			setRedraw(hWndEditNew, true);
			AkelPad.MemFree(lpPoint);
		}
	}
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getScriptDirName() {
	return WScript.ScriptName.replace(/\.js$/i, "");
}
function regVal(name, val) {
	name = "HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\newFileTemplate\\" + name;
	if(arguments.length == 2)
		return wsh.RegWrite(name, val, "REG_SZ");
	try { return wsh.RegRead(name); }
	catch(e) { return ""; }
}
<download | mirror | development version>
Create new file from template.
Last edited by Infocatcher on Sat Aug 15, 2015 9:00 pm, edited 14 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#p9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/openFileIn.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/openFileIn.js

// (c) Infocatcher 2010-2021
// Version: 0.2.0.1 - 2021-08-15
// Author: Infocatcher

//===================
//// Open file in other application

// Usage (see "var appsData = { ... }" for appID):
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%f"')
// In "URL menu":
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%u"')
// Disable mappings:
//   Call("Scripts::Main", 1, "openFileIn.js", '"appID" "%f" -mappings=false')
// Trick to not open archive-like files in Total Commander:
//   Call("Scripts::Main", 1, "openFileIn.js", '"Total Commander" "%f\:"')
//===================

//== Settings begin
// You can use openFileIn-options.js file to override or tweak settings
// Override:
//   var appsData = { ... };
// Tweak:
//   appsData["App"] = { ... };       - add application
//   appsData["App"].paths = [ ... ]  - change paths
var mappings = {
	// Only for applications marked as 'isBrowser: true'
	// Example:
	// "D:\\Site\\": "http://localhost/",
	// "D:\\AnotherSite\\": "http://example.com/"
};
var appsData = {
	// Example:
	//	"appID": {
	//		paths: [
	//			"c:\\path\\to\\app.exe",
	//			"%EnvVar%\\another\\path\\to\\app.exe",
	//			// Special: %AkelDir% - path to AkelPad directory (e.g. C:\Soft\AkelPad),
	//			//          %AkelDrive% - path to AkelPad drive (e.g. C:)
	//			"<HKCU\\path\\from\\registry>app.exe",
	//			"?x64?...\\app64.exe", // Check only on x64 system
	//			"?x86?...\\app32.exe"  // Check only on x86 system
	//		],
	//		args: "-file:%f -line:%l",
	//		isBrowser: true
	//	}
	"Total Commander": {
		paths: [
			"%COMMANDER_EXE%",
			"%COMMANDER_PATH%\\TOTALCMD.EXE",
			"?x64?%COMMANDER_PATH%\\TOTALCMD64.EXE",
			"%AkelDir%\\..\\totalcmd\\TOTALCMD.EXE",
			"%AkelDir%\\..\\Total Commander\\TOTALCMD.EXE",
			"%AkelDir%\\..\\..\\TOTALCMD.EXE",
			"%__portable__%\\totalcmd\\TOTALCMD.EXE",
			"?x64?<HKCU\\Software\\Ghisler\\Total Commander\\InstallDir>\\TOTALCMD64.EXE",
			"<HKCU\\Software\\Ghisler\\Total Commander\\InstallDir>\\TOTALCMD.EXE",
			"%ProgramFiles%\\totalcmd\\TOTALCMD.EXE",
			"%ProgramFiles%\\Total Commander\\TOTALCMD.EXE"
		],
		args: "/O /S /T %f"
	},

	"Notepad": {
		paths: [
			"%SystemRoot%\\notepad.exe"
		],
		args: "%f"
	},
	"Notepad++": {
		paths: [
			"%COMMANDER_PATH%\\..\\Notepad++\\notepad++.exe",
			"%AkelDir%\\..\\Notepad++\\notepad++.exe",
			"%__portable__%\\Notepad++\\notepad++.exe",
			"%ProgramFiles%\\Notepad++\\notepad++.exe"
		],
		args: "%f -n%l"
	},
	"PSPad": {
		paths: [
			"%COMMANDER_PATH%\\..\\PSPad\\PSPad.exe",
			"%COMMANDER_PATH%\\..\\PSPad editor\\PSPad.exe",
			"%AkelDir%\\..\\PSPad\\PSPad.exe",
			"%AkelDir%\\..\\PSPad editor\\PSPad.exe",
			"%ProgramFiles%\\PSPad\\PSPad.exe",
			"%ProgramFiles%\\PSPad editor\\PSPad.exe"
		],
		args: "%f"
	},
	"EmEditor": {
		paths: [
			"%COMMANDER_PATH%\\..\\EmEditor\\EmEditor.exe",
			"%AkelDir%\\..\\EmEditor\\EmEditor.exe",
			"%ProgramFiles%\\EmEditor\\EmEditor.exe"
		],
		args: "%f"
	},

	"Internet Explorer": {
		paths: [
			"%ProgramFiles%\\Internet Explorer\\iexplore.exe"
		],
		args: "%f",
		isBrowser: true
	},
	"Firefox": {
		paths: [
			"<HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe\\>",
			"%ProgramFiles%\\Mozilla Firefox\\firefox.exe",
			"%COMMANDER_PATH%\\..\\FirefoxPortable\\FirefoxPortable.exe",
			"%AkelDir%\\..\\FirefoxPortable\\FirefoxPortable.exe"
		],
		args: "%f",
		isBrowser: true
	},
	"Opera": {
		paths: [
			"<HKCU\\Software\\Opera Software\\Last Install Path>\\opera.exe",
			"%ProgramFiles%\\Opera\\opera.exe",
			"%COMMANDER_PATH%\\..\\OperaUSB\\opera.exe",
			"%COMMANDER_PATH%\\..\\Opera\\opera.exe",
			"%AkelDir%\\..\\OperaUSB\\opera.exe",
			"%AkelDir%\\..\\Opera\\opera.exe"
		],
		args: "%f",
		isBrowser: true
	},
	"Vivaldi": {
		paths: [
			"<HKCU\\Software\\Vivaldi\\DestinationFolder>\\Application\\vivaldi.exe",
			"%ProgramFiles%\\Vivaldi\\Application\\vivaldi.exe",
			"%LocalAppData%\\Vivaldi\\Application\\vivaldi.exe",
			"%COMMANDER_PATH%\\..\\Vivaldi\\Application\\vivaldi.exe",
			"%AkelDir%\\..\\Vivaldi\\Application\\vivaldi.exe"
		],
		args: "%f",
		isBrowser: true
	},
	"Google Chrome": {
		paths: [
			"<HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\\>",
			"<HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\\>",
			"%LocalAppData%\\Google\\Chrome\\Application\\chrome.exe",
			"%UserProfile%\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe",
			"%UserProfile%\\Local Settings\\Application Data\\Bromium\\Application\\chrome.exe",
			"%COMMANDER_PATH%\\..\\GoogleChromePortable\\GoogleChromePortable.exe",
			"%AkelDir%\\..\\GoogleChromePortable\\GoogleChromePortable.exe"
		],
		args: "%f",
		isBrowser: true
	},
	"Safari": {
		paths: [
			"%ProgramFiles%\\Safari\\Safari.exe",
			"%COMMANDER_PATH%\\..\\SafariPortable\\SafariPortable.exe",
			"%AkelDir%\\..\\SafariPortable\\SafariPortable.exe"
		],
		args: "%f",
		isBrowser: true
	}
};
//== Settings end

var fso = new ActiveXObject("Scripting.FileSystemObject");
var optionsPath = WScript.ScriptFullName.replace(/(\.[^.]+)?$/, "-options$&");
if(fso.FileExists(optionsPath))
	AkelPad.Include(".." + optionsPath.replace(/^.*(\\|\/)/, "$1"));

var allowMappings = AkelPad.GetArgValue("mappings", true);

var wsh = new ActiveXObject("WScript.Shell");
var akelDir = AkelPad.GetAkelDir();

if(WScript.Arguments.length >= 2) {
	var app = WScript.Arguments(0);
	var file = WScript.Arguments(1);
	if(app in appsData) {
		var appData = appsData[app];
		var path = getPath(appData.paths);
		if(path) {
			if(appData.isBrowser) {
				for(var p in mappings) {
					var pl = p.length;
					if(file.substr(0, pl) == p) {
						file = mappings[p] + file.substr(pl).replace(/\\/g, "/");
						break;
					}
				}
			}
			var args = appData.args;
			if(file) {
				if(/%f/.test(args))
					args = args.replace(/%f/g, '"' + file + '"');
				if(/%l/.test(args))
					args = args.replace(/%l/g, getLine());
			}
			else {
				args = args
					.replace(/\s*\S*%f\S*\s*/g, " ")
					.replace(/\s*\S*%l\S*\s*/g, " ");
			}
			var cmdLine = ('"' + path + '" ' + args).replace(/\s+$/, "");
			try {
				wsh.Exec(cmdLine);
			}
			catch(e) {
				// Windows Vista/7 and admin rights required
				//WScript.Echo(e.name + "\n" + e.message);
				new ActiveXObject("Shell.Application").ShellExecute(path, args, "" /*directory*/, "runas");
			}
		}
		else {
			warn(app + " not found!\n\n" + appData.paths.join("\n"));
		}
	}
	else {
		warn("Application with \"" + app + "\" id not found in the database!");
	}
}
else {
	warn('Wrong arguments!\nUsage:\nCall("Scripts::Main", 1, "' + WScript.ScriptName + '", \'"appID" "%f"\')');
}
function getPath(paths) {
	for(var i = 0, l = paths.length; i < l; ++i) {
		var path = paths[i];
		if(path.charAt(0) == "?") {
			if(path.substr(0, 5) != (_X64 ? "?x64?" : "?x86?"))
				continue;
			path = path.substr(5);
		}
		var path = expandVariables(paths[i]);
		//WScript.Echo(paths[i] + "\n=>\n" + path);
		if(fso.FileExists(path))
			return path;
	}
	return "";
}
function expandVariables(s) {
	return expandEnvironmentVariables(expandRegistryVariables(s));
}
function expandEnvironmentVariables(s) {
	if(s.substr(0, 5) == "%Akel") {
		s = s
			.replace(/^%AkelDir%/, akelDir)
			.replace(/^%AkelDrive%/, fso.GetDriveName(akelDir));
	}
	return wsh.ExpandEnvironmentStrings(s);
}
function expandRegistryVariables(s) { // <HKCU\Software\Foo\installPath>\foo.exe
	return s.replace(/<(.+?)>/g, function(s, path) {
		var val = getRegistryValue(path);
		if(val)
			return val;
		return s;
	});
}
function getRegistryValue(path) {
	try {
		return wsh.RegRead(path);
	}
	catch(e) {
	}
	return "";
}
function getLine() {
	var hWndEdit = AkelPad.GetEditWnd();
	var wrpLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, AkelPad.GetSelStart());
	var unwrpLine = AkelPad.SendMessage(hWndEdit, 3143 /*AEM_GETUNWRAPLINE*/, wrpLine, 0);
	return unwrpLine + 1;
}
function warn(msg) {
	AkelPad.MessageBox(AkelPad.GetMainWnd(), msg, WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
}
<download | development version>
Example for open file in other application.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#p9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/scriptToBookmarklet.js

// (c) Infocatcher 2008-2011
// version 0.3.0 - 2011-12-20
// Windows XP +

//===================
// Convert JavaScript code to one line bookmarklet
// http://en.wikipedia.org/wiki/Bookmarklet
// http://ru.wikipedia.org/wiki/Букмарклет

// Arguments:
//   -saveSpaces=0         - replace multiple spaces with one
//              =1         - don't replace spaces inside lines
//              =2         - only replace new lines
//   -removeNewLines=true  - remove new lines instead of replace them with space
//   -saveComments=0       - sum of flags: 1 - save block comments, 2 - save line comments

// Usage:
//   Call("Scripts::Main", 1, "converter.js")
//   Call("Scripts::Main", 1, "converter.js", "-saveSpaces=0 -removeNewLines=true -saveComments=3")
//===================

function _localize(s) {
	var strings = {
		"Code of bookmarklet (OK - copy):": {
			ru: "Код букмарклета (ОК - копировать):"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var saveSpaces     = getArg("saveSpaces", 0);
var removeNewLines = getArg("removeNewLines", true);
var saveComments   = getArg("saveComments", 0);

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
	scriptToBookmarklet();

function scriptToBookmarklet() {
	var text = getText();

	var excludes = {};
	var rnd = function() {
		return "<#" + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2) + "#>";
	};

	text = text
		// Remove "strings" and 'strings'
		.replace(
			/"(\\.|[^"\\\n\r])*"|'(\\.|[^'\\\n\r])*'/g,
			function(s) {
				var r = rnd();
				excludes[r] = s;
				return r;
			}
		)
		// Try remove regular expressions like /x*/ and /\/*x/
		// We search for invalid divisions:
		// x = /./;            -> =
		// if(/a/.test(b))     -> (
		// a = [/a/, /b/]      -> [ ,
		// x = a && /b/test(c) -> & |
		// x = a ? /b/ : /c/   -> ? :
		// x = !/a/.test(b)    -> !
		.replace(
			/([=(\[,&|?:!]\s*((\/\/[^\n\r]*[\n\r]+|\/\*[\s\S]*?\*\/)\s*)*)\/([^*+?\\\/\n\r]|\\[^\n\r])(\\\/|[^\/\n\r])*\//g,
			// special chars   line comments       block comments         regexp begin                         regexp end
			function(s, prefix) {
				var r = rnd();
				excludes[r] = s.substr(prefix.length);
				return prefix + r;
			}
		);


	if(!(saveComments & 1))
		text = text.replace(/\/\*[\s\S]*?\*\//g, ""); // /*comment*/
	if(!(saveComments & 2))
		text = text.replace(/(^|[\t ]+|([^:\\]))\/\/[^\n\r]*$/mg, "$2"); // //comment
	else
		text = text
			.replace(/(^|[\t ]+|[^:\\])\/\/([ \t]?)[ \t]*([^\n\r]*)$/mg, "$1/*$2$3*/") // //comment -> /*comment*/
			.replace(/\*\/[\n\r]+\/\*/g, " ");

	text = text
		.replace(/^\s*javascript:\s*/i, "")
		.replace(/^\s+|\s+$/g, "");

	var newLinesReplacement = removeNewLines ? "" : " ";

	if(saveSpaces == 0)
		text = text.replace(/\s+/g, " ");
	else if(saveSpaces == 1)
		text = text
			.replace(/^[ \t]+|[ \t]+$/mg, "")
			.replace(/[\n\r]+/g, newLinesReplacement);
	else if(saveSpaces >= 2)
		text = text.replace(/[\n\r]+/g, newLinesReplacement);


	text = text.replace(/<#[a-z0-9]{2,}#>/g, function(s) {
		if(s in excludes)
			return excludes[s];
		return s;
	});

	if(
		!/^\(function\s*\(\)\s*\{.+\}\)\s*\(\);?$/.test(text) // (function(){ ... })();
		&& !/^alert\s*\(([^()]*\([^()]+\))*[^()]*\);?$/.test(text) // alert( ... );
		&& !/\Walert\s*\(\s*[^)]+\s*\);?$/.test(text) // ... alert(x);
	)
		text += " void(0);";

	text = "javascript: " + text;

	text = AkelPad.InputBox(
		hMainWnd,
		WScript.ScriptName,
		_localize("Code of bookmarklet (OK - copy):"),
		text
	);
	if(text)
		AkelPad.SetClipboardText(text);
}
function getText() {
	// Get selection or all text
	var text = AkelPad.GetSelText();
	if(text)
		return text;
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(lpPoint) {
		setRedraw(hWndEdit, false);
		AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

		var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
		var ss = AkelPad.GetSelStart();
		var se = AkelPad.GetSelEnd();

		AkelPad.SetSel(0, -1);
		text = AkelPad.GetSelText();

		AkelPad.SetSel(ss, se);
		columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

		AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
		AkelPad.MemFree(lpPoint);
		setRedraw(hWndEdit, true);
	}
	return text;
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
<download | development version>
Convert JavaScript code to one line bookmarklet (javascript: ...).

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#p9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/scriptToBookmarklet_w2k.js

// (c) Infocatcher 2008-2011
// version 0.3.0 - 2011-12-20
// Windows 2000 SP2 +

//===================
// Convert JavaScript code to one line bookmarklet
// http://en.wikipedia.org/wiki/Bookmarklet
// http://ru.wikipedia.org/wiki/Букмарклет

// Arguments:
//   -saveSpaces=0         - replace multiple spaces with one
//              =1         - don't replace spaces inside lines
//              =2         - only replace new lines
//   -removeNewLines=true  - remove new lines instead of replace them with space
//   -saveComments=0       - sum of flags: 1 - save block comments, 2 - save line comments

// Usage:
//   Call("Scripts::Main", 1, "converter.js")
//   Call("Scripts::Main", 1, "converter.js", "-saveSpaces=0 -removeNewLines=true -saveComments=3")
//===================

function _localize(s) {
	var strings = {
		"Code of bookmarklet (OK - copy):": {
			ru: "Код букмарклета (ОК - копировать):"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var saveSpaces     = getArg("saveSpaces", 1);
var removeNewLines = getArg("removeNewLines", false);
var saveComments   = getArg("saveComments", 0);

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
	scriptToBookmarklet();

function scriptToBookmarklet() {
	var txt = getText();

	if(!(saveComments & 1))
		txt = txt.replace(/\/\*[\s\S]*\*\//g, ""); // /*comment*/

	if(!(saveComments & 2)) {
		var lines = txt.split("\r");
		for(var i = 0, l = lines.length; i < l; i++)
			lines[i] = lines[i].replace(/(^|[\t ]+|([^:\\]))\/\/[^\n\r]*$/, "$2"); // //comment
		txt = lines.join("\r");
	}
	else {
		// //comment -> /*comment*/
		var lines = txt.split("\r");
		for(var i = 0, l = lines.length; i < l; i++)
			lines[i] = lines[i].replace(/(^|[\t ]+|[^:\\])\/\/([ \t]?)[ \t]*([^\n\r]*)$/, "$1/*$2$3*/");
		txt = lines.join("\r")
			.replace(/\*\/[\n\r]+\/\*/g, "");
	}

	var newLinesReplacement = removeNewLines ? "" : " ";

	txt = txt
		.replace(/^\s*javascript:\s*/i, "")
		.replace(/^\s+|\s+$/g, "");

	if(saveSpaces == 0)
		txt = txt.replace(/[\n\r\t\s]+/g, " ");
	else if(saveSpaces == 1)
		txt = txt
			.replace(/^[ \t]+|[ \t]+$/mg, "")
			.replace(/[\n\r]+/g, newLinesReplacement);
	else if(saveSpaces >= 2)
		txt = txt.replace(/[\n\r]+/g, newLinesReplacement);

	if(
		!/^\(function\s*\(\)\s*\{.+\}\)\s*\(\);?$/.test(txt) // (function(){ ... })();
		&& !/^alert\s*\(([^()]*\([^()]+\))*[^()]*\);?$/.test(txt) // alert( ... );
		&& !/\Walert\s*\(\s*[^)]+\s*\);?$/.test(txt) // ... alert(x);
	)
		txt += " void(0);";

	txt = "javascript: " + txt;

	txt = AkelPad.InputBox(
		hMainWnd,
		WScript.ScriptName,
		_localize("Code of bookmarklet (OK - copy):"),
		txt
	);
	if(txt)
		AkelPad.SetClipboardText(txt);
}
function getText() {
	// Get selection or all text
	var txt = AkelPad.GetSelText();
	if(txt)
		return txt;
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(lpPoint) {
		setRedraw(hWndEdit, false);
		AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

		var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
		var ss = AkelPad.GetSelStart();
		var se = AkelPad.GetSelEnd();

		AkelPad.SetSel(0, -1);
		txt = AkelPad.GetSelText();

		AkelPad.SetSel(ss, se);
		columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

		AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
		AkelPad.MemFree(lpPoint);
		setRedraw(hWndEdit, true);
	}
	return txt;
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
<download | development version>
For old JScript versions.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#p9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/textStatistics.js

// (c) Infocatcher 2008-2011
// version 0.3.4 - 2011-12-20

// Usage:
//   Call("Scripts::Main", 1, "textStatistics.js")

// Windows XP+ (?)

function _localize(s) {
	var strings = {
		"Text missing!": {
			ru: "Текст отсутствует!"
		},
		"Lines: ": {
			ru: "Строки: "
		},
		"Only spaces: ": {
			ru: "Только пробельные символы: "
		},
		"Empty: ": {
			ru: "Пустые: "
		},
		"Shortest line: #": {
			ru: "Самая короткая строка: №"
		},
		"Longest line: #": {
			ru: "Самая длинная строка: №"
		},
		"Length: ": {
			ru: "Длина: "
		},
		"Line: “%S”": {
			ru: "Строка: «%S»"
		},
		"Symbols: ": {
			ru: "Символы: "
		},
		"Cyrillic: ": {
			ru: "Кириллица: "
		},
		"Latin: ": {
			ru: "Латиница: "
		},
		"Digits: ": {
			ru: "Цифры: "
		},
		"Space symbols: ": {
			ru: "Пробельные символы: "
		},
		"Spaces: ": {
			ru: "Пробелы: "
		},
		"Tabs: ": {
			ru: "Табуляции: "
		},
		"Carriage returns (\\r): ": {
			ru: "Возвраты каретки (\\r): "
		},
		"Line feeds (\\n): ": {
			ru: "Переводы строки (\\n): "
		},
		"Words: ": {
			ru: "Слова: "
		},
		"Cyrillic: ": {
			ru: "Кириллица: "
		},
		"Latin: ": {
			ru: "Латиница: "
		},
		"Numbers: ": {
			ru: "Числа: "
		},
		"Decimal: ": {
			ru: "Десятичные: "
		},
		"Hexadecimal: ": {
			ru: "Шестнадцатеричные: "
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
	showTextStatistics();

function showTextStatistics() {
	var res = getTextStatistics();
	AkelPad.MessageBox(hMainWnd, res, WScript.ScriptName, 64 /*MB_ICONINFORMATION*/);
}
function getTextStatistics() {
	var txt = getText();
	if(!txt)
		return _localize("Text missing!");
	var txtn = txt.replace(/\r\n|\n\r|\n|\r/g, "\n"); // Strange things happens with \r\n
	var cFile = AkelPad.GetEditFile(0);
	var res = cFile ? cFile + ":\n\n" : "";

	res +=          _localize("Lines: ")       + formatNum(countOf(txt, /\r\n|\n\r|\n|\r/g) + 1) + "\n";
	res += "  – " + _localize("Only spaces: ") + formatNum(countOf(txt, /^[\t ]+$/mg)) + "\n";
	res += "  – " + _localize("Empty: ")       + formatNum(countOf(txtn, /^$/mg)) + "\n";

	res += "\n";

	var longestLine  = -1,       longestLineNum,  longestLineText;
	var shortestLine = Infinity, shortestLineNum, shortestLineText;
	var lines = txtn.split("\n");
	var curLine, curLen;
	var tabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0) || 8;
	for(var i = 0, l = lines.length; i < l; i++) {
		curLine = lines[i];
		curLen = curLine.length;

		if(curLine.indexOf("\t") != -1) {
			var tabWidth, dw;
			for(var j = 0, column = 0, ll = curLen; j < ll; j++, column++) {
				if(curLine.charAt(j) != "\t")
					continue;
				tabWidth = tabStop - column % tabStop;
				if(tabWidth <= 1)
					continue;
				dw = tabWidth - 1;
				curLen += dw;
				column += dw;
			}
		}

		if(curLen > longestLine) {
			longestLine = curLen;
			longestLineNum = i + 1;
			longestLineText = curLine;
		}
		if(curLen < shortestLine) {
			shortestLine = curLen;
			shortestLineNum = i + 1;
			shortestLineText = curLine;
		}
	}

	res +=          _localize("Longest line: #") + formatNum(longestLineNum) + "\n";
	res += "  – " + _localize("Length: ") + formatNum(longestLine) + "\n";
	res += "  – " + _localize("Line: “%S”").replace("%S", formatLine(longestLineText)) + "\n";
	res +=          _localize("Shortest line: #") + formatNum(shortestLineNum) + "\n";
	res += "  – " + _localize("Length: ") + formatNum(shortestLine) + "\n";
	res += "  – " + _localize("Line: “%S”").replace("%S", formatLine(shortestLineText)) + "\n";

	res += "\n";

	res +=             _localize("Symbols: ")                + formatNum(txt.length) + "\n";
	res += "  – "    + _localize("Cyrillic: ")               + formatNum(countOf(txt, /[а-яё]/ig)) + "\n";
	res += "  – "    + _localize("Latin: ")                  + formatNum(countOf(txt, /[a-z]/ig)) + "\n";
	res += "  – "    + _localize("Digits: ")                 + formatNum(countOf(txt, /\d/g)) + "\n";
	res += "  – "    + _localize("Space symbols: ")          + formatNum(countOf(txt, /\s/g)) + "\n";
	res += "     = " + _localize("Spaces: ")                 + formatNum(countOf(txt, / /g)) + "\n";
	res += "     = " + _localize("Tabs: ")                   + formatNum(countOf(txt, /\t/g)) + "\n";
	res += "     = " + _localize("Carriage returns (\\r): ") + formatNum(countOf(txt, /\r/g)) + "\n";
	res += "     = " + _localize("Line feeds (\\n): ")       + formatNum(countOf(txt, /\n/g)) + "\n";

	res += "\n";

	var wordsCyr = countOf(txt, /[а-яё]+(-[а-яё]+)*/ig);
	var wordsLat = countOf(txt, /[a-z]+(-[a-z]+)*('[st])?/ig);
	res +=          _localize("Words: ")    + formatNum(wordsCyr + wordsLat) + "\n";
	res += "  – " + _localize("Cyrillic: ") + formatNum(wordsCyr) + "\n";
	res += "  – " + _localize("Latin: ")    + formatNum(wordsLat) + "\n";

	res += "\n";

	var numsDec = countOf(txt, /(^|\W)\d+([.,]\d+)?(?=(\W|$))/g); // Be careful with numbers like "0,2"
	var numsHex = countOf(txt, /(^|\W)0x[\da-f]+(?=(\W|$))/ig);
	res +=          _localize("Numbers: ")     + formatNum(numsDec + numsHex) + "\n";
	res += "  – " + _localize("Decimal: ")     + formatNum(numsDec) + "\n";
	res += "  – " + _localize("Hexadecimal: ") + formatNum(numsHex) + "\n";

	return res;
}
function countOf(txt, regexp) {
	var m = txt.match(regexp);
	return m ? m.length : 0;
}
function formatNum(n) {
	return String(n).replace(/(\d)(?=(\d{3})+(\D|$))/g, "$1 ");
}
function formatLine(s) {
	var maxLength = 45;
	var tabWidth = 8;
	var tab = new Array(tabWidth + 1).join(" ");
	var ret = s.substr(0, maxLength);
	while(ret.replace(/\t/g, tab).length > maxLength)
		ret = ret.substr(0, ret.length - 1);
	return ret == s
		? ret
		: ret + "\u2026"; // "..."
}

function getText() {
	// Get selection or all text
	var txt = AkelPad.GetSelText(4 - AkelPad.GetEditNewLine(0));
	if(txt)
		return txt;
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1, 4 - AkelPad.GetEditNewLine(0));
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return "";
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	AkelPad.SetSel(0, -1);
	txt = AkelPad.GetSelText(4 - AkelPad.GetEditNewLine(0));

	AkelPad.SetSel(ss, se);
	columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	AkelPad.MemFree(lpPoint);
	setRedraw(hWndEdit, true);
	return txt;
}

function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | development version>
Provide some statistic for English and Russian texts.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9927#p9927
// http://infocatcher.ucoz.net/js/akelpad_scripts/undoRedoAll.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/undoRedoAll.js

// (c) Infocatcher 2010, 2014
// version 0.1.1 - 2014-04-04

// Arguments:
//   -mode=0       - undo
//   -mode=1       - redo
//   -stopOnSaved

// Usage:
//   Call("Scripts::Main", 1, "undoRedoAll.js", "-mode=0 -stopOnSaved=true")

var AEM_CANUNDO = 3075;
var AEM_CANREDO = 3076;
var AEM_UNDO    = 3077;
var AEM_REDO    = 3078;

var MODE_UNDO = 0;
var MODE_REDO = 1;

// Read arguments:
var mode        = AkelPad.GetArgValue("mode", MODE_UNDO);
var stopOnSaved = AkelPad.GetArgValue("stopOnSaved", false);

var CAN_ACTION = AEM_CANUNDO;
var ACTION     = AEM_UNDO;
if(mode == MODE_REDO) {
	CAN_ACTION = AEM_CANREDO;
	ACTION     = AEM_REDO;
}

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(
	AkelPad.GetMainWnd()
	&& AkelPad.IsAkelEdit()
	&& canAction()
) {
	var nFirstLine = saveLineScroll(hWndEdit);

	do action();
	while(canAction());

	restoreLineScroll(hWndEdit, nFirstLine);
}
function canAction() {
	return (stopOnSaved ? AkelPad.SendMessage(hWndEdit, 3086 /*AEM_GETMODIFY*/, 0, 0) : true)
		&& AkelPad.SendMessage(hWndEdit, CAN_ACTION, 0, 0);
}
function action() {
	AkelPad.SendMessage(hWndEdit, ACTION, 0, 0);
}

// From Instructor's SearchReplace.js
function saveLineScroll(hWnd)
{
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, false, 0);
	return AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0);
}
function restoreLineScroll(hWnd, nBeforeLine)
{
	if (AkelPad.SendMessage(hWnd, 3129 /*AEM_GETLINENUMBER*/, 4 /*AEGL_FIRSTVISIBLELINE*/, 0) != nBeforeLine)
	{
		var lpScrollPos;
		var nPosY=AkelPad.SendMessage(hWnd, 3198 /*AEM_VPOSFROMLINE*/, 0 /*AECT_GLOBAL*/, nBeforeLine);

		if (lpScrollPos=AkelPad.MemAlloc(_X64?16:8 /*sizeof(POINT64)*/))
		{
			AkelPad.MemCopy(lpScrollPos + 0 /*offsetof(POINT64, x)*/, -1, 2 /*DT_QWORD*/);
			AkelPad.MemCopy(lpScrollPos + (_X64?8:4) /*offsetof(POINT64, y)*/, nPosY, 2 /*DT_QWORD*/);
			AkelPad.SendMessage(hWnd, 3180 /*AEM_SETSCROLLPOS*/, 0, lpScrollPos);
			AkelPad.MemFree(lpScrollPos);
		}
	}
	AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, true, 0);
	oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | development version>
Last edited by Infocatcher on Sun Aug 15, 2021 5:14 pm, edited 20 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

One-dimensional text array sorting function:

Code: Select all

// One-dimensional text array sorting function - 2010-12-18
//
// Sorted by key from nStart to nEnd character in string.
// This function changes the original array.
// Here is an example of use:

var aArray = ["ZZZdddaaa",
              "456aaa0xAcla",
              "999ZZZ0xF"];

ArrayTextSort(aArray, 9, 10, 1, 0, 0)

WScript.Echo("Sorted array:" + "\n" + aArray[0] + "\n" + aArray[1] + "\n" + aArray[2]);


////////////////////////////////////////////////
function ArrayTextSort(aArr, nStart, nEnd, bDescending, bNumerical, bIgnoreCase)
{
  if (bNumerical)
  {
    if (bDescending)
    {
      aArr.sort(function(a, b) {
        if      (Number(a.substring(nStart, nEnd)) < Number(b.substring(nStart, nEnd))) return 1;
        else if (Number(a.substring(nStart, nEnd)) > Number(b.substring(nStart, nEnd))) return -1;
        else return 0; });
    }
    else
    {
      aArr.sort(function(a, b) {
        if      (Number(a.substring(nStart, nEnd)) < Number(b.substring(nStart, nEnd))) return -1;
        else if (Number(a.substring(nStart, nEnd)) > Number(b.substring(nStart, nEnd))) return 1;
        else return 0; });
    }
  }
  else
  {
    if (bDescending)
    {
      if (bIgnoreCase)
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd).toUpperCase() < b.substring(nStart, nEnd).toUpperCase()) return 1;
          else if (a.substring(nStart, nEnd).toUpperCase() > b.substring(nStart, nEnd).toUpperCase()) return -1;
          else return 0; });
      }
      else
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd) < b.substring(nStart, nEnd)) return 1;
          else if (a.substring(nStart, nEnd) > b.substring(nStart, nEnd)) return -1;
          else return 0; });
      }
    }
    else
    {
      if (bIgnoreCase)
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd).toUpperCase() < b.substring(nStart, nEnd).toUpperCase()) return -1;
          else if (a.substring(nStart, nEnd).toUpperCase() > b.substring(nStart, nEnd).toUpperCase()) return 1;
          else return 0; });
      }
      else
      {
        aArr.sort(function(a, b) {
          if      (a.substring(nStart, nEnd) < b.substring(nStart, nEnd)) return -1;
          else if (a.substring(nStart, nEnd) > b.substring(nStart, nEnd)) return 1;
          else return 0; });
      }
    }
  }
}


One or two-dimensional array sorting function:

Code: Select all

// One or two-dimensional array sorting function - 2010-12-18
//
// Sorted by any field, ascending or descending order, by numbers or by strings.
// This function changes the original array.
// Here is an example of use:

// nField      0      1      2
var aArray = [["ZZZ", "ddd", "aaa"],
              ["999", "ZZZ", "0xF"],
              ["456", "aaa", "0xA"]];

Array2DSort(aArray, 0, 0, 1, 1)

WScript.Echo("Sorted array:" + "\n" + aArray[0] + "\n" + aArray[1] + "\n" + aArray[2]);

////////////////////////////////////////////////
// If nField < 0 - must be one-dimensional array
////////////////////////////////////////////////
function Array2DSort(aArr, nField, bDescending, bNumerical, bIgnoreCase)
{
  if (bNumerical)
  {
    if (bDescending)
    {
      if (nField < 0)
        aArr.sort(function(a, b) {
          if      (Number(a) < Number(b)) return 1;
          else if (Number(a) > Number(b)) return -1;
          else return 0; });
      else
        aArr.sort(function(a, b) {
          if      (Number(a[nField]) < Number(b[nField])) return 1;
          else if (Number(a[nField]) > Number(b[nField])) return -1;
          else return 0; });
    }
    else
    {
      if (nField < 0)
        aArr.sort(function(a, b) {
          if      (Number(a) < Number(b)) return -1;
          else if (Number(a) > Number(b)) return 1;
          else return 0; });
      else
        aArr.sort(function(a, b) {
          if      (Number(a[nField]) < Number(b[nField])) return -1;
          else if (Number(a[nField]) > Number(b[nField])) return 1;
          else return 0; });
    }
  }
  else
  {
    if (bDescending)
    {
      if (bIgnoreCase)
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a).toUpperCase() < String(b).toUpperCase()) return 1;
            else if (String(a).toUpperCase() > String(b).toUpperCase()) return -1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]).toUpperCase() < String(b[nField]).toUpperCase()) return 1;
            else if (String(a[nField]).toUpperCase() > String(b[nField]).toUpperCase()) return -1;
            else return 0; });
      }
      else
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a) < String(b)) return 1;
            else if (String(a) > String(b)) return -1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]) < String(b[nField])) return 1;
            else if (String(a[nField]) > String(b[nField])) return -1;
            else return 0; });
      }
    }
    else
    {
      if (bIgnoreCase)
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a).toUpperCase() < String(b).toUpperCase()) return -1;
            else if (String(a).toUpperCase() > String(b).toUpperCase()) return 1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]).toUpperCase() < String(b[nField]).toUpperCase()) return -1;
            else if (String(a[nField]).toUpperCase() > String(b[nField]).toUpperCase()) return 1;
            else return 0; });
      }
      else
      {
        if (nField < 0)
          aArr.sort(function(a, b) {
            if      (String(a) < String(b)) return -1;
            else if (String(a) > String(b)) return 1;
            else return 0; });
        else
          aArr.sort(function(a, b) {
            if      (String(a[nField]) < String(b[nField])) return -1;
            else if (String(a[nField]) > String(b[nField])) return 1;
            else return 0; });
      }
    }
  }
}


Two-dimensional array transposition function:

Code: Select all

// Two-dimensional array transposition function - 2010-12-18
//
// Here is an example of use:

var aArray = [["aaa", "bbb", "ccc"],
              ["111", "222", "333"],
              ["ddd", "eee", "fff"],
              ["444", "555", "666"],
              ["ggg", "hhh", "iii"]];

var aArray1 = Array2DTransp(aArray);

WScript.Echo("Array after transposition:" + "\n" + aArray1[0] + "\n" + aArray1[1] + "\n" + aArray1[2]);


////////////////////////////////////////////////
function Array2DTransp(aArr)
{
  var nLen1 = aArr.length;
  var nLen2 = aArr[0].length;
  var aArr2 = [];
  var i, n;

  aArr2.length = nLen2;

  for (n = 0; n < nLen2; ++n)
  {
    aArr2[n] = [];
    for (i = 0; i < nLen1; ++i)
    {
      aArr2[n].push(aArr[i][n]);
    }
  }

  return aArr2;
}
Last edited by KDJ on Sat Dec 18, 2010 9:47 pm, edited 3 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

DateToShortLocaleString(dDate) function returns a short local date.

Code: Select all

// DateToShortLocaleString(dDate) function returns a short local date - 2010-12-02
//
// Here is an example of use:

var dToday     = new Date();
var pLongDate  = dToday.toLocaleString();
var pShortDate = DateToShortLocaleString(dToday);

WScript.Echo("Long date:  " + pLongDate + "\n" + "Short date: " + pShortDate);

////////
function DateToShortLocaleString(dDate)
{
  var DT_WORD   = 4;
  var oSys      = AkelPad.SystemFunction();
  var lpSysTime = AkelPad.MemAlloc(16 /*sizeof(SYSTEMTIME)*/);
  var lpString  = AkelPad.MemAlloc(256 * _TSIZE);
  var pDateTime;

  AkelPad.MemCopy(lpSysTime,     dDate.getFullYear(),     DT_WORD);
  AkelPad.MemCopy(lpSysTime + 2, dDate.getMonth() + 1,    DT_WORD);
  AkelPad.MemCopy(lpSysTime + 4, dDate.getDay(),          DT_WORD);
  AkelPad.MemCopy(lpSysTime + 6, dDate.getDate(),         DT_WORD);
  AkelPad.MemCopy(lpSysTime + 8, dDate.getHours(),        DT_WORD);
  AkelPad.MemCopy(lpSysTime +10, dDate.getMinutes(),      DT_WORD);
  AkelPad.MemCopy(lpSysTime +12, dDate.getSeconds(),      DT_WORD);
  AkelPad.MemCopy(lpSysTime +14, dDate.getMilliseconds(), DT_WORD);

  oSys.Call("kernel32::GetDateFormat" + _TCHAR,
            0x400, //LOCALE_USER_DEFAULT
            0x1,   //DATE_SHORTDATE
            lpSysTime,
            0,
            lpString,
            256);
  pDateTime = AkelPad.MemRead(lpString, _TSTR) + " ";

  oSys.Call("kernel32::GetTimeFormat" + _TCHAR,
            0x400, //LOCALE_USER_DEFAULT
            0x8,   //TIME_FORCE24HOURFORMAT
            lpSysTime,
            0,
            lpString,
            256);
  pDateTime += AkelPad.MemRead(lpString, _TSTR);

  AkelPad.MemFree(lpSysTime);
  AkelPad.MemFree(lpString);

  return pDateTime;
}

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

This function retrieves columnar text, without selecting.

Code: Select all

// GetTextRangeColumn() function returns columnar text, without selecting - 2011-01-15
//
// Example of use:

var Txt = GetTextRangeColumn([0, 3], [6, 12], 1, 1, 1);
AkelPad.Command(4101);
AkelPad.ReplaceSel(Txt);

/////////////////////////////////////////////
// aBeg = [nBeginLine, nBeginColumn]
// aEnd = [nEndLine,   nEndColumn]
// Optional:
// bReturnText = 0 //return array of lines (default)
//               1 //return text
// nNewLine = 1  //"\r" new line (default)
//            2  //"\n" new line
//            3  //"\r\n" new line
// bFillSpaces = 0 //(default)
//               1 //fill empties with spaces
/////////////////////////////////////////////
function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var hEditWnd  = AkelPad.GetEditWnd();
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}
Last edited by KDJ on Sat Jan 15, 2011 8:35 pm, edited 1 time in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10403#p10403
// http://infocatcher.ucoz.net/js/akelpad_scripts/saveStoreTime.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/saveStoreTime.js

// (c) Infocatcher 2010-2011, 2014
// version 0.1.4 - 2014-03-03

// Save file and don't update modification time
// Based on Instructor's code: http://akelpad.sourceforge.net/forum/viewtopic.php?p=4222#p4222

// Usage:
//   Call("Scripts::Main", 1, "saveStoreTime.js")

var hMainWnd = AkelPad.GetMainWnd();

if(hMainWnd) {
	var saveTime = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 148 /*MI_SAVETIME*/, 0);
	if(!saveTime)
		AkelPad.Command(4252 /*IDM_OPTIONS_SAVETIME*/);
	AkelPad.Command(4105 /*IDM_FILE_SAVE*/);
	if(!saveTime)
		AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 148 /*MIS_SAVETIME*/, saveTime);
}
<download | mirror | development version>
Temporary check “save file time” option and save current document.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10403#p10403
// http://infocatcher.ucoz.net/js/akelpad_scripts/goToLongestLine.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/goToLongestLine.js

// (c) Infocatcher 2010-2011, 2014
// version 0.3.9.1 - 2014-05-06

//===================
// Go to longest line below or above current
// Hotkeys in dialog:
//   PageUp/PageDown            - go to longest line below/above current
//   Ctrl+PageUp/Ctrl+PageDown  - go to start/end of document

// Arguments:
//   -dialog=true        - show dialog
//   -reverse=false      - inverse direction (only without dialog)
//   -timeLimit=400      - time limit (in milliseconds) for very big files
//   -close=true         - force check "close dialog"
//   -focus=true         - force check "focus editor"
//   -autoGo=true        - automatically go to longest line after run with -dialog=true
//   -saveOptions=0      - don't store options
//               =1      - save options after them usage
//               =2      - save options on exit
//   -savePosition=true  - allow store last window position

// Usage:
//   Call("Scripts::Main", 1, "goToLongestLine.js")
//   Call("Scripts::Main", 1, "goToLongestLine.js", "-dialog=false -reverse=false")
//   Call("Scripts::Main", 1, "goToLongestLine.js", "-dialog=true -close=true -saveOptions=0 -savePosition=false")
//===================

function _localize(s) {
	var strings = {
		"&Close dialog": {
			ru: "&Закрывать диалог"
		},
		"&Focus editor": {
			ru: "Переводить &фокус на редактор"
		},
		"&Time limit:": {
			ru: "&Ограничение по времени:"
		},
		"ms": {
			ru: "мс"
		},
		"Are you sure to disable time limit?": {
			ru: "Вы уверены, что хотите отключить ограничение по времени?"
		},
		"Time limit is too big (%S min)!\nContinue anyway?": {
			ru: "Ограничение по времени слишком велико (%S мин)\nВсе равно продолжить?"
		},
		"&Line:": {
			ru: "&Строка:"
		},
		"L&ength:": {
			ru: "&Длина:"
		},
		"&Processed:": {
			ru: "&Обработано:"
		},
		"&Down": {
			ru: "В&низ"
		},
		"&Up": {
			ru: "В&верх"
		},
		"Cancel": {
			ru: "Отмена"
		}
	};
	var lng;
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}


// Read arguments:
// getArg(argName, defaultValue), getArgOrPref(argAndPrefName, type, defaultValue)
var saveOptions  = getArg("saveOptions", 1);
var savePosition = getArg("savePosition", true);

if(saveOptions || savePosition)
	var prefs = new Prefs();

var dialog       = getArg("dialog", true);
var reverse      = getArg("reverse", false);
var autoGo       = getArg("autoGo", false);
var checkClose   = getArgOrPref("close",     prefs && prefs.DWORD);
var checkFocus   = getArgOrPref("focus",     prefs && prefs.DWORD);
var timeLimit    = getArgOrPref("timeLimit", prefs && prefs.DWORD, 400);

prefs && prefs.end();


var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

Number.prototype._origToFixed = Number.prototype.toFixed;
Number.prototype.toFixed = function(r) {
	if(r >= 0 && this._origToFixed)
		return this._origToFixed(r);
	var n = this;
	var d = Math.pow(10, r);
	n = (Math.round(n*d)/d).toString();
	if(r <= 0)
		return n;
	if(!/\./.test(n))
		n += ".";
	var count = n.match(/\.(.*)$/)[1].length;
	n += new Array(r - count + 1).join("0");
	return n;
};

if(hMainWnd) {
	if(dialog)
		goToLongestLineDialog();
	else
		goToLongestLine(reverse);
}

function goToLongestLine(reverse) {
	var hWndEdit = AkelPad.GetEditWnd();

	var ww = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
	if(ww) {
		setRedraw(hWndEdit, false);
		AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
	}

	var longestLine;
	var longestLineLength = -1;
	var line, lineStart, lineLength, lineEnd;
	var indx;
	var linesCount = AkelPad.SendMessage(hWndEdit, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
	var count;
	var ss = AkelPad.GetSelStart();
	line = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, ss);
	if(reverse) {
		lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
		indx       = lineStart - 1;

		count = line;
	}
	else {
		lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
		lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, ss, 0);
		lineEnd    = lineStart + lineLength;
		indx       = lineEnd + 1;

		count = linesCount - line - 1;
	}

	if(timeLimit)
		var stopTime = new Date().getTime() + timeLimit;
	var lines = 0;
	var tabStop = AkelPad.SendMessage(AkelPad.GetEditWnd(), 3239 /*AEM_GETTABSTOP*/, 0, 0) || 8;
	for(;;) {
		if(reverse) {
			if(--line == -1)
				break;
			lineStart  = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/,  line, 0);
			lineEnd    = indx;
			lineLength = lineEnd - lineStart;
		}
		else {
			if(++line == linesCount)
				break;
			lineStart  = indx;
			lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, indx, 0);
			lineEnd    = lineStart + lineLength;
		}
		lines++;

		var lineText = AkelPad.GetTextRange(lineStart, lineEnd);
		if(lineText.indexOf("\t") != -1) {
			for(var i = 0, column = 0, ll = lineLength; i < ll; i++, column++) {
				if(lineText.charAt(i) != "\t")
					continue;
				var tabWidth = tabStop - column % tabStop;
				if(tabWidth <= 1)
					continue;
				var dw = tabWidth - 1;
				lineLength += dw;
				column     += dw;
			}
		}

		if(lineLength > longestLineLength) {
			longestLineLength = lineLength;
			longestLine = line;
		}
		if(timeLimit && new Date().getTime() > stopTime)
			break;
		indx = reverse
			? lineStart - 1
			: lineEnd   + 1;
	}

	if(ww) {
		AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
		setRedraw(hWndEdit, true);
	}

	if(longestLine != undefined) {
		var gotoStr = (longestLine + 1) + ":" + (longestLineLength + 1);
		AkelPad.SendMessage(hMainWnd, 1206 /*AKD_GOTOW*/, 0x1 /*GT_LINE*/, AkelPad.MemStrPtr(gotoStr));
	}
	return {
		line:        (longestLine == undefined ? line : longestLine) + 1,
		lineLength:  longestLineLength,
		linesCount:  linesCount,
		processed:   lines,
		targetCount: lines ? count : 0
	};
}

function goToLongestLineDialog(modal) {
	var hInstanceDLL = AkelPad.GetInstanceDll();
	var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");

	var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
	if(hWndDialog) {
		if(oSys.Call("user32::IsIconic", hWndDialog))
			oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
		AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
		return;
	}

	if(
		!AkelPad.WindowRegisterClass(dialogClass)
		&& ( // Previous script instance crashed
			!AkelPad.WindowUnregisterClass(dialogClass)
			|| !AkelPad.WindowRegisterClass(dialogClass)
		)
	)
		return;

	var disabled = false;
	var disabledTimeout = 150;

	var IDC_STATIC     = -1;
	var IDC_FOCUS      = 1001;
	var IDC_CLOSE      = 1002;
	var IDC_TIME_LIMIT = 1003;
	var IDC_LINE       = 1004;
	var IDC_LENGTH     = 1005;
	var IDC_PROCESSED  = 1006;
	var IDC_UP         = 1007;
	var IDC_DOWN       = 1008;
	var IDC_CANCEL     = 1009;

	var hWndFocus, hWndClose;
	var hWndStatic, hWndTimeLimit, hWndLine, hWndLength, hWndProcessed;
	var hWndDown, hWndUp, hWndCancel;

	var scale = new Scale(0, hMainWnd);
	var sizeNonClientX = oSys.Call("user32::GetSystemMetrics", 7 /*SM_CXFIXEDFRAME*/) * 2;
	var sizeNonClientY = oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/) * 2 + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);

	// Create dialog
	hWndDialog = oSys.Call(
		"user32::CreateWindowEx" + _TCHAR,
		0,                             //dwExStyle
		dialogClass,                   //lpClassName
		0,                             //lpWindowName
		0x90CA0000,                    //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
		scale.x(0),                    //x
		scale.y(0),                    //y
		scale.x(286) + sizeNonClientX, //nWidth
		scale.y(193) + sizeNonClientY, //nHeight
		hMainWnd,                      //hWndParent
		0,                             //ID
		hInstanceDLL,                  //hInstance
		dialogCallback                 //Script function callback. To use it class must be registered by WindowRegisterClass.
	);
	if(!hWndDialog)
		return;

	function dialogCallback(hWnd, uMsg, wParam, lParam) {
		switch(uMsg) {
			case 1: //WM_CREATE
				function setWindowFontAndText(hWnd, hFont, pText) {
					AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
					windowText(hWnd, pText);
				}

				var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);

				// Dialog caption
				windowText(hWnd, dialogTitle);

				// Checkbox: close dialog
				hWndClose = createWindowEx(
					0,             //dwExStyle
					"BUTTON",      //lpClassName
					0,             //lpWindowName
					0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
					12,            //x
					12,            //y
					270,           //nWidth
					16,            //nHeight
					hWnd,          //hWndParent
					IDC_CLOSE,     //ID
					hInstanceDLL,  //hInstance
					0              //lpParam
				);
				setWindowFontAndText(hWndClose, hGuiFont, _localize("&Close dialog"));
				checked(hWndClose, checkClose);

				// Checkbox: focus editor
				hWndFocus = createWindowEx(
					0,             //dwExStyle
					"BUTTON",      //lpClassName
					0,             //lpWindowName
					0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
					12,            //x
					34,            //y
					270,           //nWidth
					16,            //nHeight
					hWnd,          //hWndParent
					IDC_FOCUS,     //ID
					hInstanceDLL,  //hInstance
					0              //lpParam
				);
				setWindowFontAndText(hWndFocus, hGuiFont, _localize("&Focus editor"));
				checked(hWndFocus, checkFocus);

				// Static window: time limit label
				hWndStatic = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					12,           //x
					59,           //y
					134,          //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Time limit:"));

				// Edit: time limit
				hWndTimeLimit = createWindowEx(
					0x200,          //WS_EX_CLIENTEDGE
					"EDIT",         //lpClassName
					0,              //lpWindowName
					0x50012080,     //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_NUMBER|ES_AUTOHSCROLL
					150,            //x
					56,             //y
					60,             //nWidth
					19,             //nHeight
					hWnd,           //hWndParent
					IDC_TIME_LIMIT, //ID
					hInstanceDLL,   //hInstance
					0               //lpParam
				);
				setWindowFontAndText(hWndTimeLimit, hGuiFont, String(timeLimit));

				// Up/down buttons
				hWndStatic = createWindowEx(
					0,                 //dwExStyle
					"msctls_updown32", //lpClassName
					0,                 //lpWindowName
					0x500000A2,        //WS_VISIBLE|WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_NOTHOUSANDS
					210,               //x
					55,                //y
					16,                //nWidth
					21,                //nHeight
					hWnd,              //hWndParent
					IDC_STATIC,        //ID
					hInstanceDLL,      //hInstance
					0                  //lpParam
				);
				AkelPad.SendMessage(hWndStatic, 0x0400 + 105 /*UDM_SETBUDDY*/, hWndTimeLimit, 0);
				AkelPad.SendMessage(hWndStatic, 0x0400 + 101 /*UDM_SETRANGE*/, 0, ((0 & 0xFFFF) << 16) + (30000 & 0xFFFF));

				// Static window: time limit ms label
				hWndStatic = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					230,          //x
					59,           //y
					58,           //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndStatic, hGuiFont, _localize("ms"));

				// Static window: line label
				hWndStatic = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					12,           //x
					89,           //y
					78,           //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Line:"));

				// Edit: line
				hWndLine = createWindowEx(
					0x200,        //WS_EX_CLIENTEDGE
					"EDIT",       //lpClassName
					0,            //lpWindowName
					0x50010880,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
					94,           //x
					86,           //y
					180,          //nWidth
					19,           //nHeight
					hWnd,         //hWndParent
					IDC_LINE,     //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndLine, hGuiFont, "");

				// Static window: length label
				hWndStatic = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					12,           //x
					110,          //y
					78,           //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndStatic, hGuiFont, _localize("L&ength:"));

				// Edit: length
				hWndLength = createWindowEx(
					0x200,        //WS_EX_CLIENTEDGE
					"EDIT",       //lpClassName
					0,            //lpWindowName
					0x50010880,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
					94,           //x
					107,          //y
					180,          //nWidth
					19,           //nHeight
					hWnd,         //hWndParent
					IDC_LENGTH,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndLength, hGuiFont, "");

				// Static window: processed lines label
				hWndStatic = createWindowEx(
					0,            //dwExStyle
					"STATIC",     //lpClassName
					0,            //lpWindowName
					0x50000000,   //WS_VISIBLE|WS_CHILD
					12,           //x
					131,          //y
					78,           //nWidth
					13,           //nHeight
					hWnd,         //hWndParent
					IDC_STATIC,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndStatic, hGuiFont, _localize("&Processed:"));

				// Edit: processed lines
				hWndProcessed = createWindowEx(
					0x200,         //WS_EX_CLIENTEDGE
					"EDIT",        //lpClassName
					0,             //lpWindowName
					0x50010880,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_READONLY
					94,            //x
					128,           //y
					180,           //nWidth
					19,            //nHeight
					hWnd,          //hWndParent
					IDC_PROCESSED, //ID
					hInstanceDLL,  //hInstance
					0              //lpParam
				);
				setWindowFontAndText(hWndProcessed, hGuiFont, "");

				// Down button window
				hWndDown = createWindowEx(
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50010001,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
					12,           //x
					159,          //y
					80,           //nWidth
					23,           //nHeight
					hWnd,         //hWndParent
					IDC_DOWN,     //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndDown, hGuiFont, _localize("&Down"));

				// Up button window
				hWndUp = createWindowEx(
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
					104,          //x
					159,          //y
					80,           //nWidth
					23,           //nHeight
					hWnd,         //hWndParent
					IDC_UP,       //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndUp, hGuiFont, _localize("&Up"));

				// Cancel button window
				hWndCancel = createWindowEx(
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
					196,          //x
					159,          //y
					80,           //nWidth
					23,           //nHeight
					hWnd,         //hWndParent
					IDC_CANCEL,   //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				setWindowFontAndText(hWndCancel, hGuiFont, _localize("Cancel"));

				oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CLOSE, 0);

				//centerWindow(hWnd);
				//centerWindow(hWnd, hMainWnd);
				restoreWindowPosition(hWnd, hMainWnd);

				//autoGo && oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
				if(autoGo) try {
					controlsEnabled(false);
					var document = new ActiveXObject("htmlfile");
					var window = document.parentWindow;
					window.setTimeout(function() {
						oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
					}, 0);
				}
				catch(e) {
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, reverse ? IDC_UP : IDC_DOWN, 0);
				}
			break;
			case 7: //WM_SETFOCUS
				focusWindow(hWndDown);
			break;
			case 256: //WM_KEYDOWN
				var ctrl = oSys.Call("user32::GetAsyncKeyState", 162 /*VK_LCONTROL*/)
					|| oSys.Call("user32::GetAsyncKeyState", 163 /*VK_RCONTROL*/);
				var shift = oSys.Call("user32::GetAsyncKeyState", 160 /*VK_LSHIFT*/)
					|| oSys.Call("user32::GetAsyncKeyState", 161 /*VK_RSHIFT*/);

				if(wParam == 27 /*VK_ESCAPE*/)
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
				else if((ctrl || shift) && wParam == 34 /*PageDown*/) {
					AkelPad.SetSel(-1, -1);
					checked(hWndFocus) && focusWindow(AkelPad.GetEditWnd());
				}
				else if((ctrl || shift) && wParam == 33 /*PageUp*/) {
					AkelPad.SetSel(0, 0);
					checked(hWndFocus) && focusWindow(AkelPad.GetEditWnd());
				}
				else if(wParam == 13 /*VK_RETURN*/ || wParam == 34 /*PageDown*/)
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_DOWN, 0);
				else if(wParam == 33 /*PageUp*/)
					oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_UP, 0);
			break;
			case 273: //WM_COMMAND
				var idc = wParam & 0xffff;
				switch(idc) {
					case IDC_DOWN:
					case IDC_UP:
						if(!readTimeLimit())
							break;

						if(disabled == true || disabled > new Date().getTime())
							break;
						disabled = true;
						var up = idc == IDC_UP;
						var hWndFocused = oSys.Call("user32::GetFocus");
						controlsEnabled(false);
						var stats = goToLongestLine(up);

						windowText(hWndLine, formatNum(stats.line) + " / " + formatNum(stats.linesCount));
						windowText(hWndLength, formatNum(stats.lineLength));
						windowText(
							hWndProcessed,
							stats.processed == stats.targetCount
								? formatNum(stats.processed)
								: formatNum(stats.processed) + " / " + formatNum(stats.targetCount)
								 + " (" + toLocaleNum((stats.processed/stats.targetCount*100).toFixed(2)) + "%)"
						);

						var closeDlg    = checked(hWndClose);
						var focusEditor = checked(hWndFocus);
						if(saveOptions == 1) {
							prefs.set({
								close:     closeDlg,
								focus:     focusEditor,
								timeLimit: timeLimit
							});
							prefs.end();
						}
						if(closeDlg)
							closeDialog();
						else {
							controlsEnabled(true);
							if(focusEditor)
								focusWindow(AkelPad.GetEditWnd());
							else if(!oSys.Call("user32::GetFocus")) // We disable focused window
								focusWindow(hWndFocused);
							disabled = new Date().getTime() + disabledTimeout;
						}
					break;
					case IDC_CANCEL:
						closeDialog();
					break;
					case IDC_CLOSE:
						enabled(hWndFocus, !checked(hWndClose));
				}
			break;
			case 16: //WM_CLOSE
				enabled(hMainWnd, true); // Enable main window
				savePosition && !oSys.Call("user32::IsIconic", hWnd) && saveWindowPosition(hWnd);
				if(saveOptions == 2) {
					prefs.set({
						close:     checked(hWndClose),
						focus:     checked(hWndFocus),
						timeLimit: parseInt(windowText(hWndTimeLimit), 10) || 0
					});
					prefs.end();
				}

				oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
			break;
			case 2: //WM_DESTROY
				oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
		}
		return 0;
	}
	function saveWindowPosition(hWnd) {
		var rcWnd = getWindowRect(hWnd);
		if(!rcWnd)
			return;
		prefs.set({
			windowLeft: rcWnd.left,
			windowTop:  rcWnd.top
		});
		prefs.end();
	}
	function restoreWindowPosition(hWnd, hWndParent) {
		if(savePosition) {
			var dlgX = prefs.get("windowLeft", prefs.DWORD);
			var dlgY = prefs.get("windowTop",  prefs.DWORD);
			prefs.end();
		}

		if(dlgX == undefined || dlgY == undefined) {
			centerWindow(hWnd, hWndParent);
			return;
		}

		var rcWnd = getWindowRect(hWnd);
		if(!rcWnd)
			return;

		var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
		if(!lpRect)
			return;
		AkelPad.MemCopy(lpRect,      dlgX,                              3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpRect + 4,  dlgY,                              3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpRect + 8,  dlgX + (rcWnd.right - rcWnd.left), 3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpRect + 12, dlgY + (rcWnd.top - rcWnd.bottom), 3 /*DT_DWORD*/);
		var hMonitor = oSys.Call("user32::MonitorFromRect", lpRect, 0x2 /*MONITOR_DEFAULTTONEAREST*/);

		if(hMonitor) {
			//typedef struct tagMONITORINFO {
			//  DWORD cbSize;
			//  RECT  rcMonitor;
			//  RECT  rcWork;
			//  DWORD dwFlags;
			//} MONITORINFO, *LPMONITORINFO;
			var sizeofMonitorInfo = 4 + 16 + 16 + 4;
			var lpMi = AkelPad.MemAlloc(sizeofMonitorInfo);
			if(lpMi) {
				AkelPad.MemCopy(lpMi, sizeofMonitorInfo, 3 /*DT_DWORD*/);
				oSys.Call("user32::GetMonitorInfo" + _TCHAR, hMonitor, lpMi);
				var rcWork = parseRect(lpMi + 4 + 16);
				AkelPad.MemFree(lpMi);
			}
		}
		else { //?
			oSys.Call("user32::SystemParametersInfo" + _TCHAR, 48 /*SPI_GETWORKAREA*/, 0, lpRect, 0);
			var rcWork = parseRect(lpRect);
		}
		AkelPad.MemFree(lpRect);

		if(rcWork) {
			var edge = Math.max(
				16,
				oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/)
					+ oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/)
			);

			var minX = rcWork.left - (rcWnd.right - rcWnd.left) + edge;
			var minY = rcWork.top;
			var maxX = rcWork.right - edge;
			var maxY = rcWork.bottom - edge;

			dlgX = Math.max(minX, Math.min(maxX, dlgX));
			dlgY = Math.max(minY, Math.min(maxY, dlgY));
		}

		oSys.Call("user32::SetWindowPos", hWnd, 0, dlgX, dlgY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
	}
	function centerWindow(hWnd, hWndParent) {
		var rcWnd = getWindowRect(hWnd);
		var rcWndParent = getWindowRect(hWndParent || oSys.Call("user32::GetDesktopWindow"));
		if(!rcWndParent || !rcWnd)
			return;
		var x = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
		var y = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
		oSys.Call("user32::SetWindowPos", hWnd, 0, x, y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
	}
	function getWindowRect(hWnd, hWndParent) {
		var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
		if(!lpRect)
			return null;
		oSys.Call("user32::GetWindowRect", hWnd, lpRect);
		hWndParent && oSys.Call("user32::ScreenToClient", hWndParent, lpRect);
		var rcWnd = parseRect(lpRect);
		AkelPad.MemFree(lpRect);
		return rcWnd;
	}
	function parseRect(lpRect) {
		return {
			left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
			top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
			right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
			bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
		};
	}
	function windowText(hWnd, pText) {
		if(arguments.length > 1)
			return oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText);
		var len = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWnd);
		var lpText = AkelPad.MemAlloc((len + 1)*_TSIZE);
		if(!lpText)
			return "";
		oSys.Call("user32::GetWindowText" + _TCHAR, hWnd, lpText, len + 1);
		pText = AkelPad.MemRead(lpText, _TSTR);
		AkelPad.MemFree(lpText);
		return pText;
	}
	function checked(hWnd, val) {
		return arguments.length == 1
			? AkelPad.SendMessage(hWnd, 240 /*BM_GETCHECK*/, 0, 0)
			: AkelPad.SendMessage(hWnd, 241 /*BM_SETCHECK*/, val ? 1 /*BST_CHECKED*/ : 0, 0);
	}
	function enabled(hWnd, val) {
		oSys.Call("user32::EnableWindow", hWnd, val);
	}
	function focusWindow(hWnd) {
		oSys.Call("user32::SetFocus", hWnd);
	}
	function controlsEnabled(val) {
		enabled(hWndUp,   val);
		enabled(hWndDown, val);
		!modal && enabled(hMainWnd, val);
	}
	function closeDialog() {
		oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
	}
	function readTimeLimit() {
		var timeLimitMin  = 0;
		var timeLimitWarn = 15000;
		var timeLimitMax  = 24*60*60*1000;
		var tlOrig = windowText(hWndTimeLimit);
		var tl = Number(
			tlOrig
				.replace(/\D/g, "")
				.replace(/^0+/, "")
		);
		tl = Math.max(timeLimitMin, Math.min(timeLimitMax, tl));

		var confirm = function(ask) {
			if(typeof readTimeLimit._ok != "undefined" && readTimeLimit._ok)
				return true; // Only one confirmation
			return readTimeLimit._ok = AkelPad.MessageBox(
				hWndDialog, ask, dialogTitle, 33 /*MB_OKCANCEL|MB_ICONQUESTION*/
			) == 1 /*IDOK*/;
		};
		if(!tl && !confirm(_localize("Are you sure to disable time limit?"))) {
			focusWindow(hWndTimeLimit);
			AkelPad.SendMessage(hWndTimeLimit, 177 /*EM_SETSEL*/, 0, -1);
			return false;
		}
		if(tl > timeLimitWarn) {
			var secs = Math.round(tl/1000);
			var mins = Math.floor(secs/60);
			secs = Math.floor(secs%60);
			if(secs < 10)
				secs = "0" + secs;
			if(!confirm(_localize("Time limit is too big (%S min)!\nContinue anyway?").replace("%S", mins + ":" + secs))) {
				focusWindow(hWndTimeLimit);
				AkelPad.SendMessage(hWndTimeLimit, 177 /*EM_SETSEL*/, 0, -1);
				return false;
			}
		}

		if(String(tl) != tlOrig)
			windowText(hWndTimeLimit, String(tl));
		timeLimit = tl;
		return true;
	}

	function Scale(hDC, hWnd) {
		var hNewDC = hDC || oSys.Call("user32::GetDC", hWnd);
		if(hNewDC) {
			this._x = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 88 /*LOGPIXELSX*/);
			this._y = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 90 /*LOGPIXELSY*/);

			//Align to 16 pixel
			this._x += (16 - this._x % 16) % 16;
			this._y += (16 - this._y % 16) % 16;

			!hDC && oSys.Call("user32::ReleaseDC", hWnd, hNewDC);

			this.x = function(x) {
				return oSys.Call("kernel32::MulDiv", x, this._x, 96);
			};
			this.y = function(y) {
				return oSys.Call("kernel32::MulDiv", y, this._y, 96);
			};
		}
		else {
			this.x = this.y = function(n) {
				return n;
			};
		}
	}
	function createWindowEx(
		dwExStyle, lpClassName, lpWindowName, dwStyle,
		x, y, w, h,
		hWndParent, id, hInstance, callback
	) {
		return oSys.Call(
			"user32::CreateWindowEx" + _TCHAR,
			dwExStyle,
			lpClassName,
			lpWindowName,
			dwStyle,
			scale.x(x),
			scale.y(y),
			scale.x(w),
			scale.y(h),
			hWndParent,
			id,
			hInstance,
			callback || 0
		);
	}

	modal && enabled(hMainWnd, false); // Disable main window, to make dialog modal

	AkelPad.ScriptNoMutex(); // Allow other scripts running
	AkelPad.WindowGetMessage(); // Message loop

	AkelPad.WindowUnregisterClass(dialogClass);
}

function formatNum(n) {
	//return Number(n).toLocaleString().replace(/\s*[^\d\s\xa0\u2002\u2003\u2009].*$/, "");
	return String(n).replace(/(\d)(?=(\d{3})+(\D|$))/g, "$1\xa0");
}
function toLocaleNum(n) { // 1.25 -> 1,25
	var localeDelimiter = 1.1.toLocaleString().replace(/^\d+|\d+$/g, "");
	if(!localeDelimiter || /\d/.test(localeDelimiter))
		 localeDelimiter = ".";
	return String(n).replace(/\./, localeDelimiter);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}

function getArg(argName, defaultVal) {
	var args = {};
	for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
		if(/^[-\/](\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
			args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
	getArg = function(argName, defaultVal) {
		argName = argName.toLowerCase();
		return typeof args[argName] == "undefined" // argName in args
			? defaultVal
			: args[argName];
	};
	return getArg(argName, defaultVal);
}
function getArgOrPref(name, type, defaultVal) {
	var argVal = getArg(name);
	return argVal === undefined
		? saveOptions
			? prefs.get(name, type, defaultVal)
			: defaultVal
		: argVal;
}
function Prefs(ns) {
	if(!ns)
		ns = WScript.ScriptBaseName;
	var oSet = AkelPad.ScriptSettings();
	var state  = 0;
	var READ   = 0x1; //POB_READ
	var SAVE   = 0x2; //POB_SAVE
	var CLEAR  = 0x4; //POB_CLEAR
	var DWORD  = 1;   //PO_DWORD
	var BINARY = 2;   //PO_BINARY
	var STRING = 3;   //PO_STRING
	function get(name, type, defaultVal) {
		if(!(state & READ)) {
			end();
			if(!oSet.Begin(ns, READ))
				return defaultVal;
			state = READ;
		}
		var val = oSet.Read(name, type || DWORD);
		if(val === undefined)
			val = defaultVal;
		//oSet.End();
		return val;
	}
	function set(name, val) {
		if(!(state & SAVE)) {
			end();
			if(!oSet.Begin(ns, SAVE))
				return false;
			state = SAVE;
		}
		var sets;
		if(arguments.length == 1)
			sets = name;
		else {
			sets = {};
			sets[name] = val;
		}
		var ok = true;
		for(var name in sets) {
			var val = sets[name];
			var type = typeof val == "number" || typeof val == "boolean" ? DWORD : STRING;
			if(!oSet.Write(name, type, val))
				ok = false;
		}
		//oSet.End();
		return ok;
	}
	function begin(flags) {
		end();
		var ok = oSet.Begin(ns, flags);
		if(ok)
			state = flags;
		return ok;
	}
	function end() {
		if(!state)
			return true;
		var ok = oSet.End();
		if(ok)
			state = 0;
		return ok;
	}
	this.READ   = READ;
	this.SAVE   = SAVE;
	this.CLEAR  = CLEAR;
	this.DWORD  = DWORD;
	this.BINARY = BINARY;
	this.STRING = STRING;
	this.get    = get;
	this.set    = set;
	this.begin  = begin;
	this.end    = end;
}
<download | mirror | development version>
Go to longest line below or above current.

Image Image
Last edited by Infocatcher on Wed May 07, 2014 11:30 am, edited 24 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Sort in columns.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10491#p10491
// Version: 2015-01-08
// Author: KDJ
//
// *** Sort in columns ***
//
// Usage:
//   Call("Scripts::Main", 1, "SortInColumns.js")
//
// Shortcut keys in dialog box:
//   Enter - Sort
//   Esc   - Close
//   Shift+Alt+Right (Left, Down, Up, End, Home, PgDn, PgUp) - move dialog box.
//
// Remark:
//   To effect was clearly visible, you should use a fixed-width font.

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtCaption   = "Sortowanie w kolumnach";
  var sTxtSortRange = "Zakres sortowania";
  var sTxtFrom      = "Od";
  var sTxtTo        = "Do";
  var sTxtColumns   = "&Kolumny:";
  var sTxtLines     = "&Wiersze:";
  var sTxtSortKeys  = "Klucze sortowania - kolumny";
  var sTxtKey       = "Klucz";
  var sTxtDesc      = "Malejąco";
  var sTxtIgCase    = "Ignoruj wlk. liter";
  var sTxtString    = "String";
  var sTxtLocale    = "Alfabetycznie";
  var sTxtNum       = "Numerycznie";
  var sTxtAllKeys   = "Wszystkie klucze";
  var sTxtDescAll   = "&Malejąco";
  var sTxtIgCaseAll = "&Ignoruj wlk. liter";
  var sTxtStringAll = "&String";
  var sTxtLocaleAll = "&Alfabetycznie";
  var sTxtNumAll    = "&Numerycznie";
  var sTxtReverse   = "&Odwróć tylko kolejność wierszy";
  var sTxtCopyToCB  = "Wynik kopiuj do schowka, nie zmieniaj &tekstu";
  var sTxtSort      = "Sortuj";
  var sTxtUndo      = "&Cofnij";
  var sTxtRedo      = "&Powtórz";
  var sTxtNoRangeC  = "Brak zakresu kolumn do sortowania.";
  var sTxtNoRangeL  = "Brak zakresu wierszy do sortowania.";
  var sTxtNoKey1    = "Brak zakresu kolumn w pierwszym kluczu.";
}
else
{
  var sTxtCaption   = "Sort in columns";
  var sTxtSortRange = "Sort range";
  var sTxtFrom      = "From";
  var sTxtTo        = "To";
  var sTxtColumns   = "&Columns:";
  var sTxtLines     = "&Lines:";
  var sTxtSortKeys  = "Sort keys - columns";
  var sTxtKey       = "Key";
  var sTxtDesc      = "Descending";
  var sTxtIgCase    = "Ignore case";
  var sTxtString    = "String";
  var sTxtLocale    = "Alphabetically";
  var sTxtNum       = "Numerically";
  var sTxtAllKeys   = "All keys";
  var sTxtDescAll   = "&Descending";
  var sTxtIgCaseAll = "&Ignore case";
  var sTxtStringAll = "&String";
  var sTxtLocaleAll = "&Alphabetically";
  var sTxtNumAll    = "&Numerically";
  var sTxtReverse   = "Reverse &order of lines only";
  var sTxtCopyToCB  = "Resul&t copy to clipboard, do not replace text";
  var sTxtSort      = "Sort";
  var sTxtUndo      = "&Undo";
  var sTxtRedo      = "&Redo";
  var sTxtNoRangeC  = "There is no range of columns to sort.";
  var sTxtNoRangeL  = "There is no range of lines to sort.";
  var sTxtNoKey1    = "There is no range of columns in first sort key.";
}

var DT_DWORD    = 3;
var BM_GETCHECK = 240;
var BM_SETCHECK = 241;

var oSys       = AkelPad.SystemFunction();
var hMainWnd   = AkelPad.GetMainWnd();
var hEditWnd   = AkelPad.GetEditWnd();
var hGuiFont   = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var aDesc      = [0,0,0,0,0];
var aIgCase    = [1,1,1,1,1];
var aString    = [1,1,1,1,1];
var aLocale    = [0,0,0,0,0];
var aNum       = [0,0,0,0,0];
var bDescAll   = 0;
var bIgCaseAll = 1;
var nMethod    = 1;
var bReverse   = 0;
var bCopyToCB  = 0;
var nUndoLimit = 0;
var nRedoLimit = 0;
var nWordWrap;
var nLastLine;
var nLastCol;
var hWndDlg;
var lpBuffer;
var bGetSel;
var bIsReturn;
var hFocus;
var nWndPosX;
var nWndPosY;

ReadWriteIni(0);

var aWnd        = [];
var IDSORTRANGE = 1000;
var IDFROM      = 1001;
var IDTO        = 1002;
var IDCOLUMNS   = 1003;
var IDBEGCOL    = 1004;
var IDENDCOL    = 1005;
var IDLINES     = 1006;
var IDBEGLINE   = 1007;
var IDENDLINE   = 1008;
var IDSORTK1    = 1009;
var IDSORTK2    = 1010;
var IDSORTK3    = 1011;
var IDSORTK4    = 1012;
var IDSORTK5    = 1013;
var IDSORTK6    = 1014;
var IDFROM1     = 1015;
var IDTO1       = 1016;
var IDALLKEYS   = 1017;
var IDKEY1      = 1018;
var IDBEGCOL1   = 1019;
var IDENDCOL1   = 1020;
var IDDESC1     = 1021;
var IDIGCASE1   = 1022;
var IDSTRING1   = 1023;
var IDLOCALE1   = 1024;
var IDNUM1      = 1025;
var IDKEY2      = 1026;
var IDBEGCOL2   = 1027;
var IDENDCOL2   = 1028;
var IDDESC2     = 1029;
var IDIGCASE2   = 1030;
var IDSTRING2   = 1031;
var IDLOCALE2   = 1032;
var IDNUM2      = 1033;
var IDKEY3      = 1034;
var IDBEGCOL3   = 1035;
var IDENDCOL3   = 1036;
var IDDESC3     = 1037;
var IDIGCASE3   = 1038;
var IDSTRING3   = 1039;
var IDLOCALE3   = 1040;
var IDNUM3      = 1041;
var IDKEY4      = 1042;
var IDBEGCOL4   = 1043;
var IDENDCOL4   = 1044;
var IDDESC4     = 1045;
var IDIGCASE4   = 1046;
var IDSTRING4   = 1047;
var IDLOCALE4   = 1048;
var IDNUM4      = 1049;
var IDKEY5      = 1050;
var IDBEGCOL5   = 1051;
var IDENDCOL5   = 1052;
var IDDESC5     = 1053;
var IDIGCASE5   = 1054;
var IDSTRING5   = 1055;
var IDLOCALE5   = 1056;
var IDNUM5      = 1057;
var IDDESCALL   = 1058;
var IDIGCASEALL = 1059;
var IDSTRINGALL = 1060;
var IDLOCALEALL = 1061;
var IDNUMALL    = 1062;
var IDREVERSE   = 1063;
var IDCOPYTOCB  = 1064;
var IDSORT      = 1065;
var IDUNDO      = 1066;
var IDREDO      = 1067;

var CLASS   = 0;
var WND     = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50012080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER
//Windows               CLASS, WND, EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDSORTRANGE] = ["BUTTON",   0,       0, 0x50000007,  10,  10, 195,  85, sTxtSortRange];
aWnd[IDFROM     ] = ["STATIC",   0,       0, 0x50000000,  80,  25,  55,  13, sTxtFrom];
aWnd[IDTO       ] = ["STATIC",   0,       0, 0x50000000, 140,  25,  55,  13, sTxtTo];
aWnd[IDCOLUMNS  ] = ["STATIC",   0,       0, 0x50000000,  20,  40,  60,  13, sTxtColumns];
aWnd[IDBEGCOL   ] = ["EDIT",     0,   0x200, 0x50012080,  80,  40,  55,  20, ""];
aWnd[IDENDCOL   ] = ["EDIT",     0,   0x200, 0x50012080, 140,  40,  55,  20, ""];
aWnd[IDLINES    ] = ["STATIC",   0,       0, 0x50000000,  20,  65,  60,  13, sTxtLines];
aWnd[IDBEGLINE  ] = ["EDIT",     0,   0x200, 0x50012080,  80,  65,  55,  20, ""];
aWnd[IDENDLINE  ] = ["EDIT",     0,   0x200, 0x50012080, 140,  65,  55,  20, ""];
aWnd[IDSORTK1   ] = ["BUTTON",   0,       0, 0x50000007,  10, 110, 290,  82, sTxtSortKeys];
aWnd[IDSORTK2   ] = ["BUTTON",   0,       0, 0x50000007,  10, 185, 290,  82, ""];
aWnd[IDSORTK3   ] = ["BUTTON",   0,       0, 0x50000007,  10, 260, 290,  82, ""];
aWnd[IDSORTK4   ] = ["BUTTON",   0,       0, 0x50000007,  10, 335, 290,  82, ""];
aWnd[IDSORTK5   ] = ["BUTTON",   0,       0, 0x50000007,  10, 410, 290,  82, ""];
aWnd[IDSORTK6   ] = ["BUTTON",   0,       0, 0x50000007,  10, 485, 290,  82, ""];
aWnd[IDFROM1    ] = ["STATIC",   0,       0, 0x50000000,  80, 125,  55,  13, sTxtFrom];
aWnd[IDTO1      ] = ["STATIC",   0,       0, 0x50000000, 140, 125,  55,  13, sTxtTo];
aWnd[IDALLKEYS  ] = ["STATIC",   0,       0, 0x50000000,  20, 515,  90,  13, sTxtAllKeys];
aWnd[IDKEY1     ] = ["STATIC",   0,       0, 0x50000000,  20, 140,  60,  13, sTxtKey+" &1:"];
aWnd[IDBEGCOL1  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 140,  55,  20, ""];
aWnd[IDENDCOL1  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 140,  55,  20, ""];
aWnd[IDDESC1    ] = ["BUTTON",   0,       0, 0x50010003, 205, 125,  90,  16, sTxtDesc];
aWnd[IDIGCASE1  ] = ["BUTTON",   0,       0, 0x50010003, 205, 145,  90,  16, sTxtIgCase];
aWnd[IDSTRING1  ] = ["BUTTON",   0,       0, 0x50010003,  50, 170,  60,  16, sTxtString];
aWnd[IDLOCALE1  ] = ["BUTTON",   0,       0, 0x50010003, 110, 170,  90,  16, sTxtLocale];
aWnd[IDNUM1     ] = ["BUTTON",   0,       0, 0x50010003, 205, 170,  90,  16, sTxtNum];
aWnd[IDKEY2     ] = ["STATIC",   0,       0, 0x50000000,  20, 215,  60,  13, sTxtKey+" &2:"];
aWnd[IDBEGCOL2  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 215,  55,  20, ""];
aWnd[IDENDCOL2  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 215,  55,  20, ""];
aWnd[IDDESC2    ] = ["BUTTON",   0,       0, 0x50010003, 205, 200,  90,  16, sTxtDesc];
aWnd[IDIGCASE2  ] = ["BUTTON",   0,       0, 0x50010003, 205, 220,  90,  16, sTxtIgCase];
aWnd[IDSTRING2  ] = ["BUTTON",   0,       0, 0x50010003,  50, 245,  60,  16, sTxtString];
aWnd[IDLOCALE2  ] = ["BUTTON",   0,       0, 0x50010003, 110, 245,  90,  16, sTxtLocale];
aWnd[IDNUM2     ] = ["BUTTON",   0,       0, 0x50010003, 205, 245,  90,  16, sTxtNum];
aWnd[IDKEY3     ] = ["STATIC",   0,       0, 0x50000000,  20, 290,  60,  13, sTxtKey+" &3:"];
aWnd[IDBEGCOL3  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 290,  55,  20, ""];
aWnd[IDENDCOL3  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 290,  55,  20, ""];
aWnd[IDDESC3    ] = ["BUTTON",   0,       0, 0x50010003, 205, 275,  90,  16, sTxtDesc];
aWnd[IDIGCASE3  ] = ["BUTTON",   0,       0, 0x50010003, 205, 295,  90,  16, sTxtIgCase];
aWnd[IDSTRING3  ] = ["BUTTON",   0,       0, 0x50010003,  50, 320,  60,  16, sTxtString];
aWnd[IDLOCALE3  ] = ["BUTTON",   0,       0, 0x50010003, 110, 320,  90,  16, sTxtLocale];
aWnd[IDNUM3     ] = ["BUTTON",   0,       0, 0x50010003, 205, 320,  90,  16, sTxtNum];
aWnd[IDKEY4     ] = ["STATIC",   0,       0, 0x50000000,  20, 365,  60,  13, sTxtKey+" &4:"];
aWnd[IDBEGCOL4  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 365,  55,  20, ""];
aWnd[IDENDCOL4  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 365,  55,  20, ""];
aWnd[IDDESC4    ] = ["BUTTON",   0,       0, 0x50010003, 205, 350,  90,  16, sTxtDesc];
aWnd[IDIGCASE4  ] = ["BUTTON",   0,       0, 0x50010003, 205, 370,  90,  16, sTxtIgCase];
aWnd[IDSTRING4  ] = ["BUTTON",   0,       0, 0x50010003,  50, 395,  60,  16, sTxtString];
aWnd[IDLOCALE4  ] = ["BUTTON",   0,       0, 0x50010003, 110, 395,  90,  16, sTxtLocale];
aWnd[IDNUM4     ] = ["BUTTON",   0,       0, 0x50010003, 205, 395,  90,  16, sTxtNum];
aWnd[IDKEY5     ] = ["STATIC",   0,       0, 0x50000000,  20, 440,  60,  13, sTxtKey+" &5:"];
aWnd[IDBEGCOL5  ] = ["EDIT",     0,   0x200, 0x50012080,  80, 440,  55,  20, ""];
aWnd[IDENDCOL5  ] = ["EDIT",     0,   0x200, 0x50012080, 140, 440,  55,  20, ""];
aWnd[IDDESC5    ] = ["BUTTON",   0,       0, 0x50010003, 205, 425,  90,  16, sTxtDesc];
aWnd[IDIGCASE5  ] = ["BUTTON",   0,       0, 0x50010003, 205, 445,  90,  16, sTxtIgCase];
aWnd[IDSTRING5  ] = ["BUTTON",   0,       0, 0x50010003,  50, 470,  60,  16, sTxtString];
aWnd[IDLOCALE5  ] = ["BUTTON",   0,       0, 0x50010003, 110, 470,  90,  16, sTxtLocale];
aWnd[IDNUM5     ] = ["BUTTON",   0,       0, 0x50010003, 205, 470,  90,  16, sTxtNum];
aWnd[IDDESCALL  ] = ["BUTTON",   0,       0, 0x50010003, 205, 500,  90,  16, sTxtDescAll];
aWnd[IDIGCASEALL] = ["BUTTON",   0,       0, 0x50010003, 205, 520,  90,  16, sTxtIgCaseAll];
aWnd[IDSTRINGALL] = ["BUTTON",   0,       0, 0x50010003,  50, 545,  60,  16, sTxtStringAll];
aWnd[IDLOCALEALL] = ["BUTTON",   0,       0, 0x50010003, 110, 545,  90,  16, sTxtLocaleAll];
aWnd[IDNUMALL   ] = ["BUTTON",   0,       0, 0x50010003, 205, 545,  90,  16, sTxtNumAll];
aWnd[IDREVERSE  ] = ["BUTTON",   0,       0, 0x50010003,  20, 575, 170,  16, sTxtReverse];
aWnd[IDCOPYTOCB ] = ["BUTTON",   0,       0, 0x50010003,  20, 595, 270,  16, sTxtCopyToCB];
aWnd[IDSORT     ] = ["BUTTON",   0,       0, 0x50010000, 220,  15,  80,  23, sTxtSort];
aWnd[IDUNDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  47,  80,  23, sTxtUndo];
aWnd[IDREDO     ] = ["BUTTON",   0,       0, 0x50010000, 220,  72,  80,  23, sTxtRedo];

if (hEditWnd)
{
  nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

  if (! AkelPad.SendMessage(hEditWnd, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0))
    AkelPad.SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, 1 /*AESELT_COLUMNON*/, 0);

  nLastLine = AkelPad.SendMessage(hEditWnd, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
  nLastCol  = LineMaxLength() + 1;

  if (AkelPad.WindowRegisterClass(sClassName))
  {
    if (lpBuffer = AkelPad.MemAlloc(256 * _TSIZE))
    {
      hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  0,               //dwExStyle
                  sClassName,      //lpClassName
                  sTxtCaption,     //lpWindowName
                  0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                  0,               //x
                  0,               //y
                  315,             //nWidth
                  650,             //nHeight
                  hMainWnd,        //hWndParent
                  0,               //ID
                  hInstDLL,        //hInstance
                  DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Disable main window, to make dialog modal
        oSys.Call("User32::EnableWindow", hMainWnd, false);

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.MemFree(lpBuffer);
    }
    AkelPad.WindowUnregisterClass(sClassName);
  }

  if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                       aWnd[i][EXSTYLE], //dwExStyle
                       aWnd[i][CLASS],   //lpClassName
                       0,                //lpWindowName
                       aWnd[i][STYLE],   //dwStyle
                       aWnd[i][X],       //x
                       aWnd[i][Y],       //y
                       aWnd[i][W],       //nWidth
                       aWnd[i][H],       //nHeight
                       hWnd,             //hWndParent
                       i,                //ID
                       hInstDLL,         //hInstance
                       0);               //lpParam
      SetWindowFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][TXT]);
    }

    CheckButtonsAll(0);
    CheckUndoRedo();

    bGetSel = GetSelection();

    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);
  }

  else if (uMsg == 7) //WM_SETFOCUS
  {
    oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    AkelPad.SendMessage(aWnd[IDBEGCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
  }

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if (wParam == 9) //VK_TAB
      SetSelection();
    else if (wParam == 27) //VK_ESCAPE
      oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (! bIsReturn)
      {
        hFocus = oSys.Call("User32::GetFocus");
        if ((hFocus != aWnd[IDSORT][WND]) && (hFocus != aWnd[IDUNDO][WND]) && (hFocus != aWnd[IDREDO][WND]))
          oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDSORT, 0);
      }
    }
  }

  else if (uMsg == 257) //WM_KEYUP
    bIsReturn = 0;

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/)))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow(hMainWnd, hWnd, "R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow(hMainWnd, hWnd, "L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow(hMainWnd, hWnd, "D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow(hMainWnd, hWnd, "U");
    else if (wParam == 0x23) //VK_END
      MoveWindow(hMainWnd, hWnd, "E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow(hMainWnd, hWnd, "H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow(hMainWnd, hWnd, "B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow(hMainWnd, hWnd, "T");
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);

    if ((nLowParam == IDBEGCOL)  || (nLowParam == IDENDCOL)  ||
        (nLowParam == IDBEGLINE) || (nLowParam == IDENDLINE) ||
        (nLowParam == IDBEGCOL1) || (nLowParam == IDENDCOL1) ||
        (nLowParam == IDBEGCOL2) || (nLowParam == IDENDCOL2) ||
        (nLowParam == IDBEGCOL3) || (nLowParam == IDENDCOL3) ||
        (nLowParam == IDBEGCOL4) || (nLowParam == IDENDCOL4) ||
        (nLowParam == IDBEGCOL5) || (nLowParam == IDENDCOL5))
    {
      CheckEditValue(nLowParam);
      if (bGetSel)
        SetSelection();
    }

    else if (((nLowParam >= IDDESC1) && (nLowParam <= IDNUM1)) ||
             ((nLowParam >= IDDESC2) && (nLowParam <= IDNUM2)) ||
             ((nLowParam >= IDDESC3) && (nLowParam <= IDNUM3)) ||
             ((nLowParam >= IDDESC4) && (nLowParam <= IDNUM4)) ||
             ((nLowParam >= IDDESC5) && (nLowParam <= IDNUM5)))
    {
      CheckButtons1(nLowParam);
      SetSelection();
    }

    else if ((nLowParam >= IDDESCALL) && (nLowParam <= IDCOPYTOCB))
    {
      CheckButtonsAll(nLowParam);
      SetSelection();
    }

    else if (nLowParam == IDSORT)
    {
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
      SetSelection();
      if (SortColumns())
      {
        SetSelection();
        CheckUndoRedo(nLowParam);
      }
    }

    else if (nLowParam == IDUNDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    }

    else if (nLowParam == IDREDO)
    {
      bIsReturn = 1;
      CheckUndoRedo(nLowParam);
      oSys.Call("User32::SetFocus", aWnd[IDBEGCOL][WND]);
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    ReadWriteIni(1);

    //Enable main window
    oSys.Call("User32::EnableWindow", hMainWnd, true);
    //Destroy dialog
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("User32::PostQuitMessage", 0);
  }

  else
    SetDefID(hWnd);

  return 0;
}

function SetWindowFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function MoveWindow(hWndParent, hWnd, vAction)
{
  var aRectParent;
  var aRect;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("User32::GetDesktopWindow");

  aRectParent = GetWindowPos(hWndParent);
  aRect       = GetWindowPos(hWnd);

  nX = aRect.left;
  nY = aRect.top;

  if (vAction == "R") //Move right
    nX = aRect.left + ((aRect.left < aRectParent.right - 50) ? 20 : 0);
  else if (vAction == "L") //Move left
    nX = aRect.left - ((aRect.right > aRectParent.left + 50) ? 20 : 0);
  else if (vAction == "D") //Move down
    nY = aRect.top + ((aRect.top < aRectParent.bottom - 50) ? 20 : 0);
  else if (vAction == "U") //Move up
    nY = aRect.top - ((aRect.bottom > aRectParent.top + 50) ? 20 : 0);
  else if (vAction == "E") //Move end (right)
    nX = aRect.left + (aRectParent.right - aRect.right);
  else if (vAction == "H") //Move home (left)
    nX = aRect.left + (aRectParent.left - aRect.left);
  else if (vAction == "B") //Move bottom
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  else if (vAction == "T") //Move top
    nY = aRect.top + (aRectParent.top - aRect.top);
  else if (vAction == "C") //Center window
  {
    nX = aRectParent.left + ((aRectParent.right  - aRectParent.left) / 2 - (aRect.right  - aRect.left) / 2);
    nY = aRectParent.top  + ((aRectParent.bottom - aRectParent.top)  / 2 - (aRect.bottom - aRect.top)  / 2);
  }
  else if (vAction == "LT") //Move left top
  {
    nX = aRectParent.left;
    nY = aRectParent.top;
  }
  else if (vAction == "RT") //Move right top
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRectParent.top;
  }
  else if (vAction == "LB") //Move left bottom
  {
    nX = aRectParent.left;
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else if (vAction == "RB") //Move right bottom
  {
    nX = aRect.left + (aRectParent.right - aRect.right);
    nY = aRect.top + (aRectParent.bottom - aRect.bottom);
  }
  else
  {
    nX = vAction[0];
    nY = vAction[1];
  }

  oSys.Call("User32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var aRect  = [];

  oSys.Call("User32::GetWindowRect", hWnd, lpRect);

  aRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  aRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  aRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  aRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return aRect;
}

function LoWord(nParam)
{
  return (nParam & 0xFFFF);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("User32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDUNDO) && (nID != IDREDO))
    nID = IDSORT;

  oSys.Call("User32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var aRect;
  var oFile;
  var sIniTxt;

  if (bWrite)
  {
    aRect = GetWindowPos(hWndDlg);

    sIniTxt = 'nWndPosX='   + aRect.left + ';\r\n' +
              'nWndPosY='   + aRect.top  + ';\r\n' +
              'aDesc=['     + aDesc + '];\r\n' +
              'aIgCase=['   + aIgCase + '];\r\n' +
              'aString=['   + aString + '];\r\n' +
              'aLocale=['   + aLocale + '];\r\n' +
              'aNum=['      + aNum + '];\r\n' +
              'bDescAll='   + bDescAll + ';\r\n' +
              'bIgCaseAll=' + bIgCaseAll + ';\r\n' +
              'nMethod='    + nMethod + ';\r\n' +
              'bReverse='   + bReverse + ';\r\n' +
              'bCopyToCB='  + bCopyToCB + ';'

    oFile = oFSO.OpenTextFile(sIniName, 2, true, 0);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniName));
    }
    catch (oError)
    {
    }
  }
}

function CheckButtonsAll(nButton)
{
  var nDif = IDDESC2 - IDDESC1;
  var i;

  if (nButton == IDDESCALL)
  {
    bDescAll = AkelPad.SendMessage(aWnd[IDDESCALL][WND], BM_GETCHECK, 0, 0);
    aDesc    = [bDescAll, bDescAll, bDescAll, bDescAll, bDescAll];
  }
  else if (nButton == IDIGCASEALL)
  {
    bIgCaseAll = AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_GETCHECK, 0, 0);
    aIgCase    = [bIgCaseAll, bIgCaseAll, bIgCaseAll, bIgCaseAll, bIgCaseAll];
  }
  else if ((nButton == IDSTRINGALL) || (nButton == IDLOCALEALL) || (nButton == IDNUMALL))
  {
    if (nMethod == nButton - IDSTRINGALL + 1)
      nMethod = 0;
    else
    {
      nMethod = nButton - IDSTRINGALL + 1;
      aString = [0,0,0,0,0];
      aLocale = [0,0,0,0,0];
      aNum    = [0,0,0,0,0];
      if (nMethod == 1)
        aString = [1,1,1,1,1];
      else if (nMethod == 2)
        aLocale = [1,1,1,1,1];
      else if (nMethod == 3)
        aNum = [1,1,1,1,1];
    }
  }
  else if (nButton == IDREVERSE)
    bReverse = AkelPad.SendMessage(aWnd[IDREVERSE][WND],  BM_GETCHECK, 0, 0);
  else if (nButton == IDCOPYTOCB)
    bCopyToCB  = AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_GETCHECK, 0, 0);

  AkelPad.SendMessage(aWnd[IDDESCALL][WND],   BM_SETCHECK, bDescAll,       0);
  AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_SETCHECK, bIgCaseAll,     0);
  AkelPad.SendMessage(aWnd[IDSTRINGALL][WND], BM_SETCHECK, (nMethod == 1), 0);
  AkelPad.SendMessage(aWnd[IDLOCALEALL][WND], BM_SETCHECK, (nMethod == 2), 0);
  AkelPad.SendMessage(aWnd[IDNUMALL][WND],    BM_SETCHECK, (nMethod == 3), 0);
  AkelPad.SendMessage(aWnd[IDREVERSE][WND],   BM_SETCHECK, bReverse,       0);
  AkelPad.SendMessage(aWnd[IDCOPYTOCB][WND],  BM_SETCHECK, bCopyToCB,      0);

  for (i = 0; i < 5; ++i)
  {
    AkelPad.SendMessage(aWnd[IDDESC1   + i * nDif][WND], BM_SETCHECK, aDesc[i],   0);
    AkelPad.SendMessage(aWnd[IDIGCASE1 + i * nDif][WND], BM_SETCHECK, aIgCase[i], 0);
    AkelPad.SendMessage(aWnd[IDSTRING1 + i * nDif][WND], BM_SETCHECK, aString[i], 0);
    AkelPad.SendMessage(aWnd[IDLOCALE1 + i * nDif][WND], BM_SETCHECK, aLocale[i], 0);
    AkelPad.SendMessage(aWnd[IDNUM1    + i * nDif][WND], BM_SETCHECK, aNum[i],    0);
  }

  for (i = IDSORTK1; i <= IDNUMALL; ++i)
    oSys.Call("User32::EnableWindow", aWnd[i][WND], ! bReverse);
}

function CheckButtons1(nButton)
{
  var nDif = IDDESC2 - IDDESC1;
  var nKey;
  var i;

  if (((nButton - IDDESC1) % nDif) == 0)
  {
    aDesc[(nButton - IDDESC1) / nDif] = AkelPad.SendMessage(aWnd[nButton][WND], BM_GETCHECK, 0, 0);
    if (aDesc[0] && aDesc[1] && aDesc[2] && aDesc[3] && aDesc[4])
      bDescAll = 1;
    else
      bDescAll = 0;
    AkelPad.SendMessage(aWnd[IDDESCALL][WND], BM_SETCHECK, bDescAll, 0);
  }
  else if (((nButton - IDIGCASE1) % nDif) == 0)
  {
    aIgCase[(nButton - IDIGCASE1) / nDif] = AkelPad.SendMessage(aWnd[nButton][WND], BM_GETCHECK, 0, 0);
    if (aIgCase[0] && aIgCase[1] && aIgCase[2] && aIgCase[3] && aIgCase[4])
      bIgCaseAll = 1;
    else
      bIgCaseAll = 0;
    AkelPad.SendMessage(aWnd[IDIGCASEALL][WND], BM_SETCHECK, bIgCaseAll, 0);
  }
  else
  {
    nKey = Math.floor((nButton - IDDESC1) / nDif);
    aString[nKey] = 0;
    aLocale[nKey] = 0;
    aNum[nKey]    = 0;

    if (((nButton - IDSTRING1) % nDif) == 0)
      aString[nKey] = 1;
    else if (((nButton - IDLOCALE1) % nDif) == 0)
      aLocale[nKey] = 1;
    else if (((nButton - IDNUM1) % nDif) == 0)
      aNum[nKey] = 1;

    AkelPad.SendMessage(aWnd[IDSTRING1 + nKey * nDif][WND], BM_SETCHECK, aString[nKey], 0);
    AkelPad.SendMessage(aWnd[IDLOCALE1 + nKey * nDif][WND], BM_SETCHECK, aLocale[nKey], 0);
    AkelPad.SendMessage(aWnd[IDNUM1    + nKey * nDif][WND], BM_SETCHECK, aNum[nKey],    0);

    if (aString[0] && aString[1] && aString[2] && aString[3] && aString[4])
      nMethod = 1;
    else if (aLocale[0] && aLocale[1] && aLocale[2] && aLocale[3] && aLocale[4])
      nMethod = 2;
    else if (aNum[0] && aNum[1] && aNum[2] && aNum[3] && aNum[4])
      nMethod = 3;
    else
      nMethod = 0;

    AkelPad.SendMessage(aWnd[IDSTRINGALL][WND], BM_SETCHECK, (nMethod == 1), 0);
    AkelPad.SendMessage(aWnd[IDLOCALEALL][WND], BM_SETCHECK, (nMethod == 2), 0);
    AkelPad.SendMessage(aWnd[IDNUMALL][WND],    BM_SETCHECK, (nMethod == 3), 0);
  }
}

function CheckUndoRedo(nButton)
{
  var sTxtUndo = aWnd[IDUNDO][TXT];
  var sTxtRedo = aWnd[IDREDO][TXT];

  if (nButton == IDSORT)
  {
    if (nUndoLimit < AkelPad.SendMessage(hEditWnd, 3084 /*AEM_GETUNDOLIMIT*/, 0, 0))
      ++nUndoLimit;
    nRedoLimit = 0;
  }
  else if ((nButton == IDUNDO) && (nUndoLimit))
  {
    --nUndoLimit;
    ++nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3077 /*AEM_UNDO*/, 0, 0);
  }
  else if ((nButton == IDREDO) && (nRedoLimit))
  {
    ++nUndoLimit;
    --nRedoLimit;
    AkelPad.SendMessage(hEditWnd, 3078 /*AEM_REDO*/, 0, 0);
  }

  if (nUndoLimit)
    sTxtUndo += " (" + nUndoLimit + ")";
  if (nRedoLimit)
    sTxtRedo += " (" + nRedoLimit + ")";

  SetWindowFontAndText(aWnd[IDUNDO][WND], hGuiFont, sTxtUndo);
  SetWindowFontAndText(aWnd[IDREDO][WND], hGuiFont, sTxtRedo);

  oSys.Call("User32::EnableWindow", aWnd[IDUNDO][WND], nUndoLimit);
  oSys.Call("User32::EnableWindow", aWnd[IDREDO][WND], nRedoLimit);
}

function CheckEditValue(nIdWnd)
{
  var sEditValue;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[nIdWnd][WND], lpBuffer, 256);
  sEditValue = AkelPad.MemRead(lpBuffer, _TSTR);

  if ((nIdWnd == IDBEGLINE) || (nIdWnd == IDENDLINE))
  {
    if (sEditValue == 0)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "1");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastLine)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastLine));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }

  else if ((nIdWnd == IDBEGCOL)  || (nIdWnd == IDENDCOL) ||
           (nIdWnd == IDBEGCOL1) || (nIdWnd == IDENDCOL1))
  {
    if (sEditValue == 0)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "1");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastCol)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastCol));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }

  else if ((nIdWnd == IDBEGCOL2) || (nIdWnd == IDENDCOL2) ||
           (nIdWnd == IDBEGCOL3) || (nIdWnd == IDENDCOL3) ||
           (nIdWnd == IDBEGCOL4) || (nIdWnd == IDENDCOL4) ||
           (nIdWnd == IDBEGCOL5) || (nIdWnd == IDENDCOL5))
  {
    if (sEditValue == "0")
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, "");
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
    else if (sEditValue > nLastCol)
    {
      SetWindowFontAndText(aWnd[nIdWnd][WND], hGuiFont, String(nLastCol));
      AkelPad.SendMessage(aWnd[nIdWnd][WND], 177 /*EM_SETSEL*/, 0, -1);
    }
  }
}

function GetSelection()
{
  var lpBegSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpEndSel = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var nLine1, nLine2, nCol1, nCol2;

  AkelPad.SendMessage(hEditWnd, 3123 /*AEM_EXGETSEL*/, lpBegSel, lpEndSel);

  nLine1 = AkelPad.MemRead(lpBegSel, DT_DWORD) + 1;
  nLine2 = AkelPad.MemRead(lpEndSel, DT_DWORD) + 1;

  if (AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) < AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD))
  {
    nCol1 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    nCol2 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
  }
  else
  {
    nCol1 = AkelPad.MemRead(_PtrAdd(lpEndSel, _X64 ? 16 : 8), DT_DWORD) + 1;
    nCol2 = AkelPad.MemRead(_PtrAdd(lpBegSel, _X64 ? 16 : 8), DT_DWORD) + 1;
  }

  SetWindowFontAndText(aWnd[IDBEGLINE][WND], hGuiFont, String(nLine1));
  SetWindowFontAndText(aWnd[IDENDLINE][WND], hGuiFont, String(nLine2));
  SetWindowFontAndText(aWnd[IDBEGCOL][WND],  hGuiFont, String(nCol1));
  SetWindowFontAndText(aWnd[IDENDCOL][WND],  hGuiFont, String(nCol2));
  SetWindowFontAndText(aWnd[IDBEGCOL1][WND], hGuiFont, String(nCol1));
  SetWindowFontAndText(aWnd[IDENDCOL1][WND], hGuiFont, String(nCol2));

  AkelPad.MemFree(lpBegSel);
  AkelPad.MemFree(lpEndSel);
  return 1;
}

function SetSelection()
{
  var hWndFocus = oSys.Call("User32::GetFocus");
  var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpBegSel  = lpSelect;
  var lpEndSel  = _PtrAdd(lpSelect, _X64 ? 24 : 12);
  var lpSelFlag = _PtrAdd(lpSelect, _X64 ? 48 : 24);
  var nLine1, nLine2, nCol1, nCol2, i;

  for (i = 1000; i < aWnd.length; ++i)
  {
    if (aWnd[i][WND] == hWndFocus)
      break;
  }

  if ((i >= IDBEGCOL1) && (i <= IDNUM1))
    i = IDBEGCOL1;
  else if ((i >= IDBEGCOL2) && (i <= IDNUM2))
    i = IDBEGCOL2;
  else if ((i >= IDBEGCOL3) && (i <= IDNUM3))
    i = IDBEGCOL3;
  else if ((i >= IDBEGCOL4) && (i <= IDNUM4))
    i = IDBEGCOL4;
  else if ((i >= IDBEGCOL5) && (i <= IDNUM5))
    i = IDBEGCOL5;
  else
    i = IDBEGCOL;

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[i][WND], lpBuffer, 256);
  nCol1 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[i + 1][WND], lpBuffer, 256);
  nCol2 = Number(AkelPad.MemRead(lpBuffer, _TSTR)) - 1;

  if ((nCol1 < 0) || (nCol2 < 0))
    nCol1 = nCol2 = 0;

  AkelPad.MemCopy(lpBegSel, nLine1, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpBegSel, _X64 ? 16 : 8), nCol1, DT_DWORD);
  AkelPad.MemCopy(lpEndSel, nLine2, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpEndSel, _X64 ? 16 : 8), nCol2, DT_DWORD);
  AkelPad.MemCopy(lpSelFlag, 1, DT_DWORD);

  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpBegSel);
  AkelPad.SendMessage(hEditWnd, 3132 /*AEM_INDEXUPDATE*/, 0, lpEndSel);

  AkelPad.SendMessage(hEditWnd, 3126 /*AEM_SETSEL*/, 0, lpSelect);

  AkelPad.MemFree(lpSelect);
}

function LineMaxLength()
{
  var nMaxLenL = 0;
  var nBegLine;
  var nLenLine;
  var i;

  for (i = 0; i < nLastLine; ++i)
  {
    nBegLine = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, i, 0);
    nLenLine = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine, 0);
    if (nLenLine > nMaxLenL)
      nMaxLenL = nLenLine;
  }

  return nMaxLenL;
}

function SortColumns()
{
  var aDesc   = new Array(5);
  var aIgCase = new Array(5);
  var aString = new Array(5);
  var aLocale = new Array(5);
  var aNum    = new Array(5);
  var aCol    = [[], [], [], [], [], []];
  var aTxt    = [];
  var sText   = "";
  var nDif    = IDBEGCOL2 - IDBEGCOL1;
  var nLine1;
  var nLine2;
  var i;

  for (i = 0; i < 5; ++i)
  {
    aDesc[i]   = AkelPad.SendMessage(aWnd[IDDESC1   + i * nDif][WND], BM_GETCHECK, 0, 0);
    aIgCase[i] = AkelPad.SendMessage(aWnd[IDIGCASE1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aString[i] = AkelPad.SendMessage(aWnd[IDSTRING1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aLocale[i] = AkelPad.SendMessage(aWnd[IDLOCALE1 + i * nDif][WND], BM_GETCHECK, 0, 0);
    aNum[i]    = AkelPad.SendMessage(aWnd[IDNUM1    + i * nDif][WND], BM_GETCHECK, 0, 0);
  }

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL][WND], lpBuffer, 256);
  aCol[0][0] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL][WND], lpBuffer, 256);
  aCol[0][1] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGLINE][WND], lpBuffer, 256);
  nLine1 = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDLINE][WND], lpBuffer, 256);
  nLine2 = Number(AkelPad.MemRead(lpBuffer, _TSTR));
  for (i = 1; i < 6; ++i)
  {
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEGCOL1 + (i - 1) * nDif][WND], lpBuffer, 256);
    aCol[i][0] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
    oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDENDCOL1 + (i - 1) * nDif][WND], lpBuffer, 256);
    aCol[i][1] = Number(AkelPad.MemRead(lpBuffer, _TSTR));
    if ((aCol[i][0] == 0) || (aCol[i][1] == 0) || (aCol[i][0] == aCol[i][1]))
    {
      aCol[i][0] = aCol[i][1] = 0;
      SetWindowFontAndText(aWnd[IDBEGCOL1 + (i - 1) * nDif][WND], hGuiFont, String(aCol[i][0]));
      SetWindowFontAndText(aWnd[IDENDCOL1 + (i - 1) * nDif][WND], hGuiFont, String(aCol[i][1]));
    }
  }

  if (aCol[0][0] == aCol[0][1])
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeC, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  if (nLine1 == nLine2)
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoRangeL, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDLINE][WND]);
    AkelPad.SendMessage(aWnd[IDENDLINE][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  if ((aCol[1][0] == aCol[1][1]) && (! bReverse))
  {
    AkelPad.MessageBox(hWndDlg, sTxtNoKey1, sTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("User32::SetFocus", aWnd[IDENDCOL1][WND]);
    AkelPad.SendMessage(aWnd[IDENDCOL1][WND], 177 /*EM_SETSEL*/, 0, -1);
    return 0;
  }

  for (i = 5; i >= 0; --i)
  {
    if (aCol[i][0] == 0)
    {
      aCol.splice(i, 1);
      aDesc.splice(i - 1, 1);
      aIgCase.splice(i - 1, 1);
      aString.splice(i - 1, 1);
      aLocale.splice(i - 1, 1);
      aNum.splice(i - 1, 1);
    }
    else
    {
      --aCol[i][0];
      --aCol[i][1];
    }
  }
  --nLine1;
  --nLine2;

  if (bReverse)
  {
    aTxt  = GetTextRangeColumn([nLine1, aCol[0][0]], [nLine2, aCol[0][1]]);
    sText = aTxt.reverse().join("\r");
  }
  else
  {
    aTxt.length = aCol.length;
    for (i = 0; i < aTxt.length; ++i)
      aTxt[i] = GetTextRangeColumn([nLine1, aCol[i][0]], [nLine2, aCol[i][1]]);

    aTxt = ArrayTransp(aTxt);

    ArraySort(aTxt, aDesc, aIgCase, aString, aLocale, aNum);

    for (i = 0; i < aTxt.length; ++i)
    {
      sText += aTxt[i][0] + "\r";
    }
    sText = sText.slice(0, -1);
  }

  AkelPad.SendMessage(aWnd[IDBEGCOL][WND], 177 /*EM_SETSEL*/, 0, -1);

  if (bCopyToCB)
  {
    AkelPad.SetClipboardText(sText);
    return 0;
  }
  else
  {
    AkelPad.ReplaceSel(sText);
    return 1;
  }
}

function GetTextRangeColumn(aBeg, aEnd, bReturnText, nNewLine, bFillSpaces)
{
  var nBegLine1;
  var nBegLine2;
  var nLenLine2;
  var nLine1;
  var nLine2;
  var nCol1;
  var nCol2;
  var aLines;
  var nWidth;
  var i;

  if (aBeg[0] < aEnd[0])
  {
    nLine1 = aBeg[0];
    nLine2 = aEnd[0];
  }
  else
  {
    nLine1 = aEnd[0];
    nLine2 = aBeg[0];
  }

  if (aBeg[1] < aEnd[1])
  {
    nCol1 = aBeg[1];
    nCol2 = aEnd[1];
  }
  else
  {
    nCol1 = aEnd[1];
    nCol2 = aBeg[1];
  }

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
  aLines    = AkelPad.GetTextRange(nBegLine1, nBegLine2 + nLenLine2, 1 /*"\r"*/).split("\r");
  nWidth    = nCol2 - nCol1;

  for (i = 0; i < aLines.length; ++i)
  {
    aLines[i] = aLines[i].substring(nCol1, nCol2);
    if (bFillSpaces)
      while (aLines[i].length < nWidth)
        aLines[i] += " ";
  }

  if (bReturnText)
  {
    if ((! nNewLine) || (nNewLine == 1))
      pNewLine = "\r";
    else if (nNewLine == 2)
      pNewLine = "\n";
    else
      pNewLine = "\r\n";

    return aLines.join(pNewLine);
  }
  else
    return aLines;
}

function ArrayTransp(aArr)
{
  var nLen1 = aArr.length;
  var nLen2 = aArr[0].length;
  var aArr2 = [];
  var i, n;

  aArr2.length = nLen2;

  for (n = 0; n < nLen2; ++n)
  {
    aArr2[n] = [];
    for (i = 0; i < nLen1; ++i)
    {
      aArr2[n].push(aArr[i][n]);
    }
  }
  return aArr2;
}

function ArraySort(aTxt, aDesc, aIgCase, aString, aLocale, aNum)
{
  var lpStrA = AkelPad.MemAlloc(nLastCol * _TSIZE);
  var lpStrB = AkelPad.MemAlloc(nLastCol * _TSIZE);
  var nComp;
  var i;

  aTxt.sort(function(a, b) {
    for (i = 0; i < aDesc.length; ++i)
    {
      nComp = CompareValue(a[i + 1], b[i + 1], lpStrA, lpStrB, aDesc[i], aIgCase[i], aString[i], aLocale[i], aNum[i]);
      if (nComp != 0)
        return nComp;
    }
    return 0; });

  AkelPad.MemFree(lpStrA);
  AkelPad.MemFree(lpStrB);
}

function CompareValue(ValA, ValB, lpStrA, lpStrB, bDesc, bIgCase, bString, bLocale, bNum)
{
  var nResult;

  if (bString)
  {
    if (bIgCase)
    {
      ValA = ValA.toUpperCase();
      ValB = ValB.toUpperCase();
    }
    if (ValA > ValB)
      nResult = bDesc ? -1 : 1;
    else if (ValA < ValB)
      nResult = bDesc ? 1 : -1;
    else
      nResult = 0;
  }
  else if (bLocale)
  {
    AkelPad.MemCopy(lpStrA, ValA, _TSTR);
    AkelPad.MemCopy(lpStrB, ValB, _TSTR);
    nResult = oSys.Call("Kernel32::lstrcmp" + (bIgCase ? "i" : "") + _TCHAR, lpStrA, lpStrB);
    if (bDesc)
      nResult = -nResult;
  }
  else
  {
    var oRegExp = /(-?\d+\.?\d*)|(-?\.\d+)/;

    ValA    = oRegExp.exec(ValA);
    ValB    = oRegExp.exec(ValB);
    ValA    = ValA ? parseFloat(ValA[0]) : 0;
    ValB    = ValB ? parseFloat(ValB[0]) : 0;
    nResult = bDesc ? (ValB - ValA) : (ValA - ValB);
  }

  return nResult;
}

Last edited by KDJ on Thu Jan 08, 2015 8:38 pm, edited 15 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7081#p7081

/// Convert tabulation to space for AkelPad 4.x.x

// Modified by Infocatcher
// version: 2010-12-29

var hMainWnd=AkelPad.GetMainWnd();
var hWndEdit=AkelPad.GetEditWnd();
var oSys=AkelPad.SystemFunction();
var pScriptName=WScript.ScriptName;
var pSelText;
var pResult;
var pSpaces;
var nSelStart;
var nSelEnd;
var nTabStop;
var nColumn;
var nSpaceCount;
var a;
var b;

if (hMainWnd)
{
  if (AkelPad.IsAkelEdit())
  {
    nSelStart=AkelPad.GetSelStart();
    nSelEnd=AkelPad.GetSelEnd();
    if (nSelStart == nSelEnd)
    {
      //AkelPad.SetSel(0, -1);
      nSelStart = 0;
      nSelEnd = -1;
      pSelText = AkelPad.GetTextRange(0, -1);
    }
    else
    {
      //SelCompleteLine(hWndEdit, nSelStart, nSelEnd);
      var sel = GetCompleteLine(hWndEdit, nSelStart, nSelEnd);
      nSelStart = sel[0];
      nSelEnd   = sel[1];
      pSelText = AkelPad.GetTextRange(nSelStart, nSelEnd);
    }
    //nSelStart=AkelPad.GetSelStart();
    //nSelEnd=AkelPad.GetSelEnd();
    //pSelText=AkelPad.GetSelText();

    nTabStop=AkelPad.SendMessage(hWndEdit, 3239 /*AEM_GETTABSTOP*/, 0, 0);
    pResult="";

    if (pSelText.indexOf("\t") == -1)
    {
      pResult = pSelText.replace(
        new RegExp("^( {" + nTabStop + "})+", "mg"),
        function(s)
        {
          return new Array(s.length/nTabStop + 1).join("\t");
        }
      );
    }
    else
    {
      for (a=0, b=0, nColumn=0; b < pSelText.length; ++b)
      {
        if (pSelText.charAt(b) == '\t')
        {
          nSpaceCount=nTabStop - nColumn % nTabStop;
          nColumn+=nSpaceCount;
          for (pSpaces=""; nSpaceCount; --nSpaceCount)
            pSpaces=pSpaces + " ";
          pResult=pResult + pSelText.substr(a, b - a) + pSpaces;
          a=b + 1;
        }
        else if (pSelText.charAt(b) == '\r')
          nColumn=0;
        else
          ++nColumn;
      }
      pResult=pResult + pSelText.substr(a, b - a);
   }

    //AkelPad.ReplaceSel(pResult);
    insertNoScroll(pResult, nSelStart, nSelEnd);
  }
}


//Functions
function GetCompleteLine(hWnd, nMinSel, nMaxSel)
{
  var nMinLine;
  var nMaxLine;
  var nMinLineIndex;
  var nMaxLineIndex;
  var nMaxLineLength;

  if (nMinSel < nMaxSel)
  {
    nMinLine=AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMinSel);
    nMaxLine=AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMaxSel);
    nMinLineIndex=AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nMinLine, 0);
    nMaxLineIndex=AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nMaxLine, 0);
    nMaxLineLength=AkelPad.SendMessage(hWnd, 193 /*EM_LINELENGTH*/, nMaxSel, 0);

    if (nMaxLineIndex == nMaxSel) --nMaxLine;
    else if (nMaxLineLength) nMaxSel=nMaxLineIndex + nMaxLineLength + 1;
    nMinSel=nMinLineIndex;

    //AkelPad.SetSel(nMinSel, nMaxSel);
    //return nMaxLine - nMinLine + 1;
    return [nMinSel, nMaxSel];
  }
  //return 0;
  throw new Error("GetCompleteLine: nMinSel >= nMaxSel");
}
function insertNoScroll(str, nSelStart, nSelEnd) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	//var hWndEdit = AkelPad.GetEditWnd();
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	AkelPad.SetSel(nSelStart, nSelEnd);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download>
Modified version of TabsToSpaces.js.
Added text inserting without scroll and backward replacement, if text doesn't contain tabulations.
Last edited by Infocatcher on Fri May 11, 2012 6:06 pm, edited 1 time in total.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Make AkelPad semitransparent

Code: Select all

//! === [transparency.js] ===
//!	FeyFre (c) 2010
//!
//!	Sets transparency level of Akelpad main window(for Windows 2000/XP and newer)
//!	Arguments:
//!		* integer transparency level to set in range 0 till 255 
//!		* "m" or "M" to set minimal and maximal alpha value
//!		* +value -value to change current transparency level
//!
//! Example:
//!		Fully visible
//!			Call("Scripts::Main", 1, "transparency.js", "m")
//!		Fully transparent(do not recommended to use unless you have assigned hotkey to reset transparency level)
//!			Call("Scripts::Main", 1, "transparency.js", "M")
//!		Semitransparent:
//!			Call("Scripts::Main", 1, "transparency.js", "127")
//!		Increase transparency
//!			Call("Scripts::Main", 1, "transparency.js", "+33")
//!		Decrease transparency
//!			Call("Scripts::Main", 1, "transparency.js", "-33")
//!
var ACTION_NONE = -1;
var ACTION_SET = 0
var ACTION_INC = 1;
//! Defaults
var action = ACTION_SET;
var data = 127;
var oSys = AkelPad.SystemFunction();
//! Parameters
if(WScript.Arguments.length > 0)
{
	var arg = WScript.Arguments(0);
	if(arg=='m')
	{
		action = ACTION_SET;
		data = 0;
	}
	else if(arg=='M')
	{
		action = ACTION_SET;
		data = 255;
	}
	else
	{
		action = ACTION_NONE;
		if(Number(arg) != NaN)
		{
			var ch = arg.charAt(0);
			data = Number(arg);
			if(ch =='+' || ch == '-')
			{
				action = ACTION_INC;
				//data = - data;
			}
			else
			{
				action = ACTION_SET;
			}
		}
	}
}

if(action != ACTION_NONE)
{
	var akel = AkelPad.GetMainWnd();
	//! We should add WS_EX_LAYERED extended style for windows in order to enable transparency
	var styleex = oSys.Call("user32::GetWindowLong"+_TCHAR,akel,-20/*GWL_EXSTYLE*/);
	styleex |= 0x00080000/*WS_EX_LAYERED*/;
	oSys.Call("user32::SetWindowLong"+_TCHAR,akel,-20/*GWL_EXSTYLE*/,styleex);
	do
	{
		if(action == ACTION_INC)
		{
			var mem = AkelPad.MemAlloc(1);
			var memfl = AkelPad.MemAlloc(4);
			AkelPad.MemCopy(memfl, 2, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(mem, 0, 5 /*DT_BYTE*/);
			//! Get current transparency level if any
			if(oSys.Call("user32::GetLayeredWindowAttributes",akel,0,mem,memfl))
			{
				var fl = AkelPad.MemRead(memfl, 3 /*DT_DWORD*/);
				if(fl & 2)
				{
					//! Do increase
					data = 255-AkelPad.MemRead(mem, 5 /*DT_BYTE*/) + data;
				}
				else data = 0;
			}
			AkelPad.MemFree(memfl);
			AkelPad.MemFree(mem);
		}
		//! Range checks
		if(data < 0) data = 0;
		if(data > 255) data = 255
		//! Set transparency
		oSys.Call("user32::SetLayeredWindowAttributes",akel,0,255-data,2/*LWA_ALPHA*/);
	}
	while(0);
	//! Force to redraw window, since we have changed extended style
	oSys.Call("user32::SetWindowPos",akel,0,0,0,0,0,55/*SWP_NOSIZE|SWP_NOMOVE|SWP_ZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED*/);
}

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Set Coder's syntax theme by extension Download
(!! REQUIRED: WIN32 Constant library !!)
Script also demonstrates concept of creating AkelPad dockbars(like QSearch, HexSel, Explorer etc) and typical usage of AkelPad.ScriptNoMutex()

Code: Select all

// === Set Coder Extension theme ===
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10672#p10672
// FeyFre (c) 2011-2014
//
//	v1.0.1 (2014.04.19) New Scripts plugin compatibility
//	Popups a dockbar which allows choose extension to activate for coder plugin.
//	Script should be positioned as a proof of concept for dockbar creation from scripts.
//	I have had no idea about existence of Highlighter.js when started to develop this script.
//	!!!Not tested on X64!!!
//
// Example:
//	Call("Scripts::Main", 1, "SetCoderExt.js")
//
//// REQUIRED: WIN32 Constant library at http://akelpad.sourceforge.net/forum/viewtopic.php?p=9420#p9420

//! Окно редактора
var g_hAkelPad = AkelPad.GetMainWnd();
//! Прокси системных вызовов
var oSys=AkelPad.SystemFunction();
//! Модуль плагина
var g_hModuleDll = AkelPad.GetInstanceDll();
//! Флаг завершения обработы скрипта
var QuitMutext = false;
//! Shell
var WshShell=new ActiveXObject("WScript.shell");
//! Константы используемые системными вызовами
AkelPad.Include("win32\\user32.js");

//! Панелька
var g_pDock = 0;
//! Окно панельки
var g_hDockWnd = 0;
//! Класс окна панельки
var DOCKCLASSNAME = "WNDCLS_"+WScript.ScriptBaseName;
//! Элементы управления на панельке
var combo_ext	= 0;
var btn_set		= 0;
var btn_exit	= 0;
//! Идентификаторы элементов управления на панельке
var IDC_EXT		= 1000;
var IDC_SET		= 1001;
var IDC_EXIT	= 1002;

//! Взято из AkelDLL.h
var DKS_LEFT	=1
var DKS_RIGHT	=2
var DKS_TOP		=3
var DKS_BOTTOM	=4

//Dock flags
var DKF_OWNTHREAD		=0x00000001
var DKF_FIXEDSIZE		=0x00000002
var DKF_DRAGDROP		=0x00000004
var DKF_HIDDEN			=0x00000008
var DKF_NODROPLEFT		=0x00000010
var DKF_NODROPRIGHT		=0x00000020
var DKF_NODROPTOP		=0x00000040
var DKF_NODROPBOTTOM	=0x00000080

//Dock action
var DK_ADD			=0x00000001
var DK_DELETE		=0x00000002
var DK_SUBCLASS		=0x00000004
var DK_UNSUBCLASS	=0x00000008
var DK_SETLEFT		=0x00000010
var DK_SETRIGHT		=0x00000020
var DK_SETTOP		=0x00000040
var DK_SETBOTTOM	=0x00000080
var DK_HIDE			=0x00000100
var DK_SHOW			=0x00000200
var DK_FINDDOCK		=0x00000400
var DK_FINDCHILD	=0x00000800

var BIF_BITMAP		=0x001; //Bitmap handle is used in BUTTONDRAW.hImage.
var BIF_ICON		=0x002; //Icon handle is used in BUTTONDRAW.hImage.
var BIF_CROSS		=0x004; //Draw small cross 8x7. BUTTONDRAW.hImage is ignored.
var BIF_DOWNARROW	=0x008; //Draw small down arrow 7x4. BUTTONDRAW.hImage is ignored.
var BIF_ETCHED		=0x100; //Draw edge around button.
var BIF_ENABLEFOCUS	=0x200; //Draw focus rectangle when button receive focus.

var AKD_RESIZE			= WM_USER + 253;
var AKD_DOCK			= WM_USER + 254;
var AKD_SETBUTTONDRAW	= WM_USER + 255;
var AKDN_MAIN_ONFINISH	= WM_USER + 6;

var WSC_MAINPROC		= 1;
var WSC_EDITPROC		= 2;
var WSC_FRAMEPROC		= 3;

var ControlH = 25;
var ComboW = 130;
//// РАБОЧИЕ ФУНКЦИИ
//! Создаёт панельку
function CreateDock()
{
	var pDock = AkelPad.MemAlloc(52/*sizeof(DOCK)*/);
	var dockside = DKS_BOTTOM;
	try
	{
		dockside = WshShell.RegRead("HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\SetCoderExt\\Side");
	}catch(e){}
	switch(dockside)
	{
		case DKS_BOTTOM:case DKS_TOP:break;
		default:dockside = DKS_BOTTOM;
	}
	AkelPad.MemCopy(pDock + 8, DKF_OWNTHREAD|DKF_NODROPLEFT|DKF_NODROPRIGHT|DKF_FIXEDSIZE|DKF_DRAGDROP, 3 /*DT_DWORD*/);
	AkelPad.MemCopy(pDock + 16, dockside, 3 /*DT_DWORD*/);
	g_pDock = AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_ADD, pDock);
	AkelPad.MemFree(pDock);
	if(g_pDock != 0)
	{
		
		g_hDockWnd = CreateWindowEx(0,DOCKCLASSNAME,DOCKCLASSNAME,WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,400,ControlH + 4,g_hAkelPad,0,DockWindowProc);
		if(g_hDockWnd!=0)
		{
			GetWindowRect(g_hDockWnd,g_pDock+20);
			var szL = AkelPad.MemRead(g_pDock+20, 3 /*DT_DWORD*/);
			var szT = AkelPad.MemRead(g_pDock+24, 3 /*DT_DWORD*/);
			var szR = AkelPad.MemRead(g_pDock+28, 3 /*DT_DWORD*/);
			var szB = AkelPad.MemRead(g_pDock+32, 3 /*DT_DWORD*/);
			/*rcSize={0,0,right-left,bottom-top}*/
			AkelPad.MemCopy(g_pDock+20, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+24, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+28, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+32, szB-szT, 3 /*DT_DWORD*/);
			/*rcDragDrop=rcSize*/
			AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+12, g_hDockWnd, 3 /*DT_DWORD*/);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SUBCLASS, g_pDock);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
			return 1;
		}
		else
		{
			AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
			g_pDock = 0;
			return 0;
		}
	}
	else return 0;
}
//! Хук главного окна.
function AkelPadCallBack(hwnd,umsg,wparam,lparam)
{
	//! Нотификция о закрытии редактора
	if(umsg == AKDN_MAIN_ONFINISH)
	{
		AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
		while(!QuitMutext)
		{
			oSys.Call("kernel32::SwitchToThread");
		}
	}
	return 0;
}
//! Хук окна редактирования. Для перехвата Enter и Esc
function ComboSubClass(hwnd,umsg,wparam,lparam)
{
	if(umsg == WM_KEYDOWN)
	{
		var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
		if(! mod)
		{
			if(wparam == VK_RETURN)
			{
				AkelPad.SendMessage(g_hDockWnd, WM_COMMAND, (BN_CLICKED <<16)+IDC_SET, 0);
			}
			else if(wparam == VK_ESCAPE)
			{
				AkelPad.SendMessage(g_hDockWnd, WM_COMMAND, (BN_CLICKED <<16)+IDC_EXIT, 0);
			}
		}
	}
	else if (umsg == WM_GETDLGCODE)
	{
		return DLGC_WANTALLKEYS;
	}
}
//! Заполнить список доступных расширений
function FillCombo(hwnd, curext)
{
	//! Extension supported by Coder collected here(ini-format file)
	var txtExt = AkelPad.ReadFile(AkelPad.GetAkelDir()+"\\AkelFiles\\Plugs\\Coder\\cache");
	var lines = txtExt.split("\r\n");
	var inSection = false, l = 0;
	var cat=[];
	if(lines.length==0) return;
	for(l = 1; l<lines.length;l++)
	{
		var line = lines[l];
		var parts=line.split('=');
		if(parts.length>=2)
		{
			var exts=parts[1].split(" ");
			var each = null
			for(each in exts)
			{
				exts[each] = exts[each].replace('"','').replace('"','');
			}
			cat[parts[0]] = exts;
		}
	}
	var catname = "";
	for(catname in cat)
	{
		var catlabel = '==' + catname.toUpperCase() + '==';
		var cats = cat[catname];
		var mem = AkelPad.MemAlloc((catlabel.length+1)*_TSIZE);
		AkelPad.MemCopy(mem, catlabel, _TSTR);
		var index = AkelPad.SendMessage(hwnd, CB_ADDSTRING, 0, mem);
		if(index != -1)
		{
			AkelPad.SendMessage(hwnd, CB_SETITEMDATA, index, 0);
		}
		AkelPad.MemFree(mem);
		var exti=0;
		for(exti in cats)
		{
			var ext = cats[exti];
			mem = AkelPad.MemAlloc((ext.length+1)*_TSIZE);
			AkelPad.MemCopy(mem, ext, _TSTR);
			index = AkelPad.SendMessage(hwnd, CB_ADDSTRING, 0, mem);
			if(index != -1)
			{
				AkelPad.SendMessage(hwnd, CB_SETITEMDATA, index, 1);
			}
			AkelPad.MemFree(mem);
			if(curext == ext)
			{
				AkelPad.SendMessage(hwnd, CB_SETCURSEL, index, 0);
			}
		}
	}
}
//! Оконная процедура панельки
function DockWindowProc(hwnd, umsg, wparam,lparam)
{
	if(umsg == WM_CREATE)
	{
		var fname = AkelPad.GetEditFile(0);
		if(fname != "")
		{
			fname = fname.split('\\');
			fname = fname[fname.length-1];
			fname = fname.split('.');
			fname = fname[fname.length-1];
		}
		//! Создаем элементы управления
		combo_ext = CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","",
							WS_CHILD|WS_VISIBLE|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|
							CBS_DROPDOWNLIST|CBS_AUTOHSCROLL,
							10,2,ComboW,ControlH,hwnd,IDC_EXT,0);
		FillCombo(combo_ext, fname);
		btn_set = CreateWindowEx(0,"BUTTON","SET",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,145,2,50,ControlH,hwnd,IDC_SET,0);
		btn_exit = CreateWindowEx(0,"BUTTON","EXIT",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|BS_OWNERDRAW,200,2,25,ControlH,hwnd,IDC_EXIT,0);
		//! Отображаем их
		ShowWindow(btn_set,SW_SHOW);UpdateWindow(btn_set);
		ShowWindow(btn_exit,SW_SHOW);UpdateWindow(btn_exit);
		ShowWindow(combo_ext,SW_SHOW);UpdateWindow(combo_ext);
		//! Рисовать кнопку закрытия
		var memBD = AkelPad.MemAlloc(16/*sizeof BUTTONDRAW*/);
		AkelPad.MemCopy(memBD+0, BIF_CROSS|BIF_ETCHED, 3 /*DT_DWORD*/);
		AkelPad.SendMessage(g_hAkelPad, AKD_SETBUTTONDRAW, btn_exit, memBD);
		AkelPad.MemFree(memBD);
		//! Фокус на строку ввода
		SetFocus(combo_ext);
		//! Сабкласим её, нужен перехват клавиш Escape и Enter
		AkelPad.WindowSubClass(combo_ext, ComboSubClass, WM_KEYDOWN, WM_GETDLGCODE);
		return 0;
	}
	else if(umsg == WM_KEYDOWN)
	{
		//! Перехват клавиш Escape и Enter на окне
		var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
		if(! mod)
		{
			if(wparam == VK_RETURN)
			{
				AkelPad.SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_SET,BN_CLICKED), 0);
			}
			else if(wparam == VK_ESCAPE)
			{
				AkelPad.SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_EXIT,BN_CLICKED), 0);
			}
		}
	}
	else if(umsg == WM_SETFOCUS)
	{
		//! Фокус на троку ввода
		SetFocus(combo_ext);
	}
	else if(umsg == WM_COMMAND)
	{
		var CODE = HIWORD(wparam);
		var IDC  = LOWORD(wparam);
		if(CODE == BN_CLICKED)
		{
			if(IDC == IDC_SET)
			{
				//! Нажата кнопка установить
				var ext = GetWindowText(combo_ext);
				if(	AkelPad.IsPluginRunning("Coder::CodeFold") ||
					AkelPad.IsPluginRunning("Coder::HighLight") ||
					AkelPad.IsPluginRunning("Coder::AutoComplete"))
				{
					AkelPad.Call("Coder::Settings",1,ext);
				}
				//AkelPad.SendMessage(hwnd,WM_CLOSE, 0, 0);
			}
			else if(IDC == IDC_EXIT)
			{
				//! Нажата кнопка выйти.
				AkelPad.SendMessage(hwnd,WM_CLOSE, 0, 0);
			}
		}
		return 0;
	}
	else if(umsg == WM_SIZE)
	{
		//! Меняем Drag&Drob область за размером панельки
		if(g_pDock)
		{
			GetWindowRect(g_hDockWnd,g_pDock+36);
			var szL = AkelPad.MemRead(g_pDock+36, 3 /*DT_DWORD*/);
			var szT = AkelPad.MemRead(g_pDock+40, 3 /*DT_DWORD*/);
			var szR = AkelPad.MemRead(g_pDock+44, 3 /*DT_DWORD*/);
			var szB = AkelPad.MemRead(g_pDock+48, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
		}
	}
	else if(umsg == WM_CLOSE)
	{
		//! Нас закрывают.
		DestroyWindow(hwnd);
		return 1;
	}
	else if(umsg == WM_DESTROY)
	{
		//! Закрыли нас. 
		try
		{
			WshShell.RegWrite("HKCU\\Software\\Akelsoft\\AkelPad\\Plugs\\Scripts\\SetCoderExt\\Side",
					AkelPad.MemRead(g_pDock+16, 3 /*DT_DWORD*/),"REG_DWORD");
		}catch(e){}
		AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_UNSUBCLASS,g_pDock);
		AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
		g_pDock = 0;
		AkelPad.SendMessage(g_hAkelPad, AKD_RESIZE, 0, 0);
		//! Убрать сабкласинг
		AkelPad.WindowUnsubClass(combo_ext);
		g_hDockWnd = 0;
		//! Выйти из цикла
		PostQuitMessage(0);
		return 0;
	}
	//return DefWindowProc(hwnd,umsg,wparam,lparam);
	return 0;
}
//! Проверка на однократный запуск скриптам
//! Используется вместе с AkelPad.ScriptNoMutex();
//! Типичное использование:
//! 1. При первом запуске скрипта, скрипт должен создать в системе объект с помощью которого можно
//!    будет с ним связаться, например окно(видимое или невидимое), объект синхронизации(событие),
//!    именованный канал, сокетом или прочее.
//! 2. Функция FirstInstance должна проверить наличие этого объекта(найти окно, открыть объект
//!    синхронизации, соединиться с каналом или сокетом).
//! 3. По желанию программиста(по заданию), функция может сразу попытаться прервать работу первого скрипта
//!    (как это сделано в этом примере)либо вернуть идентификатор объекта, через который будет осуществляться управление
//! 4. При отсутствии такого объекта(первый запуск), скрипт инициализируется, потом должен создать связной объект,
//!    и приготовившись взаимодействовать с ним, делает вызов AkelPad.ScriptNoMutex() которые и даст работать
//!    другим скриптам(в том числе второму экземпляру). После успешного вызова скрипт может делать свою фоновую
//!    задачу или просто ждать внешней команды.
//!
//!    В этом примере:
//!     1. Скрипт регистрирует оконный класс и создает окно(который и служит объектом взаимодействия)
//!     2. В случае успеха вызывается AkelPad.ScriptNoMutex(), иначе - завершение
//!     3. Пользователь взаимодействует с окном, и закрыв его завершает скрипт
//!     4. При повторном вызове, скрипт находит окно, и закрывает его(в следствии чего и завершается первый скрипт),
//!        после чего завершается сам.
//!
//! ВАЖНО: такой фоновый скрипт разрешает полное взаимодействие с окнами редактора, потому для корректной работы
//! скрипа должен уметь определять момент когда ему нужно завершится досрочно(например, при закрытии редактора,
//! при закрытии рабочего окна, при выключении зависимых плагинов)
function FirstInstance()
{
	var dock = FindWindowEx(g_hAkelPad,DOCKCLASSNAME);
	if(dock)
	{
		AkelPad.SendMessage(dock, WM_CLOSE, 0, 0);
		return false;
	}
	else
		return true;
}

if(FirstInstance())
{
	//! Регистрируем класс окна
	var res = AkelPad.WindowRegisterClass(DOCKCLASSNAME);
	
	//! Создаем панельку
	if(CreateDock())
	{
		//! Сабкласим главное окно
		if(AkelPad.WindowSubClass( WSC_MAINPROC, AkelPadCallBack,AKDN_MAIN_ONFINISH))
		{
			//! Мы инициализировались, можно дать работать другим скриптам
			AkelPad.ScriptNoMutex();
			//! Поток в цикл сообщений
			AkelPad.WindowGetMessage();
			//! Вышли(только по закрытии панельки)
			AkelPad.WindowUnsubClass( WSC_MAINPROC );
			//! Сняли хук
		}
		if(g_hDockWnd != 0)
		{
			//AkelPad.MessageBox(0, "Text", "Caption", 0 /*MB_OK*/);
			//! По идее сюда не попадем
			AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
			g_hDockWnd = 0;
		}
	}
	//! Класс долой
	AkelPad.WindowUnregisterClass(DOCKCLASSNAME);
	//! Вернуть фокус
	SetFocus(g_hAkelPad);
	//! Взводим флаг разрешения выхода из скрипта.
	QuitMutext = true;
}
///// UTILITY
///// HELPERS: функции для упрощения системных вызовов
//! Поиск окна в пределах рабочего стола по родителю и имени класса
function FindWindowEx(hwndParent,lpszClassName)
{
	var memclass =0;
	var t = "" + lpszClassName;
	memclass = AkelPad.MemAlloc((t.length+1)*_TSIZE);
	AkelPad.MemCopy(memclass, t, _TSTR);
	var hwnd = oSys.Call("user32::FindWindowEx"+_TCHAR, hwndParent,0,memclass,0);
	AkelPad.MemFree(memclass);
	return hwnd;
}
//! Создаёт окно
function CreateWindowEx(styleex,_class,title,style,x,y,cx,cy,parent,menu,lparam)
{
	//! Нативные строки
	var mem_class = AkelPad.MemAlloc((_class.length+1)*_TSIZE);
	AkelPad.MemCopy(mem_class, _class, _TSTR);
	var mem_title = AkelPad.MemAlloc((title.length+1)*_TSIZE);
	AkelPad.MemCopy(mem_title, title, _TSTR);
	var hwnd = oSys.Call("user32::CreateWindowEx" + _TCHAR,
							styleex,				//! Расширенный стиль
							mem_class,			//! Класс окна
							mem_title,			//! Заголовок окна
							style,				//! Стиль окна
							x,y,cx,cy,			//! Координаты и размер
							parent, menu,			//! Родитель и меню(идентификатор)
							g_hModuleDll,			//! принадлежность коду
							lparam);				//! Доп. параметр
	//! Освободить память
	AkelPad.MemFree(mem_class);
	AkelPad.MemFree(mem_title);
	return hwnd;
}
//! Показать окно, SW_* константы
function ShowWindow(hwnd,how)
{
	return oSys.Call("user32::ShowWindow",hwnd,how);
}
//! Обновить окно
function UpdateWindow(hwnd)
{
	return oSys.Call("user32::UpdateWindow",hwnd);
}
//! Выйти из оконного цикла
function PostQuitMessage(code)
{
	return oSys.Call("user32::PostQuitMessage",code);
}
//! Уничтожить окно
function DestroyWindow(hwnd)
{
	return oSys.Call("user32::DestroyWindow",hwnd);
}
//! Получить размер окна
function GetWindowRect(hwnd,rc)
{
	return oSys.Call("user32::GetWindowRect",hwnd,rc);
}
//! Дать фокус
function SetFocus(hwnd)
{
	return oSys.Call("user32::SetFocus",hwnd);
}
//! Получить текст окна
function GetWindowText(hwnd)
{
	//! Получить размер текста
	var res = AkelPad.SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
	//! Выделить память
	var mem = AkelPad.MemAlloc((res+2)*_TSIZE);
	//! Полчиуть текст
	AkelPad.SendMessage(hwnd, WM_GETTEXT,res+1, mem);
	var str = AkelPad.MemRead(mem, _TSTR);
	//! Освободить память
	AkelPad.MemFree(mem);
	return str;
}
//! Получить состояние кнопки
function GetKeyState(key)
{
	return oSys.Call("user32::GetKeyState",key);
}
//! LOWORD
function LOWORD(long)
{
	return long & 0x0FFFF;
}
//! HIWORD
function HIWORD(long)
{
	return (long >> 16) & 0x0FFFF;
}
//! MAKEWPARAM
function MAKEWPARAM(l, h)
{
	return MAKELONG(l, h);
}
//! MAKELONG
function MAKELONG(l, h)
{
	return (l & 0x0FFFF) + ((h & 0x0FFFF) << 16);
}
///// UNUSED HELPERS, STILL CAN BE USEFUL IN FUTURE
//! Системная оконная процедура 
////function DefWindowProc(hwnd,umsg,wparam,lparam)
////{
////	return oSys.Call("user32::DefWindowProc"+_TSTR,hwnd,umsg,wparam,lparam);
////}
//! Получить контекст рисования
////function BeginPaint(hwnd,ps)
////{
////	return oSys.Call("user32::BeginPaint",hwnd,ps);
////}
//! Закончить рисование
////function EndPaint(hwnd,ps)
////{
////	return oSys.Call("user32::EndPaint",hwnd,ps);
////}
//! Перерисовать область окна
////function InvalidateRect(hwnd,rect,erase)
////{
////	return oSys.Call("user32::InvalidateRect",hwnd,rect,erase);
////}
/*****************************************************
	Manuals
*****************************************************/
/***
	typedef struct _DOCK {
0	struct _DOCK *next;
4	struct _DOCK *prev;
8	DWORD dwFlags;			//Dock flags: see DKF_* defines.
12	HWND hWnd;			//Dock window handle.
16	int nSide;			//Dock side: DKS_LEFT, DKS_TOP, DKS_RIGHT or DKS_BOTTOM.
20	RECT rcSize;			//Dock window client RECT.
20	.left
24	.top
28	.right
32	.bottom
36	RECT rcDragDrop;		//Drag-and-drop client RECT.
36	.left
40	.top
44	.right
48	.bottom
	} DOCK;
***/
Last edited by FeyFre on Sat Apr 19, 2014 6:03 pm, edited 2 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10791#p10791
// http://infocatcher.ucoz.net/js/akelpad_scripts/backupVersion.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/backupVersion.js

// (c) Infocatcher 2011-2012, 2014-2015
// Version: 0.1.5 - 2015-01-12
// Author: Infocatcher

//===================
//// Tries find file version and copy current file to the same directory
//   file.js      -> file-%version%.js
//   file.user.js -> file-%version%.user.js

// Arguments:
//   -forceDate=true  - force use last modification date
//   -dateType=1      - see dateToString() in settings section
//   -openBackup=true - open created backup file
//   -warnings=false  - skip "Can't detect file version!" warning, just ask for file name

// Usage:
//   Call("Scripts::Main", 1, "backupVersion.js")
//   Call("Scripts::Main", 1, "backupVersion.js", "-forceDate=true -dateType=1")
//===================

//== Settings begin
var getVersionPattern  = /(^|[^a-z])(version|ver\.?|v\.?)[ \t]*[-:=]?[ \t]*(\S+)/i;
var versionBracketsNumber = 3; // We don't use (?:something) for backward compatibility with old JScript
var testVersionPattern = /\d/; // Version string must contain number
var linesLimit = 20; // Check only first 20 lines of file
var addVersionPattern = /(\.user)?\.[^.\s_-]+$/; // {fileName}{versionSeparator}{version}{addVersionPattern}
function getVersionSeparator(version) {
	return /-/.test(version) ? "_" : "-";
}
var dateTypesCount = 3;
function dateToString(date, type) {
	function pad(n) {
		return n < 10 ? "0" + n : n;
	}
	var ret = date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate());
	if(type == 0)
		return ret;
	ret += "_" + pad(date.getHours()) + "-" + pad(date.getMinutes());
	if(type == 1)
		return ret;
	ret += "-" + pad(date.getSeconds());
	return ret;
}
function trimVersion(version) {
	return version
		.replace(/^v\.?\s*/i, "")
		.replace(/[.,]+$/, "");
}
//== Settings end

function _localize(s) {
	var strings = {
		"Save file first!": {
			ru: "Сначала сохраните файл!"
		},
		"Can't detect file version!": {
			ru: "Не удалось определить версию файла!"
		},
		"Can't use original file name!": {
			ru: "Нельзя использовать имя исходного файла!"
		},
		"File “%S” already exists!\nOverwrite?": {
			ru: "Файл «%S» уже существует!\nПерезаписать?"
		},
		"Can't copy current file to “%F”\nError:\n%E": {
			ru: "Не удалось копировать текущий файл в «%F»\nОшибка:\n%E"
		},
		"Backup file was succefully created:\n%S": {
			ru: "Файл резервной копии успешно создан:\n%S"
		},
		"Name of backup file:": {
			ru: "Имя файла резервной копии:"
		}
	};
	var lng = "en";
	switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
		case 0x19: lng = "ru";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

var hMainWnd = AkelPad.GetMainWnd();
if(!hMainWnd)
	WScript.Quit();

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var fso = new ActiveXObject("Scripting.FileSystemObject");
var curPath = AkelPad.GetEditFile(0);
var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);

if(!curPath) {
	AkelPad.MessageBox(hMainWnd, _localize("Save file first!"), dialogTitle, 48 /*MB_ICONEXCLAMATION*/);
	WScript.Quit();
}

copyFile();

function copyFile() {
	var forceDate = AkelPad.GetArgValue("forceDate", false);

	var curName = fso.GetFileName(curPath);
	var curDir  = fso.GetParentFolderName(curPath);
	var newName;
	var overwrite = false;
	var exists = function(name) {
		var path = curDir + "\\" + name;
		//return fso.FileExists(path) || fso.FolderExists(path);
		return oSys.Call("kernel32::GetFileAttributes" + _TCHAR, path) != -1;
	};
	if(!forceDate)
		var version = getVersion();
	if(version)
		newName = addVersion(curName, version);
	else {
		var dateType = AkelPad.GetArgValue("dateType", 0);

		var askName = curName;
		var lastMod = new Date(fso.GetFile(curPath).DateLastModified);
		for(var i = dateType; i < dateTypesCount; ++i) {
			var lastModStr = dateToString(lastMod, i);
			var testName = addVersion(curName, lastModStr);
			if(!exists(testName)) {
				askName = testName;
				break;
			}
		}
		var forceAsk = i > dateType;
		if(!forceDate && AkelPad.GetArgValue("warnings", true))
			AkelPad.MessageBox(hMainWnd, _localize("Can't detect file version!"), dialogTitle, 48 /*MB_ICONEXCLAMATION*/);
		newName = !forceDate || forceAsk
			? askFileName(testName || askName)
			: askName;
		if(!newName)
			return;
	}
	for(;;) {
		if(newName == curName) {
			AkelPad.MessageBox(
				hMainWnd,
				_localize("Can't use original file name!"),
				dialogTitle,
				48 /*MB_ICONEXCLAMATION*/
			);
		}
		else {
			if(!exists(newName) && _copy(curPath, curDir, newName, overwrite))
				break;

			var btn = AkelPad.MessageBox(
				hMainWnd,
				_localize("File “%S” already exists!\nOverwrite?").replace("%S", newName),
				dialogTitle,
				35 /*MB_YESNOCANCEL|MB_ICONQUESTION*/
			);
			if(btn == 2 /*IDCANCEL*/)
				return;
			overwrite = btn == 6 /*IDYES*/;
			if(overwrite && _copy(curPath, curDir, newName, overwrite))
				break;
		}
		newName = askFileName(newName);
		if(!newName)
			return;
	}
}
function askFileName(fileName) {
	return AkelPad.InputBox(hMainWnd, dialogTitle, _localize("Name of backup file:"), fileName);
}
function _copy(curPath, curDir, newName, overwrite) {
	try {
		fso.CopyFile(curPath, curDir + "\\" + newName, overwrite);
		if(AkelPad.GetArgValue("openBackup", false)) {
			var lpFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
			AkelPad.OpenFile(curDir + "\\" + newName, 0, AkelPad.GetEditCodePage(hWndEdit), AkelPad.GetEditBOM(hWndEdit));
			lpFrame && AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, lpFrame);
		}
	}
	catch(e) {
		AkelPad.MessageBox(
			hMainWnd,
			_localize("Can't copy current file to “%F”\nError:\n%E")
				.replace("%F", newName)
				.replace("%E", e.message || e),
			dialogTitle,
			16 /*MB_ICONQUESTION*/
		);
		return false;
	}
	//if(overwrite)
	//	return true;
	new ActiveXObject("WScript.Shell").Popup(
		_localize("Backup file was succefully created:\n%S").replace("%S", newName),
		2, // Autoclose after 2 seconds
		dialogTitle,
		64 /*MB_ICONINFORMATION*/
	);
	return true;
}
function getVersion() {
	var version = "";

	var ww = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
	if(ww) {
		setRedraw(hWndEdit, false);
		AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
	}

	var lineStart = 0;
	var line = 0;
	var linesCount = AkelPad.SendMessage(hWndEdit, 3129 /*AEM_GETLINENUMBER*/, 0 /*AEGL_LINECOUNT*/, 0);
	var maxLine = Math.min(linesLimit, linesCount) - 1;
	for(;;) {
		var lineLength = AkelPad.SendMessage(hWndEdit, 193 /*EM_LINELENGTH*/, lineStart, 0);
		var lineEnd    = lineStart + lineLength;
		var lineText   = AkelPad.GetTextRange(lineStart, lineEnd);

		lineText = lineText.replace(/(http|ftp)s?:\/\S+/, "");
		if(getVersionPattern.test(lineText)) {
			var tmp = RegExp["$" + versionBracketsNumber];
			if(testVersionPattern.test(tmp)) {
				version = trimVersion(tmp);
				break;
			}
		}

		lineStart = lineEnd + 1;
		if(++line > maxLine)
			break;
	}

	if(ww) {
		AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
		setRedraw(hWndEdit, true);
	}

	return version;
}
function addVersion(name, version) {
	return name.replace(addVersionPattern, getVersionSeparator(version) + version + "$&");
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download | mirror | development version>
Tries find file version and copy current file to the same directory:
file.js -> file-%version%.js
file.user.js -> file-%version%.user.js
Last edited by Infocatcher on Mon Jan 12, 2015 12:16 pm, edited 5 times in total.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Delete record from recent files.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#p10810
// Version: 1.1
// Author: Shengalts Aleksander aka Instructor
//
//
// Description(1033): Delete record from recent files.
// Description(1049): Удалить запись из последних файлов.
//
// Usage (via ContextMenu plugin):
// Call("Scripts::Main", 1, "DeleteRecentFile.js", `'%f'`)

var hMainWnd=AkelPad.GetMainWnd();

if (WScript.Arguments.length)
  DeleteRecentFile(WScript.Arguments(0));

function DeleteRecentFile(pFileToDelete)
{
  var nIndex;

  if ((nIndex=AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 7 /*RF_FINDINDEX*/, AkelPad.MemStrPtr(pFileToDelete))) >= 0)
  {
    if (AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 8 /*RF_DELETEINDEX*/, nIndex))
      AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 4 /*RF_SAVE*/, 0);
  }
}


Clear recent files list.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#p10810
// Version: 1.0
// Author: Shengalts Aleksander aka Instructor
//
//
// Description(1033): Clear recent files list.
// Description(1049): Очистить список последних файлов.
//
// Arguments:
// -Msg=false  -Clear recent files list without prompt (default is true).
//
// Usage:
// Call("Scripts::Main", 1, "ClearRecentFiles.js", `-Msg=false`)

//Arguments
var bMsg=AkelPad.GetArgValue("Msg", true);

//Variables
var hWndMain=AkelPad.GetMainWnd();

if (bMsg)
{
  if (AkelPad.MessageBox(hWndMain, GetLangString(0), WScript.ScriptName, 0x24 /*MB_ICONQUESTION|MB_YESNO*/) == 7 /*IDNO*/)
    WScript.Quit();
}
AkelPad.SendMessage(hWndMain, 1238 /*AKD_RECENTFILES*/, 5 /*RF_CLEAR*/, 0);
AkelPad.SendMessage(hWndMain, 1238 /*AKD_RECENTFILES*/, 4 /*RF_SAVE*/, 0);

function GetLangString(nStringID)
{
  var nLangID=AkelPad.GetLangId(1 /*LANGID_PRIMARY*/);

  if (nLangID == 0x19) //LANG_RUSSIAN
  {
    if (nStringID == 0)
      return "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u0020\u0441\u043F\u0438\u0441\u043E\u043A\u0020\u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445\u0020\u0444\u0430\u0439\u043B\u043E\u0432\u003F";
  }
  else
  {
    if (nStringID == 0)
      return "Clear recent files list?";
  }
  return "";
}


Open closed file.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=10810#p10810
// Version: 1.1
// Author: Shengalts Aleksander aka Instructor
//
//
// Description(1033): Open closed file.
// Description(1049): Открыть закрытый файл.

var hMainWnd=AkelPad.GetMainWnd();
var nMaxRecentFiles;
var lppStack;
var lpStack;
var lpRecentFile;
var pFile;

if (lppStack=AkelPad.MemAlloc(_X64?8:4 /*sizeof(STACKRECENTFILE **)*/))
{
  if (nMaxRecentFiles=AkelPad.SendMessage(hMainWnd, 1238 /*AKD_RECENTFILES*/, 1 /*RF_GET*/, lppStack))
  {
    lpStack=AkelPad.MemRead(lppStack, 2 /*DT_QWORD*/);
    lpRecentFile=AkelPad.MemRead(_PtrAdd(lpStack, 0) /*offsetof(STACKRECENTFILE, first)*/, 2 /*DT_QWORD*/)

    while (lpRecentFile)
    {
      pFile=AkelPad.MemRead(_PtrAdd(lpRecentFile, _X64?16:8) /*offsetof(RECENTFILE, wszFile)*/, 1 /*DT_UNICODE*/);
      if (!AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 5 /*FWF_BYFILENAME*/, pFile))
      {
        AkelPad.OpenFile(pFile);
        break;
      }
      lpRecentFile=AkelPad.MemRead(_PtrAdd(lpRecentFile, 0) /*offsetof(RECENTFILE, next)*/, 2 /*DT_QWORD*/)
    }
  }
  AkelPad.MemFree(lppStack);
}
Last edited by Instructor on Sat Apr 18, 2015 4:19 am, edited 9 times in total.

Offline
Posts: 19
Joined: Fri Jan 14, 2011 3:29 am

Post by lexa »

1. "Кавычкер"

Меняет кавычки на "елочки", а вложенные кавычки на другие кавычки "лапки":
Вася сказал: "Я живу в отеле "Калифорния""
Вася сказал: «Я живу в отеле „Калифорния“».
Подробнее на http://spectator.ru/technology/php/quot ... stike_back.

Автор Дима Смирнов.

Изначальный вариант предполагает замену на HTML-значения (вроде &#151 для тире). Вариант ниже для чистого текста поэтому неразрывные пробелы и <nobr /> не вошли в скрипт, а специальные символы преобрели первозданный вариант. Работает с cp1251.

Code: Select all

// Apply russian basic typography rules.
//
// Version: 1.0 (2011/01/14)
// Author: Dmitry Smirnov <http://spectator.ru>

var s = AkelPad.GetSelText();

if (!s){
    s = AkelPad.GetTextRange(0, -1);
    AkelPad.SetSel(0, -1);
}

s = ' ' + s;

// кавычки

// put in array
var a = s.match(/<([^>]*)>/g);

var i = 0;
var r = /<([^>]*)>/;

while (r.test(s))
    s = s.replace(r, '\x01' + ++i + '\x02');

// wordfix
s = s.replace(/«/g, '"');
s = s.replace(/»/g, '"');
s = s.replace(/“/g, '"');
s = s.replace(/”/g, '"');
s = s.replace(/…/g, '...');
s = s.replace(/–/g, '-');
s = s.replace(/—/g, '-');

// kavychking
s = s.replace(/([\x01-(\s\"])(\")([^\"]{1,})([^\s\"(])(\")/g, '$1«$3$4»');

// kavychking in kavychking
if (/"/.test(s)){
    s = s.replace(/([\x01(\s\"])(\")([^\"]{1,})([^\s\"(])(\")/g, '$1«$3$4»');
    
    while (/(«)([^»]*)(«)/.test(s))
        s = s.replace(/(«)([^»]*)(«)([^»]*)(»)/g, '$1$2„$4“');
}

s = s.replace(/  +/g, ' '); 

s = s.replace(/ -{1,2} /g, ' — '); 
s = s.replace(/\.{3}/g, '…'); 
s = s.replace(/([>|\s])- /g, '$1— '); 
s = s.replace(/^- /g, '— '); 

s = s.replace(/(\d)-(\d)/g, '$1–$2');

// инициалы 

// A.C. Пушкин
s = s.replace(/([А-ЯA-Z])([\. ]{1})[ ]{0,1}([А-ЯA-Z])([\. ]{1})[ ]{0,1}([А-ЯA-Z][А-Яа-яA-Za-z]*)/g, '$1. $3. $5');

// Пушкин А. С.
s = s.replace(/([А-ЯA-Z][А-Яа-яA-Za-z]*) ([А-ЯA-Z])[\. ]{1}[ ]{0,1}([А-ЯA-Z])\.([,\ )]{1})/g, '$1 $2. $3.$4');

// (А.С.Пушкин)  
 // (Пушкин А.С) 
 // (Пушкин А. С) 

s = s.replace(/'/g, '’');
s = s.replace(/\(c\)/gi, '©');
s = s.replace(/\(r\)/gi, '®');
s = s.replace(/\(tm\)/gi, '™');
s = s.replace(/№ /gi, '№');

// out array
i = 0;
r = /\x01([0-9]*)\x02/;

while (r.test(s))
    s = s.replace(r, a[++i - 1]);

AkelPad.ReplaceSel(s.substr(1));



2. SmartBackspace

Такое уже есть в пожеланиях, но пока нет официальной реализации внутри редактора, есть криворукий вариант через скрипты. :)

Что делает: удаляет пробелы и табы по несколько штук за раз, а не по одному пробелу. Умеет упираться в начало блока текста предыдущей строки:

Code: Select all

if (i){
        var j; // Начало блока
        |<--------отсюда туда
|<----потом сюда
}
[выпилил]

upd добавил шапку-комментарий, как советовали, но моя английский говорить плохо. Поэтому... да. :)
Last edited by lexa on Sun Jan 23, 2011 8:37 am, edited 2 times in total.
Post Reply