#help_index "DolDoc/Output;StdOut/DolDoc"
public CTask *PopUpViewDoc(CDoc *doc, I64 dof_flags=0)
{//Pass doc to PopUp win task for viewing.
    U8      *buf = MStrPrint("DocEd(0x%X,0x%X);", doc, dof_flags);
    CTask   *task = Spawn(&ServerCmdLine, NULL, "View",, Fs);

    TaskExe(task, NULL, buf, 1 << JOBf_EXIT_ON_COMPLETE | 1 << JOBf_FREE_ON_COMPLETE);
    Free(buf);

    return task;
}

public CTask *PopUpViewPrint(U8 *format, ...)
{//View Print statement in PopUp win task.
    CTask   *task = Spawn(&ServerCmdLine, NULL, "View",, Fs);
    U8      *buf = StrPrintJoin(NULL, format, argc, argv);
    CDoc    *doc = DocNew(, task);

    DocPrint(doc, buf);
    Free(buf);
    buf = MStrPrint("DocEd(0x%X);", doc);
    TaskExe(task, NULL, buf, 1 << JOBf_EXIT_ON_COMPLETE | 1 << JOBf_FREE_ON_COMPLETE);
    Free(buf);

    return task;
}

#help_index "DolDoc/Input;File/FileNames;StdIn/DolDoc"
public U8 *PopUpPickFile(U8 *dir=NULL)
{//Filename chooser.    Uses FileMgr().
    U8 *res, *st, *st2;

    if (dir)
        st = MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);", dir);
    else
    {
        st2 = DirCur;
        st = MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);", st2);
        Free(st2);
    }
    res = PopUp(st, Fs);
    Free(st);

    return res;
}

public U8 *PopUpPickDir(U8 *dir=NULL)
{//File dir name chooser.  Uses FileMgr().
    U8 *res, *st, *st2;

    if (dir)
        st = MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);", dir);
    else
    {
        st2 = DirCur;
        st = MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);", st2);
        Free(st2);
    }
    res = PopUp(st, Fs);
    Free(st);

    return res;
}

public U8 *FileNameForm(U8 *default=NULL, I64 dof_flags=0, CTask *mem_task=NULL)
{//Text filename form in cur win, not PopUp.
    CEdFileName fn;

    if (default)
        StrCopy(fn.name, default);
    else
        *fn.name = 0;
    if (DocForm(&fn,, dof_flags))
        return StrNew(fn.name, mem_task);
    else
        return NULL;
}

public U8 *PopUpFileName(U8 *default=NULL, I64 dof_flags=0)
{//Filename chooser. Uses form, not FileMgr().
    U8 *st = MStrPrint("FileNameForm(\"%Q\",0x%X,Fs->parent_task);", default, dof_flags | DOF_SIZE_MIN), *res = PopUp(st, Fs);

    Free(st);

    return res;
}

#help_index "DolDoc"
Bool PopUpCd()
{
    Bool res;
    U8  *st = PopUpPickDir;

    if (st)
    {
        res = Cd(st);
        Free(st);
    }
    else
        res = FALSE;

    return res;
}

#help_index "DolDoc/Input;Char/Lists;StdIn/DolDoc"
public I64 PopUpPickList(U8 *list)
{//Prompt for list entry in PopUp win task.
    I64   res, i = 0;
    CDoc *doc = DocNew;

    DocPrint(doc, "$LTBLUE$");
    while (*list)
    {
        if (*list == '@')
        {//Check for '@' alias list entry
            i--;
            list++;
        }
        DocPrint(doc, "$MU,\"%s\",LE=%d$\n", list, i++);
        list += StrLen(list) + 1;
    }
    DocPrint(doc, "\n$MU,\"CANCEL\",LE=DOCM_CANCEL$\n");
    res = PopUpMenu(doc);
    DocDel(doc);

    return res;
}

#help_index "DolDoc/Input;Char/Lists;Char/Define;StdIn/DolDoc"
public U8 *PopUpPickDefineSub(U8 *dname)
{//Prompt for Define list entry in PopUp win task.
    return PopUpPickList(Define(dname));
}

#help_index "DolDoc/Input;StdIn/DolDoc"
public I64 PopUp1(U8 *b1, I64 n1, U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task with one button.
    I64   i, l1 = StrLen(b1);
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s", header);
    DocPrint(doc, "$CM+CX,%d,4$$BT,\"%s\",LE=%d$\n", -l1 / 2, b1, n1);
    if (footer)
        DocPrint(doc, "%s", footer);
    i = PopUpMenu(doc);
    DocDel(doc);

    return i;
}

public I64 PopUp2(U8 *b1, I64 n1, U8 *b2, I64 n2, U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task with two buttons.
    I64   i, l1 = StrLen(b1), l2 = StrLen(b2), y;
    CDoc *doc = DocNew;

    if (header)
    {
        DocPrint(doc, "%s", header);
        y = 4;
    }
    else
    {
        DocPrint(doc, "%*s\n", l1 + l2 + 10, "");
        y = 3;
    }
    DocPrint(doc, "$CM+CX,%d,%d$$BT,\"%s\",LE=%d$", -(l1 + l2 + 3) >> 1, y, b1, n1);
    DocPrint(doc, "$CM+CX,%d,0$$BT,\"%s\",LE=%d$\n" , -(l1 + l2 + 3) >> 1 + l1 + 6, b2, n2);
    if (footer)
        DocPrint(doc, "%s", footer);
    i = PopUpMenu(doc);
    DocDel(doc);

    return i;
}

public Bool PopUpOk(U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task with OKAY button.
    return PopUp1("OKAY", 1, header, footer) > 0;
}

public Bool PopUpNoYes(U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task with NO/YES buttons.
    return PopUp2("YES", 1, "NO", 0, header, footer) > 0;
}

public Bool PopUpCancelOk(U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task CANCEL/OKAY buttons.
    return PopUp2("OKAY", 1, "CANCEL", 0, header, footer) > 0;
}

U8 *PopUpGetStr2(U8 *header, CTask *mem_task)
{
    U8 *res, *st;

    if (header)
        "%s", header;
    st = StrGet(,, SGF_WITH_NEW_LINE);
    res = StrNew(st, mem_task);
    Free(st);

    return res;
}

public U8 *PopUpGetStr(U8 *header=NULL)
{//Prompt for text str in PopUp win task.
    U8 *st = MStrPrint("PopUpGetStr2(0x%X,0x%X);", header, Fs), *res = PopUp(st, Fs);

    Free(st);

    return res;
}

public I64 PopUpI64Get(U8 *message, I64 default, I64 lo=I64_MIN, I64 hi=I64_MAX)
{//Prompt for I64 text expression in PopUp win task.
    U8 *st = MStrPrint("I64Get(0x%X,0x%X,0x%X,0x%X);", message, default, lo, hi);
    I64 res = PopUp(st, Fs);

    Free(st);

    return res;
}

public F64 PopUpGetF64(U8 *message, F64 default, F64 lo=F64_MIN, F64 hi=F64_MAX)
{//Prompt for F64 text expression in PopUp win task.
    U8 *st = MStrPrint("F64Get(0x%X,0x%X(F64),0x%X(F64),0x%X(F64));", message, default, lo, hi);
    F64 res = PopUp(st, Fs)(F64);

    Free(st);

    return res;
}

public I64 PopUpRangeI64(I64 lo, I64 hi, I64 step=1, 
                U8 *header=NULL, U8 *footer=NULL)
{//Evenly-spaced I64 range chooser in PopUp win task.
    I64   i;
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s", header);
    DocPrint(doc, "$LTBLUE$");
    for (i = lo; i <= hi; i += step)
        DocPrint(doc, "$MU,\"%d\",LE=%d$\n", i, i);
    if (footer)
        DocPrint(doc, "%s", footer);
    i = PopUpMenu(doc);
    DocDel(doc);

    return i;
}

public F64 PopUpRangeF64(F64 lo, F64 hi, F64 step, U8 *format="%9.4f", U8 *header=NULL, U8 *footer=NULL)
{//Evenly-spaced F64 range chooser in PopUp win task.
    F64   d;
    I64   i;
    U8    buf[STR_LEN];
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s", header);
    DocPrint(doc, "$LTBLUE$");
    for (d = lo; d <= hi; d += step)
    {
        StrPrint(buf, format, d);
        DocPrint(doc, "$MU,\"%s\",LE=0x%X$\n", buf, d);
    }
    if (footer)
        DocPrint(doc, "%s", footer);
    i = PopUpMenu(doc);
    DocDel(doc);

    return i(F64);
}

public F64 PopUpRangeF64Exp(F64 lo, F64 hi, F64 factor, U8 *format="%9.4f", U8 *header=NULL, U8 *footer=NULL)
{//Exp-spaced F64 range chooser in PopUp win task.
    F64   d;
    I64   i;
    U8    buf[STR_LEN];
    CDoc *doc = DocNew;

    if (header)
        DocPrint(doc, "%s", header);
    DocPrint(doc, "$LTBLUE$");
    for (d = lo; d <= hi; d *= factor)
    {
        StrPrint(buf, format, d);
        DocPrint(doc, "$MU,\"%s\",LE=0x%X$\n", buf, d);
    }
    if (footer)
        DocPrint(doc, "%s", footer);
    i = PopUpMenu(doc);
    DocDel(doc);

    return i(F64);
}

public F64 PopUpRangeF64Log(F64 lo, F64 hi, I64 steps, U8 *format="%9.4f", U8 *header=NULL, U8 *footer=NULL)
{//Log-spaced F64 range chooser in PopUp win task.
    return PopUpRangeF64Exp(lo, hi, Exp(Ln(hi / lo) / (steps - 1)), format, header, footer);
}

#help_index "Job/Exe;Task/Job/Exe;Compiler"
public I64 SysFile(U8 *filename, Bool warn_ext=TRUE)
{//Make sys_task execute file.
    Bool okay = TRUE;
    U8  *name = FileNameAbs(filename), *name2 = ExtDefault(name, "ZC");
    I64  res = 0;

    if (warn_ext && !FilesFindMatch(name2, FILEMASK_JIT) && !PopUpCancelOk(ST_WARN_ST "Not .ZC File\n\n"))
        okay = FALSE;
    if (okay)
        res = Sys("#include \"%s\";", name2);
    Free(name2);
    Free(name);

    return res;
}

public I64 PopUpFile(U8 *filename, Bool warn_ext=TRUE, CTask *parent=NULL, CTask **_pu_task=NULL)
{//ExeFile2() in PopUp task. Cont as User.
    Bool okay = TRUE;
    U8  *st, *name = FileNameAbs(filename), *name2 = ExtDefault(name, "ZC");
    I64  res = 0;

    if (warn_ext && !FilesFindMatch(name2, FILEMASK_JIT) && !PopUpCancelOk(ST_WARN_ST "Not .ZC File\n\n"))
        okay = FALSE;
    if (okay)
    {
        st = MStrPrint("\"$$WW+H,1$$\"; In(\"ExeFile2(\\\"%s\\\", CCF_CMD_LINE);\\n\"); UserTaskCont;", name2);
        res = PopUp(st, parent, _pu_task);
        Free(st);
    }
    Free(name2);
    Free(name);

    return res;
}

public I64 PopUpRunFile(U8 *filename, I64 ccf_flags=0, ...)
{//ExeFile() with args using LastFun() in PopUp task.
    U8 *st, *name = FileNameAbs(filename), *name2 = ExtDefault(name, "ZC");
    I64 res = 0;

    st = MStrPrint("\"$$WW+H,1$$\"; ExeFile2(\"%s\", 0x%X); LastFun(0x%X, 0x%X);", name2, ccf_flags, argc, argv);
    res = PopUp(st, Fs);
    Free(st);
    Free(name2);
    Free(name);

    return res;
}