#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 stmt 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 bttn.
        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 bttns.
        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 bttn.
        return PopUp1("OKAY", 1, header, footer) > 0;
}

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

public Bool PopUpCancelOk(U8 *header=NULL, U8 *footer=NULL)
{//Make PopUp win task CANCEL/OKAY bttns.
        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, "CC");
        I64  res = 0;

        if (warn_ext && !FilesFindMatch(name2, FILEMASK_JIT) && !PopUpCancelOk(ST_WARN_ST "Not .CC 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, "CC");
        I64  res = 0;

        if (warn_ext && !FilesFindMatch(name2, FILEMASK_JIT) && !PopUpCancelOk(ST_WARN_ST "Not .CC 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, "CC");
        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;
}