mirror of https://gitlab.com/basile.b/dexed.git
drw2
This commit is contained in:
parent
cac091a4d6
commit
0c6454ca05
|
@ -18,6 +18,9 @@ object CurrentProject: TCEProject
|
||||||
Sources.Strings = (
|
Sources.Strings = (
|
||||||
'..\tool\resman.d'
|
'..\tool\resman.d'
|
||||||
'..\tool\utils.d'
|
'..\tool\utils.d'
|
||||||
|
'..\tool\e7F.d'
|
||||||
|
'..\tool\z85.d'
|
||||||
|
'..\tool\item.d'
|
||||||
)
|
)
|
||||||
ConfigurationIndex = 0
|
ConfigurationIndex = 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
*/
|
*/
|
||||||
module resman;
|
module resman;
|
||||||
|
|
||||||
|
import std.path, std.conv, std.base64, std.digest.crc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activate the resman mechanism. If the resources related to a
|
* Activate the resman mechanism. If the resources related to a
|
||||||
* module have been generated using the Coedit *Resman* widget
|
* module have been generated using the Coedit *Resman* widget
|
||||||
|
@ -17,7 +19,7 @@ module resman;
|
||||||
mixin template activateResman()
|
mixin template activateResman()
|
||||||
{
|
{
|
||||||
mixin("private import resman;");
|
mixin("private import resman;");
|
||||||
enum f = (__FILE__.stripExtension.stripPath) ~ ".res";
|
enum f = (__FILE__.stripExtension.baseName) ~ ".res";
|
||||||
mixin(import(f));
|
mixin(import(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +34,7 @@ public enum ResFormat {
|
||||||
*
|
*
|
||||||
* Params:
|
* Params:
|
||||||
* identifiers = the array which holds the resource identifiers,
|
* identifiers = the array which holds the resource identifiers,
|
||||||
* always named *residententifiers*.
|
* always named *TBA*.
|
||||||
* identifier = the identifier to find.
|
* identifier = the identifier to find.
|
||||||
*
|
*
|
||||||
* Return:
|
* Return:
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
module e7F;
|
||||||
|
|
||||||
|
private const t = true;
|
||||||
|
private const f = false;
|
||||||
|
|
||||||
|
/// Returns true if a white has to be encoded.
|
||||||
|
private bool[14] isWhite7F = [
|
||||||
|
t, t, t, f, f, f, t, f, f, t, t, f, f, t
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "7F" binary-to-text encoder.
|
||||||
|
* Kind of "percent encoding" except that the prefix is the character 0x7F.
|
||||||
|
* non-ASCII chars and "whites" are prefixed and represented in base 16.
|
||||||
|
*/
|
||||||
|
char[] encode_7F(ubyte[] input)
|
||||||
|
{
|
||||||
|
import utils : ubyte2Hex;
|
||||||
|
char[] result;
|
||||||
|
foreach(b; input){
|
||||||
|
//if ((b < 14 && isWhite7F[b]) || b > 0x7E)
|
||||||
|
if (b < 32 || b > 0x7E || b == '"' || b == '\\')
|
||||||
|
result ~= (cast(char) 0x7F) ~ ubyte2Hex(b);
|
||||||
|
else
|
||||||
|
result ~= cast(char)b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "7F" text-to-binary decoder.
|
||||||
|
*/
|
||||||
|
ubyte[] decode_7F(in char[] input)
|
||||||
|
{
|
||||||
|
ubyte[] result;
|
||||||
|
size_t i;
|
||||||
|
while(i < input.length)
|
||||||
|
{
|
||||||
|
char c = input[i];
|
||||||
|
assert(c <= 0x7F);
|
||||||
|
if (c == 0x7F)
|
||||||
|
{
|
||||||
|
assert(i+2 < input.length);
|
||||||
|
char[2] digits = input[i+1 .. i+3];
|
||||||
|
import std.conv : to;
|
||||||
|
result ~= to!ubyte(digits[], 16);
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else result ~= c;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
module item;
|
||||||
|
|
||||||
|
import core.exception;
|
||||||
|
|
||||||
|
import std.file, std.path;
|
||||||
|
import std.string: format;
|
||||||
|
|
||||||
|
import utils;
|
||||||
|
|
||||||
|
enum ResFormat {bytes, utf8, base16, base64, z85, e7F}
|
||||||
|
|
||||||
|
alias ResourceItems = ResourceItem * [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource item.
|
||||||
|
* The resource properties and the encoded form are generated in the constructor.
|
||||||
|
*/
|
||||||
|
struct ResourceItem{
|
||||||
|
private:
|
||||||
|
static const resFileMsg = "resource file '%s' ";
|
||||||
|
ResFormat _resFormat;
|
||||||
|
string _resIdentifier;
|
||||||
|
string _resMetaData;
|
||||||
|
char[] _resTxtData;
|
||||||
|
ubyte[] _resRawData;
|
||||||
|
uint _initialSum;
|
||||||
|
uint _encodedSum;
|
||||||
|
|
||||||
|
bool encodeDispatcher(){
|
||||||
|
final switch(this._resFormat){
|
||||||
|
case ResFormat.bytes:
|
||||||
|
return encodeUtf8(); // should add to a ubyte[][] import(filename)
|
||||||
|
case ResFormat.utf8:
|
||||||
|
return encodeUtf8();
|
||||||
|
case ResFormat.base16:
|
||||||
|
return encodeb16();
|
||||||
|
case ResFormat.base64:
|
||||||
|
return encodeb64();
|
||||||
|
case ResFormat.z85:
|
||||||
|
return encodez85();
|
||||||
|
case ResFormat.e7F:
|
||||||
|
return encodee7F();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// encodes _resRawData to an UTF8 string
|
||||||
|
bool encodeUtf8(){
|
||||||
|
scope(failure) return false;
|
||||||
|
_resTxtData = (cast(char[])_resRawData).dup;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// encodes _resRawData to a hex string
|
||||||
|
bool encodeb16(){
|
||||||
|
scope(failure) return false;
|
||||||
|
foreach(b; _resRawData)
|
||||||
|
this._resTxtData ~= ubyte2Hex(b);
|
||||||
|
assert(_resTxtData.length == _resRawData.length * 2,
|
||||||
|
"b16 representation length mismatches");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// encodes _resRawData to a base64 string
|
||||||
|
bool encodeb64(){
|
||||||
|
import std.base64: Base64;
|
||||||
|
scope(failure) return false;
|
||||||
|
_resTxtData = Base64.encode(_resRawData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// encodes _resRawData to a Z85 string
|
||||||
|
bool encodez85(){
|
||||||
|
import z85: Z85_encode;
|
||||||
|
scope(failure) return false;
|
||||||
|
_resTxtData = Z85_encode(_resRawData);
|
||||||
|
assert(_resTxtData.length == _resRawData.length * 5 / 4,
|
||||||
|
"z85 representation length mismatches");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// encodes _resRawData to an e7F string
|
||||||
|
bool encodee7F()
|
||||||
|
{
|
||||||
|
import e7F: encode_7F;
|
||||||
|
scope(failure) return false;
|
||||||
|
_resTxtData = encode_7F(_resRawData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and encodes a new resource item.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
*
|
||||||
|
* resFile = the file whose content is to encode.
|
||||||
|
* resEnc = the encoding format.
|
||||||
|
* resIdent = optional string used as identifier. When not set, the filename is used.
|
||||||
|
* resMeta = optional string used as metadata.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* --------
|
||||||
|
* auto item = new Item("\folder\strings_en.txt", ResEncoding.e7F, "string_english");
|
||||||
|
* auto item = new Item("\folder\strings_fr.txt", ResEncoding.e7F, "string_frecnh");
|
||||||
|
* --------
|
||||||
|
*/
|
||||||
|
this(string resFile, ResFormat resFormat, string resIdent = "", string resMeta = "")
|
||||||
|
{
|
||||||
|
this._resFormat = resFormat;
|
||||||
|
|
||||||
|
// load the raw content
|
||||||
|
if (!resFile.exists)
|
||||||
|
throw new Exception(format(resFileMsg ~ "does not exist", resFile));
|
||||||
|
else
|
||||||
|
_resRawData = cast(ubyte[])std.file.read(resFile);
|
||||||
|
if (!_resRawData.length)
|
||||||
|
throw new Exception(format(resFileMsg ~ "is empty", resFile));
|
||||||
|
|
||||||
|
import std.digest.crc: CRC32;
|
||||||
|
CRC32 ihash;
|
||||||
|
ihash.put(_resRawData);
|
||||||
|
_initialSum = crc322uint(ihash.finish);
|
||||||
|
|
||||||
|
// sets the resource identifier to the res filename if param is empty
|
||||||
|
this._resIdentifier = resIdent;
|
||||||
|
if (this._resIdentifier == "")
|
||||||
|
this._resIdentifier = resFile.baseName.stripExtension;
|
||||||
|
|
||||||
|
this._resMetaData = resMeta;
|
||||||
|
|
||||||
|
if (!encodeDispatcher)
|
||||||
|
throw new Exception(format(resFileMsg ~ "encoding failed", resFile));
|
||||||
|
this._resRawData.length = 0;
|
||||||
|
CRC32 ehash;
|
||||||
|
ehash.put(cast(ubyte[])_resTxtData);
|
||||||
|
_encodedSum = crc322uint(ehash.finish);
|
||||||
|
|
||||||
|
writeMessage(true, format("encoded resource file '%s'", resFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns the resource encoded as a string.
|
||||||
|
char[] resText(){return _resTxtData;}
|
||||||
|
|
||||||
|
/// returns the resource identifier.
|
||||||
|
string resIdentifier(){return _resIdentifier;}
|
||||||
|
|
||||||
|
/// returns the resource metadata.
|
||||||
|
string resMetaData(){return _resMetaData;}
|
||||||
|
|
||||||
|
/// returns the resource encoding kind.
|
||||||
|
ResFormat resFormat(){return _resFormat;}
|
||||||
|
|
||||||
|
/// returns the signature of the original data.
|
||||||
|
uint initialSum(){return _initialSum;}
|
||||||
|
|
||||||
|
/// returns the signature of the encoded data.
|
||||||
|
uint encodedSum(){return _encodedSum;}
|
||||||
|
}
|
|
@ -1,14 +1,20 @@
|
||||||
module resman;
|
module resman;
|
||||||
|
|
||||||
import std.stdio, std.getopt, std.path;
|
import std.stdio, std.getopt, std.path;
|
||||||
import std.json, std.file, std.conv;
|
import std.json, std.file, std.conv, std.string;
|
||||||
|
|
||||||
|
import utils, item;
|
||||||
|
|
||||||
enum ResType {aFile, aFolder}
|
enum ResType {aFile, aFolder}
|
||||||
enum ResFormat {bytes, utf8, base16, base64}
|
|
||||||
|
|
||||||
struct ResourceItem{}
|
|
||||||
alias ResourceItems = ResourceItem * [];
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resman main procedure.
|
||||||
|
* Params:
|
||||||
|
* args = the options and a list of file.
|
||||||
|
* - -v or --verbose: detailed messages for each operation.
|
||||||
|
* - -b or --basepath: a path used to solve relative resource filenames.
|
||||||
|
* - -files: a list of files produced by the Resman widget.
|
||||||
|
*/
|
||||||
void main(string[] args)
|
void main(string[] args)
|
||||||
{
|
{
|
||||||
string[] files;
|
string[] files;
|
||||||
|
@ -29,24 +35,57 @@ void main(string[] args)
|
||||||
json2Items(f, items);
|
json2Items(f, items);
|
||||||
Items2Module(f, items);
|
Items2Module(f, items);
|
||||||
}
|
}
|
||||||
readln;
|
//readln;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string fmt_json_err = "invalid JSON format: %s, in file '%s'";
|
||||||
|
static string fmt_file_skp = "invalid JSON file: %s, '%s' is skipped";
|
||||||
|
static string fmt_item_skp = "invalid JSON item: %s, '%s' is skipped";
|
||||||
|
static string fmt_item_rep = "invalid JSON value: %s, has been set to '%s'";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms the items contained in the JSON file fname to an array of
|
||||||
|
* ResourceItem.
|
||||||
|
* Params:
|
||||||
|
* fname = a valid filename.
|
||||||
|
* items = container for the ResourceItem found in the file.
|
||||||
|
*/
|
||||||
void json2Items(string fname, out ResourceItems items)
|
void json2Items(string fname, out ResourceItems items)
|
||||||
{
|
{
|
||||||
if (!fname.exists) return; // + verbose, msg
|
if (!fname.exists) {
|
||||||
|
writeMessage(true, format(fmt_file_skp, "it does not exists", fname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size = cast(size_t) getSize(fname);
|
size_t size = cast(size_t) getSize(fname);
|
||||||
if (size == 0) return; // + verbose, msg
|
if (size == 0) {
|
||||||
|
writeMessage(true, format(fmt_file_skp, "empty file", fname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto json_string = cast(string) std.file.read(fname, size);
|
auto json_string = cast(string) std.file.read(fname, size);
|
||||||
JSONValue root = parseJSON(json_string);
|
JSONValue root = parseJSON(json_string);
|
||||||
if (root.type != JSON_TYPE.OBJECT) return; // invalid format
|
if (root.type != JSON_TYPE.OBJECT) {
|
||||||
JSONValue * itms = ("items" in root.object);
|
writeMessage(true, format(fmt_json_err, "first value must be of type OBJECT", fname));
|
||||||
if (itms == null) return; // invalid format
|
return;
|
||||||
if (itms.type != JSON_TYPE.ARRAY) return; // invalid format
|
}
|
||||||
foreach(itm; itms.array)
|
|
||||||
|
JSONValue * itms = ("resources" in root.object);
|
||||||
|
if (itms == null) {
|
||||||
|
writeMessage(true, format(fmt_json_err, "the member 'resources' is missing", fname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (itms.type != JSON_TYPE.ARRAY) {
|
||||||
|
writeMessage(true, format(fmt_json_err, "'resources' must be of type ARRAY", fname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(itm; itms.array)
|
||||||
{
|
{
|
||||||
if (itm.type != JSON_TYPE.OBJECT) continue; // invalid format
|
if (itm.type != JSON_TYPE.OBJECT) {
|
||||||
|
writeMessage(true, format(fmt_item_skp, "an item must be of type OBJECT", itm.toString));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
JSONValue * itm_tpe = ("resourceType" in itm.object);
|
JSONValue * itm_tpe = ("resourceType" in itm.object);
|
||||||
JSONValue * itm_nme = ("name" in itm.object);
|
JSONValue * itm_nme = ("name" in itm.object);
|
||||||
|
@ -54,89 +93,131 @@ void json2Items(string fname, out ResourceItems items)
|
||||||
JSONValue * itm_fmt = ("format" in itm.object);
|
JSONValue * itm_fmt = ("format" in itm.object);
|
||||||
JSONValue * itm_mdt = ("metadata" in itm.object);
|
JSONValue * itm_mdt = ("metadata" in itm.object);
|
||||||
|
|
||||||
if (itm_tpe == null) continue; // invalid format
|
if (itm_tpe == null || itm_nme == null || itm_idt == null ||
|
||||||
if (itm_nme == null) continue; // invalid format
|
itm_fmt == null || itm_mdt == null)
|
||||||
if (itm_idt == null) continue; // invalid format
|
{
|
||||||
if (itm_fmt == null) continue; // invalid format
|
writeMessage(true, format(fmt_item_skp, "an item must contain all the properties",
|
||||||
if (itm_mdt == null) continue; // invalid format
|
itm.toString));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (itm_tpe.type != JSON_TYPE.STRING) continue; // invalid format
|
if (itm_tpe.type != JSON_TYPE.STRING || itm_nme.type != JSON_TYPE.STRING ||
|
||||||
if (itm_nme.type != JSON_TYPE.STRING) continue; // invalid format
|
itm_idt.type != JSON_TYPE.STRING || itm_fmt.type != JSON_TYPE.STRING ||
|
||||||
if (itm_idt.type != JSON_TYPE.STRING) continue; // invalid format
|
itm_mdt.type != JSON_TYPE.STRING)
|
||||||
if (itm_fmt.type != JSON_TYPE.STRING) continue; // invalid format
|
{
|
||||||
if (itm_mdt.type != JSON_TYPE.STRING) continue; // invalid format
|
writeMessage(true, format(fmt_item_skp, "an item value must be of type STRING",
|
||||||
|
itm.toString));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
string[] nme_vs;
|
string[] nme_vs;
|
||||||
string nme_v = itm_nme.str;
|
string nme_v = itm_nme.str;
|
||||||
string idt_v = itm_idt.str;
|
string idt_v = itm_idt.str;
|
||||||
string mdt_v = itm_mdt.str;
|
string mdt_v = itm_mdt.str;
|
||||||
ResType tpe_v = to!ResType(itm_tpe.str);
|
ResType tpe_v;
|
||||||
ResFormat fmt_v = to!ResFormat(itm_fmt.str);
|
ResFormat fmt_v;
|
||||||
|
|
||||||
if (!nme_v.exists) continue; // path or filename must exists
|
if (!nme_v.exists) {
|
||||||
|
writeMessage(true, format(fmt_item_skp, "the item filename or path is invalid", nme_v));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try tpe_v = to!ResType(itm_tpe.str);
|
||||||
|
catch (Exception e) {
|
||||||
|
if (isDir(nme_v)) tpe_v = ResType.aFolder;
|
||||||
|
else tpe_v = ResType.aFile;
|
||||||
|
writeMessage(true, format(fmt_item_rep, "resourceType", to!string(tpe_v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try fmt_v = to!ResFormat(itm_fmt.str);
|
||||||
|
catch (Exception e) {
|
||||||
|
fmt_v = ResFormat.bytes;
|
||||||
|
writeMessage(true, format(fmt_item_rep, "format", to!string(fmt_v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idt_v == "" && tpe_v == ResType.aFile)
|
||||||
|
writeMessage(true, format(fmt_item_rep, "identifier", "the striped filename"));
|
||||||
|
|
||||||
|
if (idt_v != "" && tpe_v == ResType.aFolder)
|
||||||
|
writeMessage(true, format(fmt_item_rep,
|
||||||
|
"identifier", "the striped filename of each entry in the direrctory"));
|
||||||
|
|
||||||
if (nme_v.isDir)
|
if (nme_v.isDir)
|
||||||
foreach(e; dirEntries(nme_v, SpanMode.shallow))
|
{
|
||||||
nme_vs ~= e;
|
foreach(e; dirEntries(nme_v, SpanMode.shallow)) nme_vs ~= e;
|
||||||
|
idt_v = "";
|
||||||
|
}
|
||||||
else nme_vs ~= nme_v;
|
else nme_vs ~= nme_v;
|
||||||
|
|
||||||
foreach(n; nme_vs)
|
foreach(n; nme_vs)
|
||||||
{
|
{
|
||||||
// creates item for the file n
|
items ~= new ResourceItem(n, fmt_v, idt_v, mdt_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void json_print(ref JSONValue value)
|
|
||||||
{
|
|
||||||
|
|
||||||
writeln("-------------");
|
|
||||||
JSON_TYPE tp = value.type;
|
|
||||||
final switch(tp){
|
|
||||||
case JSON_TYPE.ARRAY:
|
|
||||||
foreach(v; value.array)
|
|
||||||
json_print(v);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.FALSE:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.FLOAT:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.INTEGER:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.NULL:
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.OBJECT:
|
|
||||||
writeln(value);
|
|
||||||
writeln(("identifier" in value.object) != null);
|
|
||||||
foreach(v; value.object)
|
|
||||||
json_print(v);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.STRING:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.TRUE:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
case JSON_TYPE.UINTEGER:
|
|
||||||
writeln(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
json_print(root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Items2Module(string fname, ref ResourceItems items)
|
/**
|
||||||
|
* Writes the ResourceItems *items* as valid D code D in a file whose content
|
||||||
|
* will be imported by the library template activateResman(). The file written
|
||||||
|
* in this method has the same name as the JSON file analyzed before, but with
|
||||||
|
* another extension.
|
||||||
|
* Params:
|
||||||
|
* fname = the name of the JSON file parsed previously.
|
||||||
|
* items = an array of *ResourceItem*
|
||||||
|
*/
|
||||||
|
void Items2Module(string fname, ref ResourceItems resItems)
|
||||||
{
|
{
|
||||||
|
string outputFname = fname.stripExtension ~ ".resdata";
|
||||||
|
if (outputFname.exists) std.file.remove(outputFname);
|
||||||
|
|
||||||
|
// writes the resource representations to the module
|
||||||
|
writeMessage(true, "writing the resources data as text...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const resource_txt = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resText));
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resText));
|
||||||
|
|
||||||
|
// writes the resources identifiers to the module
|
||||||
|
writeMessage(true, "writing the resources identifiers...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const resource_idt = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resIdentifier));
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resIdentifier));
|
||||||
|
|
||||||
|
// writes the resources metadata to the module
|
||||||
|
writeMessage(true, "writing the resources metadata...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const resource_mdt = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resMetaData));
|
||||||
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resMetaData));
|
||||||
|
|
||||||
|
// writes the resources encoder kind to the module
|
||||||
|
writeMessage(true, "writing the resources kind...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const resource_enc = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t%s.%s,", ResFormat.stringof, resItems[i].resFormat));
|
||||||
|
outputFname.append(format("\r\n\t%s.%s \r\n];", ResFormat.stringof, resItems[$-1].resFormat));
|
||||||
|
|
||||||
|
// writes the initial sums to the module
|
||||||
|
writeMessage(true, "writing the resources initial sum...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const uint[] resource_sumi = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ ",", resItems[i].initialSum));
|
||||||
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ "\r\n];", resItems[$-1].initialSum));
|
||||||
|
|
||||||
|
// writes the encoded sums to the module
|
||||||
|
writeMessage(true, "writing the resources encoded sum...");
|
||||||
|
outputFname.append("\r\n\r\n");
|
||||||
|
outputFname.append("private static const uint[] resource_sume = [");
|
||||||
|
foreach (i; 0 .. resItems.length -1)
|
||||||
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ ",", resItems[i].encodedSum));
|
||||||
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ "\r\n];", resItems[$-1].encodedSum));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
|
private static const resource_txt = [
|
||||||
|
"Ibl@q4gj0X0000dnK#lE0000g0000g2Ngne03y?jve{oc8fwqHBw)9&BA.elwDk2bz^)o2nO})GwM08Fwo&gpwJP})0gltCk#-9.v/loaklAiZ1W}dTCKCJ[Vl@Jrk{W*62E1j]sj&ZBXJOZK%nI$(+Nn}2@!g:f!ZYlnRLUWOG$b5Q4exCS4*fxWk5*#:Z.AI&3ZS*$c(K:zXiK818w<qBVlkSiL%uRr0aZM]7z(bZ^a^qFtRa!msyRwmU!dJpBor{^I9IedNAp1FY:9GWFd.?[u&SPYv[pSCzwi6J002OVpdhlKv1FvU0SSi2"
|
||||||
|
];
|
||||||
|
|
||||||
|
private static const resource_idt = [
|
||||||
|
"image1"
|
||||||
|
];
|
||||||
|
|
||||||
|
private static const resource_mdt = [
|
||||||
|
"bla|abl"
|
||||||
|
];
|
||||||
|
|
||||||
|
private static const resource_enc = [
|
||||||
|
ResFormat.z85
|
||||||
|
];
|
||||||
|
|
||||||
|
private static const uint[] resource_sumi = [
|
||||||
|
3830768605
|
||||||
|
];
|
||||||
|
|
||||||
|
private static const uint[] resource_sume = [
|
||||||
|
3301322969
|
||||||
|
];
|
|
@ -1 +1 @@
|
||||||
{ "Name" : "", "Tag" : 0, "items" : [{ "format" : "bytes", "identifier" : "img1", "metadata" : "bla|oops", "name" : "C:\\Dev\\dproj\\Resource.d\\res\\res_img1.png", "resourceType" : "aFile" }, { "format" : "bytes", "identifier" : "<id_for_item1>", "metadata" : "", "name" : "", "resourceType" : "aFile" }] }
|
{ "Name" : "", "Tag" : 0, "resources" : [{ "format" : "z85", "identifier" : "image1", "metadata" : "bla|abl", "name" : "C:\\Dev\\dproj\\Resource.d\\res\\res_img1.png", "resourceType" : "aFile" }] }
|
|
@ -1 +1,65 @@
|
||||||
module utils;
|
module utils;
|
||||||
|
|
||||||
|
|
||||||
|
private static const hexDigits = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hexadecimal representation of a ubyte.
|
||||||
|
* "to!string(int, radix)" is not used because it strips the leading 0 off.
|
||||||
|
*/
|
||||||
|
public char[2] ubyte2Hex(ubyte aUbyte)
|
||||||
|
{
|
||||||
|
char[2] result;
|
||||||
|
result[1] = hexDigits[(aUbyte & 0x0F)];
|
||||||
|
result[0] = hexDigits[(aUbyte & 0xF0) >> 4];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a CRC32 to a BigEndian uint.
|
||||||
|
* It grants a resource module to be cross-plateform.
|
||||||
|
*/
|
||||||
|
public uint crc322uint(in ubyte[4] aCrc32)
|
||||||
|
{
|
||||||
|
uint result;
|
||||||
|
ubyte* ptr = cast(ubyte*) &result;
|
||||||
|
version(BigEndian)
|
||||||
|
foreach(i; 0..4) * (ptr + i) = aCrc32[i];
|
||||||
|
else
|
||||||
|
foreach(i; 0..4) * (ptr + i) = aCrc32[3-i];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* splits the encoded resource representation in multiple lines.
|
||||||
|
* Problem: not UTF-8 aware (does not always split on a code point)
|
||||||
|
*/
|
||||||
|
string splitConstString(char[] input, size_t columns = 80)
|
||||||
|
{
|
||||||
|
size_t lo, hi;
|
||||||
|
string result;
|
||||||
|
auto lines = input.length / columns;
|
||||||
|
foreach(i; 0 .. lines){
|
||||||
|
lo = i * columns;
|
||||||
|
hi = lo + columns;
|
||||||
|
result ~= "\t\"" ~ input[lo .. hi] ~ "\" ~\r\n";
|
||||||
|
}
|
||||||
|
result ~= "\t" ~ "\"" ~ input[hi .. $-1] ~ "\"";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a log message if verbose.
|
||||||
|
*/
|
||||||
|
void writeMessage(bool verbose, lazy string aMessage){
|
||||||
|
import std.stdio : writefln;
|
||||||
|
if (!verbose) return;
|
||||||
|
writefln("%s", aMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Self-centered init.
|
||||||
|
*/
|
||||||
|
void reset(T)(ref T aValue){
|
||||||
|
aValue = aValue.init;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
module z85;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Z85 is Copyright (c) 2010-2013 iMatix Corporation and Contributors
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import std.stdio, std.conv;
|
||||||
|
|
||||||
|
/// Maps base 256 to base 85
|
||||||
|
static string encoder =
|
||||||
|
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a byte array as a string whose charset is defined by encoder.
|
||||||
|
*
|
||||||
|
* Modified version of the reference implementation of Z85_encode.
|
||||||
|
* The tailling value is integrated to the input data before encoding:
|
||||||
|
* - the tail is added as an ubyte[tail_size]
|
||||||
|
* - the tail size is indicated in the first slot of an additional ubyte[4].
|
||||||
|
* Finally the encoded text contains up to 7 * 5 / 4 chars in more from the original z85 form.
|
||||||
|
*
|
||||||
|
* This modified version is destructive for the input data.
|
||||||
|
*/
|
||||||
|
char[] Z85_encode(ref ubyte[] input)
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(input.length);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
// appends the tail things
|
||||||
|
ubyte[] tail;
|
||||||
|
ubyte added = 4 - (input.length % 4);
|
||||||
|
tail.length = added + 4;
|
||||||
|
tail[added] = added;
|
||||||
|
input ~= tail;
|
||||||
|
assert(input.length % 4 == 0);
|
||||||
|
|
||||||
|
// reference implementation
|
||||||
|
size_t encoded_size = input.length * 5 / 4;
|
||||||
|
char[] encoded;
|
||||||
|
encoded.length = encoded_size;
|
||||||
|
uint char_nbr;
|
||||||
|
uint byte_nbr;
|
||||||
|
uint value;
|
||||||
|
while (byte_nbr < input.length)
|
||||||
|
{
|
||||||
|
value = value * 256 + input [byte_nbr++];
|
||||||
|
if ((byte_nbr & 3) == 0)
|
||||||
|
{
|
||||||
|
uint divisor = 85 * 85 * 85 * 85;
|
||||||
|
while (divisor)
|
||||||
|
{
|
||||||
|
encoded[char_nbr++] = encoder[value / divisor % 85];
|
||||||
|
divisor /= 85;
|
||||||
|
}
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (char_nbr == encoded_size);
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps base 85 to base 256
|
||||||
|
static immutable ubyte[96] z85_decoder = [
|
||||||
|
0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
|
||||||
|
0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,
|
||||||
|
0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
|
||||||
|
0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
||||||
|
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
|
||||||
|
0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,
|
||||||
|
0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
|
||||||
|
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||||
|
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
|
||||||
|
0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a string as a byte array.
|
||||||
|
*
|
||||||
|
* Modified version of the reference implementation of Z85_decode.
|
||||||
|
* It automatically handles the tail added to grant the 4/5 i/o ratio,
|
||||||
|
* as described in Z85_endcode()
|
||||||
|
*/
|
||||||
|
ubyte[] Z85_decode(in char[] input)
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert(input.length % 5 == 0);
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
// reference implementation
|
||||||
|
size_t decoded_size = input.length * 4 / 5;
|
||||||
|
ubyte[] decoded;
|
||||||
|
decoded.length = decoded_size;
|
||||||
|
uint byte_nbr;
|
||||||
|
uint char_nbr;
|
||||||
|
uint value;
|
||||||
|
while (char_nbr < input.length)
|
||||||
|
{
|
||||||
|
value = value * 85 + z85_decoder [cast(ubyte) input[char_nbr++] - 32];
|
||||||
|
if (char_nbr % 5 == 0)
|
||||||
|
{
|
||||||
|
uint divisor = 256 * 256 * 256;
|
||||||
|
while (divisor)
|
||||||
|
{
|
||||||
|
decoded[byte_nbr++] = value / divisor % 256;
|
||||||
|
divisor /= 256;
|
||||||
|
}
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert (byte_nbr == decoded_size);
|
||||||
|
|
||||||
|
// removes the tail things.
|
||||||
|
ubyte added = decoded[$-4];
|
||||||
|
decoded = decoded[0..$- (4 + added)];
|
||||||
|
|
||||||
|
return decoded;
|
||||||
|
}
|
|
@ -125,7 +125,6 @@ end;
|
||||||
{$REGION ICEMultiDocObserver ---------------------------------------------------}
|
{$REGION ICEMultiDocObserver ---------------------------------------------------}
|
||||||
procedure TCEEditorWidget.docNew(aDoc: TCESynMemo);
|
procedure TCEEditorWidget.docNew(aDoc: TCESynMemo);
|
||||||
begin
|
begin
|
||||||
fDoc := aDoc;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEEditorWidget.docClosing(aDoc: TCESynMemo);
|
procedure TCEEditorWidget.docClosing(aDoc: TCESynMemo);
|
||||||
|
|
|
@ -78,12 +78,12 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLibraryManager.addDubPackages;
|
procedure TLibraryManager.addDubPackages;
|
||||||
var
|
//var
|
||||||
path: string;
|
//path: string;
|
||||||
begin
|
begin
|
||||||
if not exeInSysPath('dub' + exeExt) then exit;
|
if not exeInSysPath('dub' + exeExt) then exit;
|
||||||
//
|
//
|
||||||
path := getUserDocPath + 'dub' + DirectorySeparator + 'packages';
|
//path := getUserDocPath + 'dub' + DirectorySeparator + 'packages';
|
||||||
{
|
{
|
||||||
get folders
|
get folders
|
||||||
foreach folder in folders
|
foreach folder in folders
|
||||||
|
|
|
@ -137,7 +137,7 @@ inherited CEProjectConfigurationWidget: TCEProjectConfigurationWidget
|
||||||
Width = 5
|
Width = 5
|
||||||
AutoSnap = False
|
AutoSnap = False
|
||||||
end
|
end
|
||||||
object Grid: TTIPropertyGrid
|
object inspector: TTIPropertyGrid
|
||||||
Left = 165
|
Left = 165
|
||||||
Height = 239
|
Height = 239
|
||||||
Top = 0
|
Top = 0
|
||||||
|
@ -147,8 +147,8 @@ inherited CEProjectConfigurationWidget: TCEProjectConfigurationWidget
|
||||||
Filter = [tkInteger, tkChar, tkEnumeration, tkFloat, tkSet, tkMethod, tkSString, tkLString, tkAString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkClass, tkWChar, tkBool, tkInt64, tkQWord, tkDynArray, tkInterfaceRaw, tkProcVar, tkUString, tkUChar, tkHelper]
|
Filter = [tkInteger, tkChar, tkEnumeration, tkFloat, tkSet, tkMethod, tkSString, tkLString, tkAString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkClass, tkWChar, tkBool, tkInt64, tkQWord, tkDynArray, tkInterfaceRaw, tkProcVar, tkUString, tkUChar, tkHelper]
|
||||||
Indent = 16
|
Indent = 16
|
||||||
NameFont.Color = clWindowText
|
NameFont.Color = clWindowText
|
||||||
OnEditorFilter = GridEditorFilter
|
OnEditorFilter = inspectorEditorFilter
|
||||||
OnModified = GridModified
|
OnModified = inspectorModified
|
||||||
PreferredSplitterX = 145
|
PreferredSplitterX = 145
|
||||||
SplitterX = 145
|
SplitterX = 145
|
||||||
ValueFont.Color = clGreen
|
ValueFont.Color = clGreen
|
||||||
|
|
|
@ -24,14 +24,14 @@ type
|
||||||
btnDelConf: TSpeedButton;
|
btnDelConf: TSpeedButton;
|
||||||
btnCloneConf: TSpeedButton;
|
btnCloneConf: TSpeedButton;
|
||||||
Splitter1: TSplitter;
|
Splitter1: TSplitter;
|
||||||
Grid: TTIPropertyGrid;
|
inspector: TTIPropertyGrid;
|
||||||
Tree: TTreeView;
|
Tree: TTreeView;
|
||||||
procedure btnAddConfClick(Sender: TObject);
|
procedure btnAddConfClick(Sender: TObject);
|
||||||
procedure btnDelConfClick(Sender: TObject);
|
procedure btnDelConfClick(Sender: TObject);
|
||||||
procedure btnCloneCurrClick(Sender: TObject);
|
procedure btnCloneCurrClick(Sender: TObject);
|
||||||
procedure btnSyncEditClick(Sender: TObject);
|
procedure btnSyncEditClick(Sender: TObject);
|
||||||
procedure GridEditorFilter(Sender: TObject; aEditor: TPropertyEditor;var aShow: boolean);
|
procedure inspectorEditorFilter(Sender: TObject; aEditor: TPropertyEditor;var aShow: boolean);
|
||||||
procedure GridModified(Sender: TObject);
|
procedure inspectorModified(Sender: TObject);
|
||||||
procedure selConfChange(Sender: TObject);
|
procedure selConfChange(Sender: TObject);
|
||||||
procedure TreeChange(Sender: TObject; Node: TTreeNode);
|
procedure TreeChange(Sender: TObject; Node: TTreeNode);
|
||||||
procedure GridFilter(Sender: TObject; aEditor: TPropertyEditor;var aShow: boolean);
|
procedure GridFilter(Sender: TObject; aEditor: TPropertyEditor;var aShow: boolean);
|
||||||
|
@ -80,7 +80,7 @@ begin
|
||||||
png.Free;
|
png.Free;
|
||||||
end;
|
end;
|
||||||
Tree.Selected := Tree.Items.GetLastNode;
|
Tree.Selected := Tree.Items.GetLastNode;
|
||||||
Grid.OnEditorFilter := @GridFilter;
|
inspector.OnEditorFilter := @GridFilter;
|
||||||
//
|
//
|
||||||
EntitiesConnector.addObserver(self);
|
EntitiesConnector.addObserver(self);
|
||||||
end;
|
end;
|
||||||
|
@ -105,8 +105,8 @@ procedure TCEProjectConfigurationWidget.projClosing(aProject: TCEProject);
|
||||||
begin
|
begin
|
||||||
if fProj <> aProject then
|
if fProj <> aProject then
|
||||||
exit;
|
exit;
|
||||||
Grid.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
Grid.ItemIndex := -1;
|
inspector.ItemIndex := -1;
|
||||||
self.selConf.Clear;
|
self.selConf.Clear;
|
||||||
syncroMode := false;
|
syncroMode := false;
|
||||||
fProj := nil;
|
fProj := nil;
|
||||||
|
@ -148,10 +148,10 @@ end;
|
||||||
procedure TCEProjectConfigurationWidget.TreeChange(Sender: TObject;
|
procedure TCEProjectConfigurationWidget.TreeChange(Sender: TObject;
|
||||||
Node: TTreeNode);
|
Node: TTreeNode);
|
||||||
begin
|
begin
|
||||||
Grid.TIObject := getGridTarget;
|
inspector.TIObject := getGridTarget;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEProjectConfigurationWidget.GridEditorFilter(Sender: TObject;
|
procedure TCEProjectConfigurationWidget.inspectorEditorFilter(Sender: TObject;
|
||||||
aEditor: TPropertyEditor; var aShow: boolean);
|
aEditor: TPropertyEditor; var aShow: boolean);
|
||||||
begin
|
begin
|
||||||
if aEditor.ClassType = TCollectionPropertyEditor then aShow := false;
|
if aEditor.ClassType = TCollectionPropertyEditor then aShow := false;
|
||||||
|
@ -184,7 +184,7 @@ begin
|
||||||
fSyncroPropValue := Value;
|
fSyncroPropValue := Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEProjectConfigurationWidget.GridModified(Sender: TObject);
|
procedure TCEProjectConfigurationWidget.inspectorModified(Sender: TObject);
|
||||||
var
|
var
|
||||||
propstr: string;
|
propstr: string;
|
||||||
src_list, trg_list: rttiutils.TPropInfoList;
|
src_list, trg_list: rttiutils.TPropInfoList;
|
||||||
|
@ -195,14 +195,14 @@ var
|
||||||
begin
|
begin
|
||||||
if fProj = nil then exit;
|
if fProj = nil then exit;
|
||||||
if not fSyncroMode then exit;
|
if not fSyncroMode then exit;
|
||||||
if Grid.TIObject = nil then exit;
|
if inspector.TIObject = nil then exit;
|
||||||
if Grid.ItemIndex = -1 then exit;
|
if inspector.ItemIndex = -1 then exit;
|
||||||
//
|
//
|
||||||
storage := nil;
|
storage := nil;
|
||||||
src_prop:= nil;
|
src_prop:= nil;
|
||||||
trg_prop:= nil;
|
trg_prop:= nil;
|
||||||
trg_obj := nil;
|
trg_obj := nil;
|
||||||
propstr := Grid.PropertyPath(Grid.ItemIndex);
|
propstr := inspector.PropertyPath(inspector.ItemIndex);
|
||||||
storage := rttiutils.TPropsStorage.Create;
|
storage := rttiutils.TPropsStorage.Create;
|
||||||
storage.OnReadString := @syncroSetPropAsString;
|
storage.OnReadString := @syncroSetPropAsString;
|
||||||
storage.OnWriteString := @syncroGetPropAsString;
|
storage.OnWriteString := @syncroGetPropAsString;
|
||||||
|
@ -218,23 +218,23 @@ begin
|
||||||
// skip current config
|
// skip current config
|
||||||
if i = fProj.ConfigurationIndex then continue;
|
if i = fProj.ConfigurationIndex then continue;
|
||||||
// find target persistent
|
// find target persistent
|
||||||
if Grid.TIObject = fProj.currentConfiguration.messagesOptions then
|
if inspector.TIObject = fProj.currentConfiguration.messagesOptions then
|
||||||
trg_obj := fProj.configuration[i].messagesOptions else
|
trg_obj := fProj.configuration[i].messagesOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.debugingOptions then
|
if inspector.TIObject = fProj.currentConfiguration.debugingOptions then
|
||||||
trg_obj := fProj.configuration[i].debugingOptions else
|
trg_obj := fProj.configuration[i].debugingOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.documentationOptions then
|
if inspector.TIObject = fProj.currentConfiguration.documentationOptions then
|
||||||
trg_obj := fProj.configuration[i].documentationOptions else
|
trg_obj := fProj.configuration[i].documentationOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.outputOptions then
|
if inspector.TIObject = fProj.currentConfiguration.outputOptions then
|
||||||
trg_obj := fProj.configuration[i].outputOptions else
|
trg_obj := fProj.configuration[i].outputOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.otherOptions then
|
if inspector.TIObject = fProj.currentConfiguration.otherOptions then
|
||||||
trg_obj := fProj.configuration[i].otherOptions else
|
trg_obj := fProj.configuration[i].otherOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.pathsOptions then
|
if inspector.TIObject = fProj.currentConfiguration.pathsOptions then
|
||||||
trg_obj := fProj.configuration[i].pathsOptions else
|
trg_obj := fProj.configuration[i].pathsOptions else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.preBuildProcess then
|
if inspector.TIObject = fProj.currentConfiguration.preBuildProcess then
|
||||||
trg_obj := fProj.configuration[i].preBuildProcess else
|
trg_obj := fProj.configuration[i].preBuildProcess else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.postBuildProcess then
|
if inspector.TIObject = fProj.currentConfiguration.postBuildProcess then
|
||||||
trg_obj := fProj.configuration[i].postBuildProcess else
|
trg_obj := fProj.configuration[i].postBuildProcess else
|
||||||
if Grid.TIObject = fProj.currentConfiguration.runOptions then
|
if inspector.TIObject = fProj.currentConfiguration.runOptions then
|
||||||
trg_obj := fProj.configuration[i].runOptions
|
trg_obj := fProj.configuration[i].runOptions
|
||||||
else continue;
|
else continue;
|
||||||
// find target property
|
// find target property
|
||||||
|
@ -279,8 +279,8 @@ begin
|
||||||
if fProj.OptionsCollection.Count = 1 then exit;
|
if fProj.OptionsCollection.Count = 1 then exit;
|
||||||
//
|
//
|
||||||
beginUpdateByEvent;
|
beginUpdateByEvent;
|
||||||
Grid.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
Grid.Clear;
|
inspector.Clear;
|
||||||
Invalidate;
|
Invalidate;
|
||||||
fProj.OptionsCollection.Delete(selConf.ItemIndex);
|
fProj.OptionsCollection.Delete(selConf.ItemIndex);
|
||||||
fProj.ConfigurationIndex := 0;
|
fProj.ConfigurationIndex := 0;
|
||||||
|
@ -363,7 +363,7 @@ begin
|
||||||
selConf.Items.Add(fProj.configuration[i].name);
|
selConf.Items.Add(fProj.configuration[i].name);
|
||||||
selConf.ItemIndex := fProj.ConfigurationIndex;
|
selConf.ItemIndex := fProj.ConfigurationIndex;
|
||||||
|
|
||||||
Grid.TIObject := getGridTarget;
|
inspector.TIObject := getGridTarget;
|
||||||
end;
|
end;
|
||||||
{$ENDREGION --------------------------------------------------------------------}
|
{$ENDREGION --------------------------------------------------------------------}
|
||||||
|
|
||||||
|
|
|
@ -63,14 +63,14 @@ inherited CEResmanWidget: TCEResmanWidget
|
||||||
ClientHeight = 295
|
ClientHeight = 295
|
||||||
ClientWidth = 424
|
ClientWidth = 424
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object lstItems: TListBox
|
object lstRes: TListBox
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 295
|
Height = 295
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 160
|
Width = 160
|
||||||
Align = alLeft
|
Align = alLeft
|
||||||
ItemHeight = 0
|
ItemHeight = 0
|
||||||
OnSelectionChange = lstItemsSelectionChange
|
OnSelectionChange = lstResSelectionChange
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
end
|
end
|
||||||
object Splitter1: TSplitter
|
object Splitter1: TSplitter
|
||||||
|
@ -80,7 +80,7 @@ inherited CEResmanWidget: TCEResmanWidget
|
||||||
Width = 5
|
Width = 5
|
||||||
AutoSnap = False
|
AutoSnap = False
|
||||||
end
|
end
|
||||||
object propsEd: TTIPropertyGrid
|
object inspector: TTIPropertyGrid
|
||||||
Left = 165
|
Left = 165
|
||||||
Height = 295
|
Height = 295
|
||||||
Top = 0
|
Top = 0
|
||||||
|
@ -90,7 +90,7 @@ inherited CEResmanWidget: TCEResmanWidget
|
||||||
Filter = [tkInteger, tkChar, tkEnumeration, tkFloat, tkSet, tkMethod, tkSString, tkLString, tkAString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkClass, tkObject, tkWChar, tkBool, tkInt64, tkQWord, tkDynArray, tkInterfaceRaw, tkProcVar, tkUString, tkUChar, tkHelper]
|
Filter = [tkInteger, tkChar, tkEnumeration, tkFloat, tkSet, tkMethod, tkSString, tkLString, tkAString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkClass, tkObject, tkWChar, tkBool, tkInt64, tkQWord, tkDynArray, tkInterfaceRaw, tkProcVar, tkUString, tkUChar, tkHelper]
|
||||||
Indent = 16
|
Indent = 16
|
||||||
NameFont.Color = clWindowText
|
NameFont.Color = clWindowText
|
||||||
OnModified = propsEdModified
|
OnModified = inspectorModified
|
||||||
ValueFont.Color = clMaroon
|
ValueFont.Color = clMaroon
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ type
|
||||||
|
|
||||||
|
|
||||||
TResourceType = (aFile, aFolder);
|
TResourceType = (aFile, aFolder);
|
||||||
TResourceFormat = (bytes, utf8, base16, base64);
|
TResourceFormat = (bytes, utf8, base16, base64, z85, e7F);
|
||||||
|
|
||||||
TResourceItem = class(TCollectionItem)
|
TResourceItem = class(TCollectionItem)
|
||||||
private
|
private
|
||||||
|
@ -34,43 +34,47 @@ type
|
||||||
* Represents a resource script. The resource script use the
|
* Represents a resource script. The resource script use the
|
||||||
* JSON format for a better compatibility with the tool.
|
* JSON format for a better compatibility with the tool.
|
||||||
*)
|
*)
|
||||||
TResourceItems = class(TWritableComponent)
|
TResources = class(TWritableComponent)
|
||||||
private
|
private
|
||||||
fItems: TCollection;
|
fResources: TCollection;
|
||||||
procedure setItems(aValue: TCollection);
|
procedure setResources(aValue: TCollection);
|
||||||
|
function getResource(index: Integer): TResourceItem;
|
||||||
published
|
published
|
||||||
property items: TCollection read fItems write setItems;
|
property resources: TCollection read fResources write setResources;
|
||||||
public
|
public
|
||||||
constructor create(aOwner: TComponent); override;
|
constructor create(aOwner: TComponent); override;
|
||||||
destructor destroy; override;
|
destructor destroy; override;
|
||||||
// overides the component streaming methods to use JSON instead of lfm
|
// overides the component streaming methods to use JSON instead of lfm
|
||||||
procedure saveToFile(const aFilename: string); override;
|
procedure saveToFile(const aFilename: string); override;
|
||||||
procedure loadFromFile(const aFilename: string); override;
|
procedure loadFromFile(const aFilename: string); override;
|
||||||
|
property resource[index: Integer]: TResourceItem read getResource; default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCEResmanWidget }
|
{ TCEResmanWidget }
|
||||||
TCEResmanWidget = class(TCEWidget, ICEProjectObserver, ICEMultiDocObserver)
|
TCEResmanWidget = class(TCEWidget, ICEProjectObserver, ICEMultiDocObserver)
|
||||||
BtnAddItem: TBitBtn;
|
BtnAddItem: TBitBtn;
|
||||||
btnRemItem: TBitBtn;
|
btnRemItem: TBitBtn;
|
||||||
lstItems: TListBox;
|
lstRes: TListBox;
|
||||||
Panel1: TPanel;
|
Panel1: TPanel;
|
||||||
Panel2: TPanel;
|
Panel2: TPanel;
|
||||||
propsEd: TTIPropertyGrid;
|
inspector: TTIPropertyGrid;
|
||||||
Splitter1: TSplitter;
|
Splitter1: TSplitter;
|
||||||
procedure BtnAddItemClick(Sender: TObject);
|
procedure BtnAddItemClick(Sender: TObject);
|
||||||
procedure btnRemItemClick(Sender: TObject);
|
procedure btnRemItemClick(Sender: TObject);
|
||||||
procedure lstItemsSelectionChange(Sender: TObject; User: boolean);
|
procedure lstResSelectionChange(Sender: TObject; User: boolean);
|
||||||
procedure propsEdModified(Sender: TObject);
|
procedure inspectorModified(Sender: TObject);
|
||||||
private
|
private
|
||||||
fProj: TCEProject;
|
fProj: TCEProject;
|
||||||
fDoc: TCESynMemo;
|
fDoc: TCESynMemo;
|
||||||
fResourceItems: TResourceItems;
|
fResourceItems: TResources;
|
||||||
|
fLogMessager: TCELogMessageSubject;
|
||||||
// try to load the json resource script for the current doc
|
// try to load the json resource script for the current doc
|
||||||
procedure loadDocResJson;
|
procedure loadDocResJson;
|
||||||
// try to save the json resource script for the current doc
|
// try to save the json resource script for the current doc
|
||||||
procedure saveDocResJson;
|
procedure saveDocResJson;
|
||||||
procedure refreshItemList;
|
procedure clearInspector;
|
||||||
procedure updateIdentifierList;
|
procedure rebuildResList;
|
||||||
|
procedure updateResList;
|
||||||
procedure genResources;
|
procedure genResources;
|
||||||
//
|
//
|
||||||
procedure projNew(aProject: TCEProject);
|
procedure projNew(aProject: TCEProject);
|
||||||
|
@ -85,25 +89,31 @@ type
|
||||||
procedure docClosing(aDoc: TCESynMemo);
|
procedure docClosing(aDoc: TCESynMemo);
|
||||||
public
|
public
|
||||||
constructor create(aOwner: TComponent); override;
|
constructor create(aOwner: TComponent); override;
|
||||||
|
destructor destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
{$REGION TResourceItems --------------------------------------------------------}
|
{$REGION TResources ------------------------------------------------------------}
|
||||||
constructor TResourceItems.Create(aOwner: TCOmponent);
|
constructor TResources.Create(aOwner: TCOmponent);
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
fItems := TCollection.Create(TResourceItem);
|
fResources := TCollection.Create(TResourceItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TResourceItems.destroy;
|
destructor TResources.destroy;
|
||||||
begin
|
begin
|
||||||
fItems.Free;
|
fResources.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TResourceItems.saveToFile(const aFilename: string);
|
function TResources.getResource(index: Integer): TResourceItem;
|
||||||
|
begin
|
||||||
|
result := TResourceItem(fResources.Items[index]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TResources.saveToFile(const aFilename: string);
|
||||||
var
|
var
|
||||||
json_streamer: TJSONStreamer;
|
json_streamer: TJSONStreamer;
|
||||||
json_string: TJSONStringType;
|
json_string: TJSONStringType;
|
||||||
|
@ -129,7 +139,7 @@ begin
|
||||||
afterSave;
|
afterSave;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TResourceItems.loadFromFile(const aFilename: string);
|
procedure TResources.loadFromFile(const aFilename: string);
|
||||||
var
|
var
|
||||||
json_destreamer: TJSONDeStreamer;
|
json_destreamer: TJSONDeStreamer;
|
||||||
json_string: TJSONStringType;
|
json_string: TJSONStringType;
|
||||||
|
@ -152,18 +162,20 @@ begin
|
||||||
afterLoad;
|
afterLoad;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TResourceItems.setItems(aValue: TCollection);
|
procedure TResources.setResources(aValue: TCollection);
|
||||||
begin
|
begin
|
||||||
fItems.Assign(aValue);
|
fResources.Assign(aValue);
|
||||||
end;
|
end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
|
{$REGION Standard Comp/Obj------------------------------------------------------}
|
||||||
constructor TCEResmanWidget.create(aOwner: TComponent);
|
constructor TCEResmanWidget.create(aOwner: TComponent);
|
||||||
var
|
var
|
||||||
png: TPortableNetworkGraphic;
|
png: TPortableNetworkGraphic;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
fResourceItems := TResourceItems.create(self);
|
fLogMessager := TCELogMessageSubject.create;
|
||||||
|
fResourceItems := TResources.create(self);
|
||||||
//
|
//
|
||||||
png := TPortableNetworkGraphic.Create;
|
png := TPortableNetworkGraphic.Create;
|
||||||
try
|
try
|
||||||
|
@ -176,6 +188,13 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TCEResmanWidget.destroy;
|
||||||
|
begin
|
||||||
|
fLogMessager.Free;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
{$ENDREGION}
|
||||||
|
|
||||||
{$REGION ICEProjectObserver ----------------------------------------------------}
|
{$REGION ICEProjectObserver ----------------------------------------------------}
|
||||||
procedure TCEResmanWidget.projNew(aProject: TCEProject);
|
procedure TCEResmanWidget.projNew(aProject: TCEProject);
|
||||||
begin
|
begin
|
||||||
|
@ -193,10 +212,10 @@ procedure TCEResmanWidget.projClosing(aProject: TCEProject);
|
||||||
begin
|
begin
|
||||||
if fProj <> aProject then exit;
|
if fProj <> aProject then exit;
|
||||||
fProj := nil;
|
fProj := nil;
|
||||||
propsEd.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
propsEd.ItemIndex := -1;
|
inspector.ItemIndex := -1;
|
||||||
fResourceItems.Items.Clear;
|
fResourceItems.resources.Clear;
|
||||||
refreshItemList;
|
rebuildResList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.projFocused(aProject: TCEProject);
|
procedure TCEResmanWidget.projFocused(aProject: TCEProject);
|
||||||
|
@ -229,7 +248,7 @@ begin
|
||||||
//
|
//
|
||||||
saveDocResJson;
|
saveDocResJson;
|
||||||
fDoc := nil;
|
fDoc := nil;
|
||||||
refreshItemList;
|
rebuildResList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.docFocused(aDoc: TCESynMemo);
|
procedure TCEResmanWidget.docFocused(aDoc: TCESynMemo);
|
||||||
|
@ -240,20 +259,20 @@ end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
{$REGION Resources things -----------------------------------------------------}
|
{$REGION Resources things -----------------------------------------------------}
|
||||||
procedure TCEResmanWidget.lstItemsSelectionChange(Sender: TObject; User: boolean);
|
procedure TCEResmanWidget.lstResSelectionChange(Sender: TObject; User: boolean);
|
||||||
begin
|
begin
|
||||||
if lstItems.Count = 0 then exit;
|
if lstRes.Count = 0 then exit;
|
||||||
if lstItems.ItemIndex = -1 then exit;
|
if lstRes.ItemIndex = -1 then exit;
|
||||||
//
|
//
|
||||||
propsEd.TIObject := TPersistent(lstItems.Items.Objects[lstItems.ItemIndex]);
|
inspector.TIObject := fResourceItems[lstRes.ItemIndex];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.propsEdModified(Sender: TObject);
|
procedure TCEResmanWidget.inspectorModified(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if propsEd.ItemIndex = -1 then
|
if inspector.ItemIndex = -1 then
|
||||||
exit;
|
exit;
|
||||||
if propsEd.Rows[propsEd.ItemIndex].Name = 'identifier' then
|
if inspector.Rows[inspector.ItemIndex].Name = 'identifier' then
|
||||||
updateIdentifierList;
|
updateResList;
|
||||||
saveDocResJson;
|
saveDocResJson;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -261,20 +280,20 @@ procedure TCEResmanWidget.BtnAddItemClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
item: TResourceItem;
|
item: TResourceItem;
|
||||||
begin
|
begin
|
||||||
item := TResourceItem(fResourceItems.items.Add);
|
item := TResourceItem(fResourceItems.resources.Add);
|
||||||
item.identifier := format('<id_for_item %d>' ,[item.ID]);
|
item.identifier := format('<id_for_item %d>' ,[item.ID]);
|
||||||
refreshItemList;
|
rebuildResList;
|
||||||
saveDocResJson;
|
saveDocResJson;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.btnRemItemClick(Sender: TObject);
|
procedure TCEResmanWidget.btnRemItemClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if lstItems.ItemIndex = -1 then
|
if lstRes.ItemIndex = -1 then
|
||||||
exit;
|
exit;
|
||||||
propsEd.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
propsEd.ItemIndex := -1;
|
inspector.ItemIndex := -1;
|
||||||
fResourceItems.items.Delete(lstItems.ItemIndex);
|
fResourceItems.resources.Delete(lstRes.ItemIndex);
|
||||||
refreshItemList;
|
rebuildResList;
|
||||||
saveDocResJson;
|
saveDocResJson;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -287,12 +306,12 @@ begin
|
||||||
if not fProj.isProjectSource(fDoc.fileName) then exit;
|
if not fProj.isProjectSource(fDoc.fileName) then exit;
|
||||||
//
|
//
|
||||||
fname := stripFileExt(fDoc.fileName) + '.resman';
|
fname := stripFileExt(fDoc.fileName) + '.resman';
|
||||||
propsEd.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
propsEd.ItemIndex := -1;
|
inspector.ItemIndex := -1;
|
||||||
fResourceItems.Items.Clear;
|
fResourceItems.resources.Clear;
|
||||||
if fileExists(fname) then
|
if fileExists(fname) then
|
||||||
fResourceItems.loadFromFile(fname);
|
fResourceItems.loadFromFile(fname);
|
||||||
refreshItemList;
|
rebuildResList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.saveDocResJson;
|
procedure TCEResmanWidget.saveDocResJson;
|
||||||
|
@ -304,7 +323,7 @@ begin
|
||||||
if not fProj.isProjectSource(fDoc.fileName) then exit;
|
if not fProj.isProjectSource(fDoc.fileName) then exit;
|
||||||
//
|
//
|
||||||
fname := stripFileExt(fDoc.fileName) + '.resman';
|
fname := stripFileExt(fDoc.fileName) + '.resman';
|
||||||
if fResourceItems.Items.Count = 0 then exit;
|
if fResourceItems.resources.Count = 0 then exit;
|
||||||
//
|
//
|
||||||
fResourceItems.saveToFile(fname);
|
fResourceItems.saveToFile(fname);
|
||||||
end;
|
end;
|
||||||
|
@ -312,17 +331,19 @@ end;
|
||||||
procedure TCEResmanWidget.genResources;
|
procedure TCEResmanWidget.genResources;
|
||||||
var
|
var
|
||||||
proc: TProcess;
|
proc: TProcess;
|
||||||
fname: string;
|
str: TStringList;
|
||||||
|
fname, msg: string;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if fProj = nil then exit;
|
if fProj = nil then exit;
|
||||||
if not exeInSysPath('resman' + exeExt) then exit;
|
if not exeInSysPath('resman' + exeExt) then exit;
|
||||||
//
|
//
|
||||||
proc := Tprocess.Create(nil);
|
proc := TProcess.Create(nil);
|
||||||
|
str := TStringList.Create;
|
||||||
try
|
try
|
||||||
proc.Executable:= 'resman' + exeExt;
|
proc.Executable:= 'resman' + exeExt;
|
||||||
//proc.Options := [poUsePipes, poStderrToOutPut];
|
proc.Options := [poUsePipes, poStderrToOutPut];
|
||||||
//proc.ShowWindow := swoHIDE;
|
proc.ShowWindow := swoHIDE;
|
||||||
proc.Parameters.Add('-v');
|
proc.Parameters.Add('-v');
|
||||||
for i := 0 to fProj.Sources.Count-1 do
|
for i := 0 to fProj.Sources.Count-1 do
|
||||||
begin
|
begin
|
||||||
|
@ -331,41 +352,45 @@ begin
|
||||||
if not FileExists(fname) then continue;
|
if not FileExists(fname) then continue;
|
||||||
proc.Parameters.Add(fname);
|
proc.Parameters.Add(fname);
|
||||||
end;
|
end;
|
||||||
|
msg := 'generating the resources...';
|
||||||
|
subjLmFromString(fLogMessager, msg, fProj, amcProj, amkInf);
|
||||||
proc.Execute;
|
proc.Execute;
|
||||||
while proc.Running do;
|
while proc.Running do begin
|
||||||
// output to project message...
|
processOutputToStrings(proc, str);
|
||||||
|
for msg in str do
|
||||||
|
subjLmFromString(fLogMessager, msg, fProj, amcProj, amkAuto);
|
||||||
|
end;
|
||||||
finally
|
finally
|
||||||
proc.Free;
|
proc.Free;
|
||||||
|
str.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.refreshItemList;
|
procedure TCEResmanWidget.clearInspector;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
item: TResourceItem;
|
|
||||||
begin
|
begin
|
||||||
propsEd.TIObject := nil;
|
inspector.TIObject := nil;
|
||||||
propsEd.ItemIndex := -1;
|
inspector.ItemIndex := -1;
|
||||||
lstItems.Items.Clear;
|
|
||||||
for i:= 0 to fResourceItems.items.Count-1 do
|
|
||||||
begin
|
|
||||||
item := TResourceItem(fResourceItems.items.Items[i]);
|
|
||||||
lstItems.Items.AddObject(item.identifier, item);
|
|
||||||
end;
|
|
||||||
if lstItems.Count > 0 then
|
|
||||||
lstItems.ItemIndex := 0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEResmanWidget.updateIdentifierList;
|
procedure TCEResmanWidget.rebuildResList;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
item: TResourceItem;
|
|
||||||
begin
|
begin
|
||||||
for i:= 0 to fResourceItems.items.Count-1 do
|
clearInspector;
|
||||||
begin
|
lstRes.Items.Clear;
|
||||||
item := TResourceItem(fResourceItems.items.Items[i]);
|
//
|
||||||
lstItems.Items.Strings[i] := item.identifier;
|
for i:= 0 to fResourceItems.resources.Count-1 do
|
||||||
end;
|
lstRes.AddItem(fResourceItems[i].identifier, nil);
|
||||||
|
if lstRes.Count > 0 then
|
||||||
|
lstRes.ItemIndex := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCEResmanWidget.updateResList;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:= 0 to fResourceItems.resources.Count-1 do
|
||||||
|
lstRes.Items.Strings[i] := fResourceItems[i].identifier;
|
||||||
end;
|
end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ type
|
||||||
function addTool: TCEToolItem;
|
function addTool: TCEToolItem;
|
||||||
procedure executeTool(aTool: TCEToolItem); overload;
|
procedure executeTool(aTool: TCEToolItem); overload;
|
||||||
procedure executeTool(aToolIndex: Integer); overload;
|
procedure executeTool(aToolIndex: Integer); overload;
|
||||||
property tool[index: integer]: TCEToolItem read getTool;
|
property tool[index: integer]: TCEToolItem read getTool; default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
@ -32,8 +32,9 @@ type
|
||||||
procedure propsEdModified(Sender: TObject);
|
procedure propsEdModified(Sender: TObject);
|
||||||
private
|
private
|
||||||
procedure executeSelectedTool;
|
procedure executeSelectedTool;
|
||||||
procedure DataToGui;
|
procedure clearInspector;
|
||||||
procedure updateNames;
|
procedure rebuildToolList;
|
||||||
|
procedure updateToolList;
|
||||||
public
|
public
|
||||||
constructor create(aOwner: TComponent); override;
|
constructor create(aOwner: TComponent); override;
|
||||||
end;
|
end;
|
||||||
|
@ -61,29 +62,34 @@ begin
|
||||||
finally
|
finally
|
||||||
png.free;
|
png.free;
|
||||||
end;
|
end;
|
||||||
DataToGui;
|
rebuildToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.updateNames;
|
procedure TCEToolsEditorWidget.clearInspector;
|
||||||
|
begin
|
||||||
|
propsEd.TIObject := nil;
|
||||||
|
propsEd.ItemIndex := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCEToolsEditorWidget.rebuildToolList;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
clearInspector;
|
||||||
|
lstTools.Clear;
|
||||||
|
//
|
||||||
|
for i := 0 to CustomTools.tools.Count-1 do
|
||||||
|
lstTools.AddItem(CustomTools[i].toolAlias, nil);
|
||||||
|
if lstTools.Count > 0 then
|
||||||
|
lstTools.ItemIndex := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCEToolsEditorWidget.updateToolList;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i := 0 to CustomTools.tools.Count-1 do
|
for i := 0 to CustomTools.tools.Count-1 do
|
||||||
lstTools.Items.Strings[i] := CustomTools.tool[i].toolAlias;
|
lstTools.Items.Strings[i] := CustomTools[i].toolAlias;
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.DataToGui;
|
|
||||||
var
|
|
||||||
i: integer;
|
|
||||||
begin
|
|
||||||
propsEd.TIObject := nil;
|
|
||||||
propsEd.ItemIndex := -1;
|
|
||||||
lstTools.Clear;
|
|
||||||
//
|
|
||||||
for i := 0 to CustomTools.tools.Count-1 do
|
|
||||||
lstTools.AddItem(CustomTools.tool[i].toolAlias, nil);
|
|
||||||
if lstTools.Count > 0 then
|
|
||||||
lstTools.ItemIndex := 0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.lstToolsSelectionChange(Sender: TObject;
|
procedure TCEToolsEditorWidget.lstToolsSelectionChange(Sender: TObject;
|
||||||
|
@ -91,7 +97,7 @@ procedure TCEToolsEditorWidget.lstToolsSelectionChange(Sender: TObject;
|
||||||
begin
|
begin
|
||||||
if lstTools.ItemIndex = -1 then
|
if lstTools.ItemIndex = -1 then
|
||||||
exit;
|
exit;
|
||||||
propsEd.TIObject := CustomTools.tool[lstTools.ItemIndex];
|
propsEd.TIObject := CustomTools[lstTools.ItemIndex];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.propsEdModified(Sender: TObject);
|
procedure TCEToolsEditorWidget.propsEdModified(Sender: TObject);
|
||||||
|
@ -99,23 +105,22 @@ begin
|
||||||
if propsEd.ItemIndex = -1 then
|
if propsEd.ItemIndex = -1 then
|
||||||
exit;
|
exit;
|
||||||
if propsEd.Rows[propsEd.ItemIndex].Name = 'toolAlias' then
|
if propsEd.Rows[propsEd.ItemIndex].Name = 'toolAlias' then
|
||||||
updateNames;
|
updateToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.BtnAddToolClick(Sender: TObject);
|
procedure TCEToolsEditorWidget.BtnAddToolClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
CustomTools.addTool;
|
CustomTools.addTool;
|
||||||
DataToGui;
|
rebuildToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.btnRemToolClick(Sender: TObject);
|
procedure TCEToolsEditorWidget.btnRemToolClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if lstTools.ItemIndex = -1 then
|
if lstTools.ItemIndex = -1 then
|
||||||
exit;
|
exit;
|
||||||
propsEd.TIObject := nil;
|
clearInspector;
|
||||||
propsEd.ItemIndex := -1;
|
|
||||||
CustomTools.tools.Delete(lstTools.ItemIndex);
|
CustomTools.tools.Delete(lstTools.ItemIndex);
|
||||||
DataToGui;
|
rebuildToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.btnMoveUpClick(Sender: TObject);
|
procedure TCEToolsEditorWidget.btnMoveUpClick(Sender: TObject);
|
||||||
|
@ -125,7 +130,7 @@ begin
|
||||||
//
|
//
|
||||||
CustomTools.tools.Exchange(lstTools.ItemIndex, lstTools.ItemIndex - 1);
|
CustomTools.tools.Exchange(lstTools.ItemIndex, lstTools.ItemIndex - 1);
|
||||||
lstTools.ItemIndex := lstTools.ItemIndex - 1;
|
lstTools.ItemIndex := lstTools.ItemIndex - 1;
|
||||||
updateNames;
|
updateToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.btnMoveDownClick(Sender: TObject);
|
procedure TCEToolsEditorWidget.btnMoveDownClick(Sender: TObject);
|
||||||
|
@ -135,7 +140,7 @@ begin
|
||||||
//
|
//
|
||||||
CustomTools.tools.Exchange(lstTools.ItemIndex, lstTools.ItemIndex + 1);
|
CustomTools.tools.Exchange(lstTools.ItemIndex, lstTools.ItemIndex + 1);
|
||||||
lstTools.ItemIndex := lstTools.ItemIndex + 1;
|
lstTools.ItemIndex := lstTools.ItemIndex + 1;
|
||||||
updateNames;
|
updateToolList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEToolsEditorWidget.executeSelectedTool;
|
procedure TCEToolsEditorWidget.executeSelectedTool;
|
||||||
|
|
Loading…
Reference in New Issue