WIP: add gui to easily interface csvRead 90/20890/4
Antoine ELIAS [Tue, 26 Feb 2019 11:23:56 +0000 (12:23 +0100)]
Need : https://codereview.scilab.org/#/c/20891/

Change-Id: Id2f54670acc78070af5f2db472c1e07a1b226eed

scilab/CHANGES.md
scilab/modules/fileio/etc/fileio.start
scilab/modules/fileio/macros/buildmacros.sce
scilab/modules/fileio/macros/importgui/importgui.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_analyze.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_cbselect.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_function.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_gethead.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_preview.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_progress.sci [new file with mode: 0644]
scilab/modules/fileio/macros/importgui/importgui_variable.sci [new file with mode: 0644]

index 887fe3d..8cdebd6 100644 (file)
@@ -32,6 +32,7 @@ In summary, the main new features are:
    - strings are quoted
    - complex numbers are aligned for matrices
    - numbers (IEEE 754 double) are not rounded
+* importgui function has been added to easily interface csvRead
 
 Installation
 ------------
index ec95d73..18e8183 100644 (file)
@@ -13,6 +13,7 @@
 //Load  functions libraries
 // =============================================================================
 load('SCI/modules/fileio/macros/lib');
+load('SCI/modules/fileio/macros/importgui/lib');
 
 // Initialize CURL environment
 // =============================================================================
index 82c1e91..cfbeeae 100644 (file)
@@ -11,3 +11,4 @@
 // along with this program.
 
 genlib("fileiolib","SCI/modules/fileio/macros",%f,%t);
+genlib("fileioguilib","SCI/modules/fileio/macros/importgui",%f,%t);
diff --git a/scilab/modules/fileio/macros/importgui/importgui.sci b/scilab/modules/fileio/macros/importgui/importgui.sci
new file mode 100644 (file)
index 0000000..9090c6f
--- /dev/null
@@ -0,0 +1,174 @@
+function importgui()
+    win = get("importgui");
+    if ~isempty(win) then
+        //set visible
+        set("win", "visible", "on");
+        //set on top
+        set("win");
+        return;
+    end
+    
+    w = 800;
+    h = 600;
+    
+       fig = figure(...
+               "figure_name", _("Import data"), ...
+               "dockable", "off", ...
+               "axes_size", [w h], ...
+               "infobar_visible", "off", ...
+               "toolbar_visible", "off", ...
+               "menubar_visible", "off", ...
+               "default_axes", "off", ...
+               "background", -2, ...
+               "resize", "off", ...
+        "layout", "border", ...
+               "tag", "importgui", ...
+               "visible", "off");
+
+    //Border frame
+    t = uicontrol(fig, ...
+        "style", "frame", ...
+        "constraints", createConstraints("border", "top", [0 90]));
+        
+    c = uicontrol(fig, ...
+        "style", "frame", ...
+        "layout", "border", ...
+        "constraints", createConstraints("border", "center"));
+    
+    uicontrol(c, ...
+        "style", "frame", ...
+        "tag", "importgui_preview", ...
+        "scrollable", "on", ...
+        "layout", "gridbag", ...
+        "constraints", createConstraints("border", "center"));
+        
+    b = uicontrol(fig, ...
+        "style", "frame", ...
+        "constraints", createConstraints("border", "bottom", [0 45]));
+
+    //frame file
+    fr1 = uicontrol(t, ...
+        "style", "frame", ...
+        "position", [0 0 800 90]);
+
+    uicontrol(fr1, ...
+        "style", "text", ...
+        "position", [20 50 560 30], ...
+        "horizontalalignment", "center", ...
+        "relief", "solid", ...
+        "fontsize", 13, ...
+        "fontweight", "bold", ...
+        "tag", "importgui_filename")
+        
+    uicontrol(fr1, ...
+        "style", "pushbutton", ...
+        "string", _("Select a file"), ...
+        "callback", "importgui_cbselect", ...
+        "position", [600 50 180 30]);
+
+    uicontrol(fr1, ...
+        "style", "checkbox", ...
+        "string", _("File has a header"), ...
+        "tag", "importgui_header", ...
+        "callback", "importgui_preview", ...
+        "position", [20 20 130 25]);
+
+    uicontrol(fr1, ...
+        "style", "checkbox", ...
+        "string", _("Show all columns"), ...
+        "tooltip", _("It can take a long time"), ...
+        "tag", "importgui_showcol", ...
+        "callback", "importgui_preview", ...
+        "position", [20 0 130 25]);
+
+    uicontrol(fr1, ...
+        "style", "text", ...
+        "string", _("Separator"), ...
+        "horizontalalignment", "center", ...
+        "position", [180 10 60 25]);
+
+        uicontrol(fr1, ...
+        "style", "popupmenu", ...
+        "string", [_("Comma"), _("Space"), _("Tab"), _("Semicolon"), _("Pipe"), _("Colon")], ...
+        "userdata", [",", " ", ascii(9), ";", "|", ":"], ...
+        "value", 4, ...
+        "tag", "importgui_delim", ...
+        "callback", "importgui_preview", ...
+        "position", [240 10 120 25]);
+
+    uicontrol(fr1, ...
+        "style", "text", ...
+        "string", _("Decimal"), ...
+        "horizontalalignment", "center", ...
+        "position", [390 10 60 25]);
+
+    uicontrol(fr1, ...
+        "style", "popupmenu", ...
+        "string", [_("Point"), _("Comma")], ...
+        "userdata", [".", ","], ...
+        "value", 1, ...
+        "tag", "importgui_decimal", ...
+        "callback", "importgui_preview", ...
+        "position", [450 10 120 25]);
+
+    uicontrol(fr1, ...
+        "style", "text", ...
+        "string", _("Conversion"), ...
+        "horizontalalignment", "center", ...
+        "position", [600 10 60 25]);
+
+    uicontrol(fr1, ...
+        "style", "popupmenu", ...
+        "string", [_("Keep as strings"), _("Convert to double")], ...
+        "userdata", ["string", "double"], ...
+        "value", 1, ...
+        "tag", "importgui_conversion", ...
+        "callback", "importgui_preview", ...
+        "position", [660 10 120 25]);
+
+        
+    //footer
+    outer = uicontrol(b, ...
+        "style", "frame", ...
+        "position", [0 40 800 5], ...
+        "border", createBorder("line", "#dddddd"));
+        
+    uicontrol(outer, ...
+        "style", "frame", ...
+        "backgroundcolor", [0 120 215]./255, ...
+        "tag", "importgui_progressbar", ...
+        "position", [0 0 0 5]);
+    
+    uicontrol(b, ...
+        "style", "pushbutton", ...
+        "string", _("Import as variable"), ...
+        "callback", "importgui_variable", ...
+        "enable", "off", ...
+        "tag", "importgui_btnvarialble", ...
+        "position", [50 5 200 30]);
+        
+    uicontrol(b, ...
+        "style", "pushbutton", ...
+        "string", _("Quit"), ...
+        "callback", "delete(get(""importgui""));", ...
+        "position", [300 5 200 30]);
+        
+    uicontrol(b, ...
+        "style", "pushbutton", ...
+        "string", _("Copy function to clipboard"), ...
+        "callback", "importgui_function", ...
+        "enable", "off", ...
+        "tag", "importgui_btnfunction", ...
+        "position", [550 5 200 30]);
+        
+    sw = getsystemmetrics("SM_CXSCREEN");
+    sh = getsystemmetrics("SM_CYSCREEN");
+
+    s = fig.figure_size;
+    w = (sw - s(1)) / 2
+    h = (sh - s(2)) / 2
+    fig.figure_position = [w h];
+
+    fig.visible = "on";
+    importgui_cbselect();
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_analyze.sci b/scilab/modules/fileio/macros/importgui/importgui_analyze.sci
new file mode 100644 (file)
index 0000000..a968f20
--- /dev/null
@@ -0,0 +1,32 @@
+function delim = importgui_analyze(f, n)
+
+    if ~exists("n", "local") then
+        n = 10;
+    end
+    
+    head = mgetl(f, n);
+    n = size(head, "r");
+    
+    delimiters = get("importgui_delim", "userdata");
+    count = zeros(delimiters);
+    
+    for i = 1:n
+        l = head(i);
+        for j = 1:size(delimiters, "*")
+            r = strindex(l, delimiters(j));
+            if size(r, "*") > 1 then
+                count(j) = count(j) + 1;
+            end
+        end
+    end
+    
+    [m, k] = max(count);
+
+    if m == n then
+        delim = k;
+    else
+        //unable to find good delimiter.
+        delim = 0;
+        return;
+    end
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_cbselect.sci b/scilab/modules/fileio/macros/importgui/importgui_cbselect.sci
new file mode 100644 (file)
index 0000000..265e7d8
--- /dev/null
@@ -0,0 +1,23 @@
+function importgui_cbselect()
+
+    path = pwd();
+    f = get("importgui_filename", "string");
+    if ~isempty(f) then
+        path = fileparts(f);
+    end
+    
+    
+       path = uigetfile(["*.txt" "Text files";"*.csv" "CSV files"], path, "Choose a file", %f);
+    if ~isempty(path) then
+        set("importgui_filename", "string", path);
+        delim = importgui_analyze(path, 10);
+        if delim then
+            set("importgui_delim", "value", delim);
+            if delim == 1 then
+                set("importgui_decimal", "value", 1);
+            end
+        end
+
+        importgui_preview();
+    end
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_function.sci b/scilab/modules/fileio/macros/importgui/importgui_function.sci
new file mode 100644 (file)
index 0000000..d9f47e9
--- /dev/null
@@ -0,0 +1,54 @@
+function importgui_function()
+
+    hasHeader = get("importgui_header", "value");
+    delim = get("importgui_delim", "userdata")(get("importgui_delim", "value"));
+    decimal = get("importgui_decimal", "userdata")(get("importgui_decimal", "value"));
+    conversion = get("importgui_conversion", "userdata")(get("importgui_conversion", "value"));
+
+    path = get("importgui_filename", "string");
+
+    importHeader = %f;
+
+    if hasHeader then
+        x = x_mdialog("Create function", ["Function name";"Import header"], ["importdata";"%F"]);
+        if isempty(x) then
+            return;
+        end
+
+        importHeader = evstr(x(2));
+    else
+        x = x_mdialog("Create function", ["Function name"], ["importdata"]);
+        if isempty(x) then
+            return;
+        end
+    end
+    
+    
+    str = [];
+    str($+1) = sprintf("clear %s;", x(1));
+    str($+1) = "";
+    if importHeader then
+        str($+1) = sprintf("function [header, data] = %s(filename)", x(1));
+        str($+1) = "    header = mgetl(filename, 1);";
+        str($+1) = sprintf("    header = csvTextScan(header, ""%s"", ""%s"", ""string"");", delim, decimal);
+    else
+        str($+1) = sprintf("function [data] = %s(filename)", x(1));
+    end
+    
+    if hasHeader then
+        str($+1) = sprintf("    data = csvRead(filename, ""%s"", ""%s"", ""%s"", [], [], [], 1);", delim, decimal, conversion);
+    else
+        str($+1) = sprintf("    data = csvRead(filename, ""%s"", ""%s"", ""%s"");", delim, decimal, conversion);
+    end
+    
+    str($+1) = "endfunction";
+    str($+1) = "";
+    
+    if importHeader then
+        str($+1) = sprintf("[header, data] = importdata(""%s"");", path);
+    else
+        str($+1) = sprintf("[data] = importdata(""%s"");", path);
+    end
+    
+    clipboard("copy", str);
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_gethead.sci b/scilab/modules/fileio/macros/importgui/importgui_gethead.sci
new file mode 100644 (file)
index 0000000..6f37966
--- /dev/null
@@ -0,0 +1,3 @@
+function head = importgui_gethead(f, n)
+    head = mgetl(f, n);
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_preview.sci b/scilab/modules/fileio/macros/importgui/importgui_preview.sci
new file mode 100644 (file)
index 0000000..651c6ec
--- /dev/null
@@ -0,0 +1,130 @@
+function importgui_preview()
+    global %importgui_cancel;
+    //get window information
+    delim = get("importgui_delim", "value")
+    if delim == 1 then
+        set("importgui_decimal", "value", 1);
+    end
+
+    set("importgui_btnvarialble", "enable", "off");
+    set("importgui_btnfunction", "enable", "off");
+    
+    hasHeader = get("importgui_header", "value");
+    delim = get("importgui_delim", "userdata")(delim);
+    decimal = get("importgui_decimal", "userdata")(get("importgui_decimal", "value"));
+    conversion = get("importgui_conversion", "userdata")(get("importgui_conversion", "value"));
+
+    path = get("importgui_filename", "string");
+    
+    if isempty(path) || ~isfile(path) then
+        return;
+    end
+    
+    c = get("importgui_preview");
+    c.visible = "off";
+    delete(c.children);
+
+    parent = c.parent;
+    fr = uicontrol(parent, ...
+        "style", "frame", ...
+        "layout", "gridbag", ...
+        "tag", "importgui_cancel", ...
+        "constraints", createConstraints("border", "center"));
+
+    uicontrol(fr, ...
+        "style", "pushbutton", ...
+        "string", _("Cancel preview"), ...
+        "callback_type", 10, ...
+        "callback", "global %importgui_cancel;%importgui_cancel=%t;", ...
+        "constraints", createConstraints("gridbag", [1 1 1 1], [1, 1]));
+
+    txt = mgetl(path, 20 + hasHeader);
+    if hasHeader then
+        header = txt(1);
+        txt(1) = [];
+        
+        //process header
+        try
+            header = csvTextScan(header, delim, decimal, "string");
+        catch
+            delete(fr);
+            c.visible = "on";
+            return;
+        end
+    end
+    
+    try
+        x = csvTextScan(txt, delim, decimal, conversion);
+    catch
+        delete(fr);
+        c.visible = "on";
+        return;
+    end
+    
+    if conversion == "double" then
+        //must convert double to string to display data
+        x = string(x);
+    end
+    
+    //frame data
+    limit = min(10, size(x, "c"));
+    show = get("importgui_showcol", "value");
+    if show then
+        limit = size(x, "c");
+    end
+
+    for i = 1:limit
+        if %importgui_cancel then
+            break;
+        end
+        
+        progress = i / limit;
+        constraints = createConstraints("gridbag", [i 1 1 1], [1, 0], "horizontal", "upper", [5, 5]);
+       
+        if hasHeader then
+            h = header(i);
+        else
+            h = sprintf("col%d", i);
+        end
+        
+        uicontrol(c, ...
+            "style", "text", ...
+            "string", h, ...
+            "horizontalalignment", "center", ...
+            "relief", "solid", ...
+            "constraints", constraints)
+        
+        for j = 1:size(x, "r")
+            constraints = createConstraints("gridbag", [i j+1 1 1], [1, 0], "horizontal", "upper", [7 7]);
+            
+            uicontrol(c, ...
+                "style", "text", ...
+                "horizontalalignment", "center", ...
+                "string", x(j,i), ...
+                "constraints", constraints);
+        end
+        
+        importgui_progress(progress);
+    end
+    
+    //to push lines to top
+    constraints = createConstraints("gridbag", [1 size(x, "r")+1 size(x, "c") 1], [1, 1], "both", "upper");
+    uicontrol(c, ...
+        "style", "frame", ...
+        "constraints", constraints);
+            
+    //delete cancel frame        
+    delete(fr);
+    
+    if %importgui_cancel then
+        //delete created children to keep interface clean
+        delete(c.children)
+    else
+        set("importgui_btnvarialble", "enable", "on");
+        set("importgui_btnfunction", "enable", "on");
+    end
+
+    clearglobal %importgui_cancel;
+    c.visible = "on";
+    importgui_progress(0);
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_progress.sci b/scilab/modules/fileio/macros/importgui/importgui_progress.sci
new file mode 100644 (file)
index 0000000..88ac58e
--- /dev/null
@@ -0,0 +1,5 @@
+function importgui_progress(val)
+    pos = get("importgui_progressbar", "position");
+    pos(3) = 800 * val;
+    set("importgui_progressbar", "position", pos);
+endfunction
diff --git a/scilab/modules/fileio/macros/importgui/importgui_variable.sci b/scilab/modules/fileio/macros/importgui/importgui_variable.sci
new file mode 100644 (file)
index 0000000..7c3cd3c
--- /dev/null
@@ -0,0 +1,43 @@
+function importgui_variable()
+    hasHeader = get("importgui_header", "value");
+    delim = get("importgui_delim", "userdata")(get("importgui_delim", "value"));
+    decimal = get("importgui_decimal", "userdata")(get("importgui_decimal", "value"));
+    conversion = get("importgui_conversion", "userdata")(get("importgui_conversion", "value"));
+
+    path = get("importgui_filename", "string");
+    if isempty(path) || ~isfile(path) then
+        return;
+    end
+
+    importHeader = %f;
+    
+    if hasHeader then
+        x = x_mdialog("Import Data", ["Variable name";"Import header";"Header name"], ["data";"%F";"header"]);
+        if isempty(x) then
+            return;
+        end
+
+        importHeader = evstr(x(2));
+        if importHeader then
+            header = mgetl(path, 1);
+            header = csvTextScan(header, delim, decimal, "string");
+            str = sprintf("[%s, %s] = resume(data, header);", x(1), x(3));
+        else
+            str = sprintf("[%s] = resume(data);", x(1));
+        end
+
+        dataName = x(1);
+        data = csvRead(path, delim, decimal, conversion, [], [], [], 1);
+    else
+        x = x_mdialog("Import Data", ["Variable name"], ["data"]);
+        if isempty(x) then
+            return;
+        end
+
+        str = sprintf("[%s] = resume(data);", x(1));
+        dataName = x(1);
+        data = csvRead(path, delim, decimal, conversion);
+    end
+
+    execstr(str);
+endfunction