iup-stack/iup/srclua5/scripter/iupluascripterdlg.c

1471 lines
47 KiB
C
Executable File
Raw Blame History

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef WIN32
#include <unistd.h> /* for chdir */
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "iup.h"
#include "iup_scintilla.h"
#include "iup_config.h"
#include "iuplua.h"
#include "il.h"
#include "iup_object.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_strmessage.h"
#include "iup_register.h"
#include "iup_childtree.h"
#include "iup_drvinfo.h"
#define BREAKPOINT_MARGIN "15"
#define FOLDING_MARGIN "20"
/* from _images.c */
void load_all_images_step_images(void);
/* from _debugger.c */
void iupLuaScripterDebuggerCreateTabs(Ihandle* panelTabs);
void iupLuaScripterDebuggerAddToolbarButtons(Ihandle *toolbar);
void iupLuaScripterDebuggerAddMenuItems(Ihandle *lua_menu);
void iupLuaScripterDebuggerAddHotKeys(Ihandle *ih);
/********************************** Utilities *****************************************/
static char* getLuaKeywords(void)
{
#ifdef OLD_LUA_LEXER
return "and break do else elseif end for function if in local load nil not or repeat return then until while "
"false true assert collectgarbage dofile error _G getmetatable ipairs loadfile next pairs "
"pcall print rawequal rawget rawset setmetatable tonumber tostring type _VERSION select "
"require xpcall "
"string string.byte string.char string.dump string.find string.format string.gsub string.len string.lower "
"string.rep string.sub string.upper string.gmatch string.match string.reverse "
"table table.concat table.insert table.remove table.sort "
"math math.abs math.acos math.asin math.atan math.ceil math.cos math.deg math.exp math.floor "
"math.log math.max math.min math.pi math.rad math.random math.randomseed math.fmod "
"math.sin math.sqrt math.tan math.huge math.modf "
"coroutine coroutine.create coroutine.resume coroutine.status coroutine.wrap coroutine.yield coroutine.running "
"io io.close io.flush io.input io.lines io.open io.output io.read io.tmpfile io.type io.write "
"io.stdin io.stdout io.stderr io.popen "
"os os.clock os.date os.difftime os.execute os.exit "
"os.getenv os.remove os.rename os.setlocale os.time os.tmpname "
"debug debug.getfenv debug.getmetatable debug.getregistry debug.setfenv debug.setmetatable debug.debug debug.gethook "
"debug.setlocal debug.setupvalue debug.sethook debug.traceback debug.getinfo debug.getlocal debug.getupvalue "
"package package.seeall package.cpath package.loaded "
"package.loadlib package.path package.preload "
#if LUA_VERSION_NUM == 501 /* Lua 5.1 Only */
"module setfenv getfenv math.log10 loadstring table.maxn unpack package.loaders "
"math.atan2 math.cosh math.sinh math.tanh math.pow math.frexp math.ldexp "
#elif LUA_VERSION_NUM == 502 /* Lua 5.2 Only */
"package.searchers goto rawlen table.pack table.unpack package.config debug.getuservalue debug.setuservalue debug.upvalueid debug.upvaluejoin _ENV "
"bit32 bit32.arshift bit32.band bit32.bnot bit32.bor bit32.btest bit32.bxor bit32.extract bit32.replace bit32.lrotate bit32.lshift bit32.rrotate bit32.rshift "
"package.searchpath "
"math.atan2 math.cosh math.sinh math.tanh math.pow math.frexp math.ldexp "
#elif LUA_VERSION_NUM == 503 /* Lua 5.3 Only */
"package.searchers goto rawlen table.pack table.unpack package.config debug.getuservalue debug.setuservalue debug.upvalueid debug.upvaluejoin _ENV "
"table.move string.pack string.unpack string.packsize "
"utf8 utf8.char utf8.charpattern utf8.codes utf8.codepoint utf8.len utf8.offset "
#endif
#else
return "and break do else elseif end for function if in local load nil not or repeat return then until while "
"false true assert collectgarbage dofile error _G getmetatable ipairs loadfile next pairs "
"pcall print rawequal rawget rawset setmetatable tonumber tostring type _VERSION select "
"require xpcall "
"string byte char dump find format gsub len lower "
"rep sub upper gmatch match reverse "
"table concat insert remove sort "
"math abs acos asin atan ceil cos deg exp floor "
"log max min pi rad random randomseed fmod "
"sin sqrt tan huge modf "
"coroutine create resume status wrap yield running "
"io close flush input lines open output read tmpfile type write "
"stdin stdout stderr popen "
"os clock date difftime execute exit "
"getenv remove rename setlocale time tmpname "
"debug getfenv getmetatable getregistry setfenv setmetatable debug gethook "
"setlocal setupvalue sethook traceback getinfo getlocal getupvalue "
"package seeall cpath loaded "
"loadlib path preload "
#if LUA_VERSION_NUM == 501 /* Lua 5.1 Only */
"module setfenv getfenv log10 loadstring maxn unpack loaders "
"atan2 cosh sinh tanh pow frexp ldexp "
#elif LUA_VERSION_NUM == 502 /* Lua 5.2 Only */
"searchers goto rawlen pack unpack config getuservalue setuservalue upvalueid upvaluejoin _ENV "
"bit32 arshift band bnot bor btest bxor extract replace lrotate lshift rrotate rshift "
"searchpath "
"atan2 cosh sinh tanh pow frexp ldexp "
#elif LUA_VERSION_NUM == 503 /* Lua 5.3 Only */
"searchers goto rawlen pack unpack config getuservalue setuservalue upvalueid upvaluejoin _ENV "
"move pack unpack packsize "
"utf8 char charpattern codes codepoint len offset "
#endif
#endif
;
}
static const char *getLastNonAlphaNumeric(const char *text)
{
int len = (int)strlen(text);
const char *c = text + len - 1;
if (*c == '\n')
c--;
for (; c != text; c--)
{
if (*c < 48 || (*c > 57 && *c < 65) || (*c > 90 && *c < 97) || *c > 122)
return c + 1;
}
return NULL;
}
static char *filterList(const char *text, const char *list)
{
char *filteredList[1024];
char *retList;
int count = 0;
int i, len;
const char *lastValue = list;
const char *nextValue = iupStrNextValue(list, (int)strlen(list), &len, ' ');
while (len != 0)
{
if ((int)strlen(text) <= len && iupStrEqualPartial(lastValue, text))
{
char *value = malloc(80);
strncpy(value, lastValue, len);
value[len] = 0;
filteredList[count++] = value;
}
lastValue = nextValue;
nextValue = iupStrNextValue(nextValue, (int)strlen(nextValue), &len, ' ');
}
retList = malloc(1024);
retList[0] = 0;
for (i = 0; i < count; i++)
{
if (i == 0)
{
strcpy(retList, filteredList[i]);
strcat(retList, " ");
}
else
{
strcat(retList, filteredList[i]);
strcat(retList, " ");
}
}
for (i = 0; i < count; i++)
free(filteredList[i]);
return retList;
}
static Ihandle* get_config(Ihandle* ih)
{
Ihandle* config = (Ihandle*)IupGetAttribute(IupGetDialog(ih), "CONFIG_HANDLE");
return config;
}
static void remove_breakpoint(Ihandle *listBreak, const char* m_filename, int m_line, lua_State* L)
{
int i, line;
char* filename;
i = 1;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
while (filename != NULL)
{
line = IupGetIntId(listBreak, "LINE", i);
if (line == m_line && iupStrEqual(filename, m_filename))
{
iuplua_push_name(L, "DebuggerRemoveBreakpoint");
iuplua_pushihandle(L, listBreak);
lua_pushinteger(L, i);
iuplua_call_raw(L, 2, 0);
return;
}
i++;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
}
}
static void add_breakpoint(Ihandle *listBreak, const char* filename, int line, lua_State* L)
{
iuplua_push_name(L, "DebuggerAddBreakpoint");
iuplua_pushihandle(L, listBreak);
lua_pushstring(L, filename);
lua_pushinteger(L, line);
iuplua_call_raw(L, 3, 0);
}
static void save_globals(Ihandle *ih, Ihandle* config)
{
Ihandle* treeGlobals = IupGetDialogChild(ih, "DEBUG_TREE_GLOBAL");
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
int i, count, id;
const char *value;
count = IupGetInt(treeGlobals, "ROOTCOUNT");
id = 0;
for (i = 0; i < count; i++)
{
iuplua_push_name(L, "DebuggerGetGlobalNameFromTree");
iuplua_pushihandle(L, treeGlobals);
lua_pushinteger(L, id);
iuplua_call_raw(L, 2, 1);
value = lua_tostring(L, -1);
IupConfigSetVariableStrId(config, "LuaScripterGlobals", "Name", i+1, value);
id = IupGetIntId(treeGlobals, "NEXT", id);
}
IupConfigSetVariableInt(config, "LuaScripterGlobals", "Count", count);
/* make sure some older globals are not saved in the configuration file (at least 10) */
for (i = count; i <= count + 10; i++)
IupConfigSetVariableStrId(config, "LuaScripterGlobals", "Name", i+1, NULL);
}
static void save_breakpoints(Ihandle *ih, Ihandle* config)
{
Ihandle* listBreak = IupGetDialogChild(ih, "DEBUG_LIST_BREAK");
int i, line, count;
char *filename;
char data[10240];
i = 1;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
while (filename != NULL)
{
line = IupGetIntId(listBreak, "LINE", i);
sprintf(data, "%s#%d", filename, line);
IupConfigSetVariableStrId(config, "LuaScripterBreakpoints", "FileLine", i, data);
i++;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
}
count = i - 1;
IupConfigSetVariableInt(config, "LuaScripterBreakpoints", "Count", count);
/* make sure some older breakpoints are not saved in the configuration file (at least 10) */
for (i = count+1; i <= count+1 + 10; i++)
IupConfigSetVariableStrId(config, "LuaScripterBreakpoints", "FileLine", i, NULL);
}
static void load_globals(Ihandle *ih, Ihandle* config)
{
Ihandle* treeGlobals = IupGetDialogChild(ih, "DEBUG_TREE_GLOBAL");
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
int i;
const char* value;
/* this will work only if the tree is already mapped */
IupSetAttribute(treeGlobals, "DELNODE", "ALL");
i = 1;
do
{
value = IupConfigGetVariableStrId(config, "LuaScripterGlobals", "Name", i);
if (value)
{
iuplua_push_name(L, "DebuggerAddGlobal");
iuplua_pushihandle(L, treeGlobals);
lua_pushstring(L, value);
iuplua_call_raw(L, 2, 0);
}
i++;
} while (value != NULL);
iuplua_push_name(L, "DebuggerInitGlobalsTree");
iuplua_pushihandle(L, treeGlobals);
iuplua_call_raw(L, 1, 0);
}
static void load_breakpoints(Ihandle *ih, Ihandle* config)
{
Ihandle* listBreak = IupGetDialogChild(ih, "DEBUG_LIST_BREAK");
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
int i, line;
const char* value;
char filename[10240], line_str[30];
i = 1;
do
{
value = IupConfigGetVariableStrId(config, "LuaScripterBreakpoints", "FileLine", i);
if (value)
{
iupStrToStrStr(value, filename, line_str, '#');
iupStrToInt(line_str, &line);
IupSetStrAttributeId(listBreak, "FILENAME", i, filename);
IupSetIntId(listBreak, "LINE", i, line);
i++;
}
} while (value != NULL);
IupSetStrAttributeId(listBreak, "FILENAME", i, NULL);
IupSetStrAttributeId(listBreak, "LINE", i, NULL);
iuplua_push_name(L, "DebuggerInitBreakpointsList");
iuplua_pushihandle(L, listBreak);
iuplua_call_raw(L, 1, 0);
}
static char* changeTabsForSpaces(const char *text, int tabsize)
{
static char newText[1024];
int len = (int)strlen(text);
int i, j, charcount = 0;
for (i = 0; i < len; i++)
{
char c = text[i];
if (c == '\t')
{
int nWhites = tabsize - (charcount % tabsize);
for (j = 0; j < nWhites; j++)
{
newText[charcount] = ' ';
charcount++;
}
continue;
}
newText[charcount] = c;
charcount++;
}
newText[charcount] = '\0';
return newText;
}
static Ihandle* get_current_multitext(Ihandle* ih)
{
Ihandle* tabs = IupGetDialogChild(ih, "MULTITEXT_TABS");
return (Ihandle*)IupGetAttribute(tabs, "VALUE_HANDLE");
}
/********************************** Callbacks *****************************************/
static int exit_cb(Ihandle *ih)
{
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
char* exit_loop = IupGetGlobal("EXITLOOP");
if (exit_loop && !iupStrBoolean(exit_loop))
{
/* assume we are inside the iupluascripter application */
IupSetGlobal("EXITLOOP", NULL);
IupExitLoop();
}
iuplua_push_name(L, "DebuggerExit");
iuplua_call_raw(L, 0, 0); /* this may trigger a Lua error which will abort the function with a goto, must sure you do nothing after that */
return IUP_DEFAULT;
}
static int restoremarkers_cb(Ihandle *ih, Ihandle *multitext)
{
int i, line;
char *filename;
/* called when a new multitext is created/loaded */
char* m_filename = IupGetAttribute(multitext, "FILENAME");
Ihandle* listBreak = IupGetDialogChild(ih, "DEBUG_LIST_BREAK");
IupSetInt(multitext, "MARKERDELETEALL", 1);
if (!m_filename)
return IUP_DEFAULT;
i = 1;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
while (filename != NULL)
{
if (iupStrEqual(filename, m_filename))
{
line = IupGetIntId(listBreak, "LINE", i);
IupSetIntId(multitext, "MARKERADD", line - 1, 1);
}
i++;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
}
return IUP_DEFAULT;
}
static int marker_changed_cb(Ihandle *ih, Ihandle *multitext, int lin, int margin)
{
if (margin == 2)
{
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
unsigned int markerMask = (unsigned int)IupGetIntId(multitext, "MARKERGET", lin);
int has_breakpoint = markerMask & 0x0002; /* 0010 - marker=1 */
Ihandle* listBreak = IupGetDialogChild(ih, "DEBUG_LIST_BREAK");
char* filename = IupGetAttribute(multitext, "FILENAME");
if (!filename)
{
IupMessageError(IupGetDialog(ih), "Must have a filename to add a breakpoint.");
return IUP_DEFAULT;
}
if (has_breakpoint)
remove_breakpoint(listBreak, filename, lin + 1, L);
else
add_breakpoint(listBreak, filename, lin + 1, L);
}
else if (margin == 3)
IupSetfAttribute(multitext, "FOLDTOGGLE", "%d", lin);
(void)ih;
return IUP_DEFAULT;
}
static int configsave_cb(Ihandle *ih, Ihandle* config)
{
save_breakpoints(ih, config);
save_globals(ih, config);
return IUP_DEFAULT;
}
static int configload_cb(Ihandle *ih, Ihandle* config)
{
const char* value;
value = IupConfigGetVariableStr(config, "LuaScripter", "CurrentDirectory");
if (value)
IupSetStrAttribute(ih, "CURRENTDIRECTORY", value);
value = IupConfigGetVariableStr(config, "LuaScripter", "Arguments");
if (value)
IupSetStrAttribute(ih, "ARGUMENTS", value);
value = IupConfigGetVariableStr(config, "LuaScripter", "AutoCompletion");
if (value)
{
Ihandle* ih_item = IupGetDialogChild(ih, "ITM_AUTOCOMPLETE");
IupSetStrAttribute(ih_item, "VALUE", value);
}
value = IupConfigGetVariableStr(config, "LuaScripter", "Folding");
if (value)
{
Ihandle* ih_item = IupGetDialogChild(ih, "ITM_FOLDING");
IupSetStrAttribute(ih_item, "VALUE", value);
}
load_breakpoints(ih, config);
if (ih->handle)
load_globals(ih, config);
return IUP_DEFAULT;
}
static int newfilename_cb(Ihandle *ih, char* old_filename, char* new_filename)
{
Ihandle* listBreak = IupGetDialogChild(ih, "DEBUG_LIST_BREAK");
int i, changed = 0;
char* filename;
i = 1;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
while (filename != NULL)
{
if (iupStrEqual(filename, old_filename))
{
IupSetStrAttributeId(listBreak, "FILENAME", i, new_filename);
changed = 1;
}
i++;
filename = IupGetAttributeId(listBreak, "FILENAME", i);
}
if (changed)
{
lua_State* L = (lua_State*)IupGetAttribute(ih, "LUASTATE");
iuplua_push_name(L, "DebuggerInitBreakpointsList");
iuplua_pushihandle(L, listBreak);
iuplua_call_raw(L, 1, 0);
}
return IUP_DEFAULT;
}
static int multitext_dwell_cb(Ihandle* multitext, int code, int pos, int x, int y)
{
if (!IupGetInt(IupGetDialogChild(multitext, "DEBUG_ITM_DEBUG"), "ACTIVE")) /* can be called by the hot key in the dialog */
return IUP_DEFAULT;
if (code)
{
int start, end, lin, start_col, end_col;
const char *value;
char *text;
char word[1024];
int tabSize = IupGetInt(multitext, "TABSIZE");
lua_State* L = (lua_State*)IupGetAttribute(multitext, "LUASTATE");
char* wordpos = IupGetAttributeId(multitext, "WORDPOS", pos);
if (wordpos == NULL)
return IUP_DEFAULT;
sscanf(wordpos, "%d:%d", &start, &end);
IupTextConvertPosToLinCol(multitext, start, &lin, &start_col);
IupTextConvertPosToLinCol(multitext, end, &lin, &end_col);
text = IupGetAttributeId(multitext, "LINE", lin);
text = changeTabsForSpaces(text, tabSize);
text[end_col] = '\0';
strcpy(word, text+start_col);
iuplua_push_name(L, "DebuggerShowTip");
lua_pushstring(L, word);
lua_pushinteger(L, lin+1);
iuplua_call_raw(L, 2, 1);
value = lua_tostring(L, -1);
if (value==NULL)
return IUP_DEFAULT;
IupSetStrf(multitext, "TIP", "%s = %s" , word, value);
IupSetAttribute(multitext, "TIPVISIBLE", "Yes");
}
else
{
IupSetAttribute(multitext, "TIPVISIBLE", "No");
IupSetAttribute(multitext, "TIP", NULL);
}
(void)x;
(void)y;
return IUP_DEFAULT;
}
static int multitext_kesc_cb(Ihandle *multitext)
{
if (!IupGetInt(multitext, "AUTOCOMPLETION"))
return IUP_CONTINUE;
if (IupGetInt(multitext, "AUTOCACTIVE"))
IupSetAttribute(multitext, "AUTOCCANCEL", "YES");
return IUP_CONTINUE;
}
static int multitext_lineschanged_cb(Ihandle* multitext, int start, int len)
{
lua_State* L = (lua_State*)IupGetAttribute(multitext, "LUASTATE");
iuplua_push_name(L, "DebuggerBreakpointsChanged");
iuplua_pushihandle(L, multitext);
lua_pushinteger(L, start + 1);
lua_pushinteger(L, len);
iuplua_call_raw(L, 3, 0);
return IUP_DEFAULT;
}
static int multitext_valuechanged_cb(Ihandle* multitext)
{
if (IupGetInt(multitext, "AUTOCOMPLETION"))
{
const char *t;
char *text = IupGetAttribute(multitext, "LINEVALUE");
int col = IupGetInt2(multitext, "CARET");
text[col + 1] = '\0';
t = getLastNonAlphaNumeric(text);
if (t != NULL && *t != '\n' && *t != 0)
{
char *fList = filterList(t, getLuaKeywords());
if (strlen(fList) > 0)
IupSetAttributeId(multitext, "AUTOCSHOW", (int)strlen(t) - 1, fList);
free(fList);
}
return IUP_DEFAULT;
}
return IUP_CONTINUE;
}
static int item_autocomplete_action_cb(Ihandle* ih_item)
{
Ihandle* tabs = IupGetDialogChild(ih_item, "MULTITEXT_TABS");
Ihandle* multitext;
Ihandle* config = get_config(ih_item);
if (IupGetInt(ih_item, "VALUE"))
{
IupSetAttribute(ih_item, "VALUE", "OFF");
for (multitext = tabs->firstchild; multitext; multitext = multitext->brother)
IupSetAttribute(multitext, "AUTOCOMPLETION", "OFF");
}
else
{
IupSetAttribute(ih_item, "VALUE", "ON");
for (multitext = tabs->firstchild; multitext; multitext = multitext->brother)
IupSetAttribute(multitext, "AUTOCOMPLETION", "ON");
}
IupConfigSetVariableStr(config, "LuaScripter", "AutoCompletion", IupGetAttribute(ih_item, "VALUE"));
return IUP_DEFAULT;
}
static int setparent_param_cb(Ihandle* param_dialog, int param_index, void* user_data)
{
if (param_index == IUP_GETPARAM_MAP)
{
Ihandle* ih = (Ihandle*)user_data;
IupSetAttributeHandle(param_dialog, "PARENTDIALOG", ih);
}
return 1;
}
static int item_style_config_action_cb(Ihandle* ih_item)
{
Ihandle* tabs = IupGetDialogChild(ih_item, "MULTITEXT_TABS");
Ihandle* multitext;
Ihandle* config = get_config(ih_item);
char commentColor[30], commentLineColor[30], numberColor[30], keywordColor[30],
stringColor[30], characterColor[30], operatorColor[30];
strcpy(commentColor, IupConfigGetVariableStr(config, "LuaScripter", "CommentColor"));
strcpy(commentLineColor, IupConfigGetVariableStr(config, "LuaScripter", "CommentLineColor"));
strcpy(numberColor, IupConfigGetVariableStr(config, "LuaScripter", "NumberColor"));
strcpy(keywordColor, IupConfigGetVariableStr(config, "LuaScripter", "KeywordColor"));
strcpy(stringColor, IupConfigGetVariableStr(config, "LuaScripter", "StringColor"));
strcpy(characterColor, IupConfigGetVariableStr(config, "LuaScripter", "CharacterColor"));
strcpy(operatorColor, IupConfigGetVariableStr(config, "LuaScripter", "OperatorColor"));
if (!IupGetParam("Syntax Colors", setparent_param_cb, IupGetDialog(ih_item),
"Comment: %c\n"
"Comment Line: %c\n"
"Number: %c\n"
"Keyword: %c\n"
"String: %c\n"
"Character: %c\n"
"Operator: %c\n",
commentColor, commentLineColor, numberColor, keywordColor, stringColor, characterColor, operatorColor, NULL))
return IUP_DEFAULT;
IupConfigSetVariableStr(config, "LuaScripter", "CommentColor", commentColor);
IupConfigSetVariableStr(config, "LuaScripter", "CommentLineColor", commentLineColor);
IupConfigSetVariableStr(config, "LuaScripter", "NumberColor", numberColor);
IupConfigSetVariableStr(config, "LuaScripter", "KeywordColor", keywordColor);
IupConfigSetVariableStr(config, "LuaScripter", "StringColor", stringColor);
IupConfigSetVariableStr(config, "LuaScripter", "CharacterColor", characterColor);
IupConfigSetVariableStr(config, "LuaScripter", "OperatorColor", operatorColor);
for (multitext = tabs->firstchild; multitext; multitext = multitext->brother)
{
IupSetStrAttribute(multitext, "STYLEFGCOLOR1", commentColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR2", commentLineColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR4", numberColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR5", keywordColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR6", stringColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR7", characterColor);
IupSetStrAttribute(multitext, "STYLEFGCOLOR10", operatorColor);
}
return IUP_DEFAULT;
}
static int item_folding_action_cb(Ihandle* ih)
{
Ihandle* tabs = IupGetDialogChild(ih, "MULTITEXT_TABS");
Ihandle* multitext;
Ihandle* config = get_config(ih);
if (IupGetInt(ih, "VALUE"))
{
IupSetAttribute(ih, "VALUE", "OFF");
for (multitext = tabs->firstchild; multitext; multitext = multitext->brother)
{
IupSetAttribute(multitext, "PROPERTY", "fold=0");
IupSetAttribute(multitext, "MARGINWIDTH3", "0");
IupSetAttribute(multitext, "_IUP_FOLDDING", NULL);
}
}
else
{
IupSetAttribute(ih, "VALUE", "ON");
for (multitext = tabs->firstchild; multitext; multitext = multitext->brother)
{
IupSetAttribute(multitext, "PROPERTY", "fold=1");
IupSetAttribute(multitext, "MARGINWIDTH3", FOLDING_MARGIN);
IupSetAttribute(multitext, "_IUP_FOLDDING", "1");
IupSetAttribute(multitext, "FOLDALL", "EXPAND");
}
}
IupConfigSetVariableStr(config, "LuaScripter", "Folding", IupGetAttribute(ih, "VALUE"));
return IUP_DEFAULT;
}
static int item_toggle_folding_action_cb(Ihandle* ih)
{
Ihandle* multitext = get_current_multitext(ih);
int pos = IupGetInt(multitext, "CARETPOS");
int lin, col;
/* must test again because it can be called by the hot key */
if (!IupGetInt(multitext, "_IUP_FOLDDING"))
return IUP_DEFAULT;
IupTextConvertPosToLinCol(multitext, pos, &lin, &col);
if (!IupGetIntId(multitext, "FOLDLEVELHEADER", lin))
{
lin = IupGetIntId(multitext, "FOLDPARENT", lin);
if (lin < 0)
return IUP_DEFAULT;
}
IupSetfAttribute(multitext, "FOLDTOGGLE", "%d", lin);
IupSetfAttribute(multitext, "CARET", "%d:0", lin);
return IUP_DEFAULT;
}
static int item_fold_collapse_action_cb(Ihandle* ih)
{
Ihandle* multitext = get_current_multitext(ih);
IupSetAttribute(multitext, "FOLDALL", "CONTRACT");
return IUP_DEFAULT;
}
static int item_fold_expand_action_cb(Ihandle* ih)
{
Ihandle* multitext = get_current_multitext(ih);
IupSetAttribute(multitext, "FOLDALL", "EXPAND");
return IUP_DEFAULT;
}
static int item_fold_toggle_action_cb(Ihandle* ih)
{
Ihandle* multitext = get_current_multitext(ih);
IupSetAttribute(multitext, "FOLDALL", "TOGGLE");
return IUP_DEFAULT;
}
static int item_fold_level_action_cb(Ihandle* ih_item)
{
int level=0, action=0;
Ihandle* config = get_config(ih_item);
const char* value = IupConfigGetVariableStr(config, "LuaScripter", "FoldAllLevel");
if (value) iupStrToInt(value, &level);
value = IupConfigGetVariableStr(config, "LuaScripter", "FoldAllLevelAction");
if (value) iupStrToInt(value, &action);
if (IupGetParam("Fold All by Level", setparent_param_cb, IupGetDialog(ih_item),
"Level: %i\n"
"Options: %o|Collapse|Expand|Toggle|\n",
&level, &action, NULL))
{
Ihandle* multitext = get_current_multitext(ih_item);
int lin, count = IupGetInt(multitext, "LINECOUNT");
IupConfigSetVariableInt(config, "LuaScripter", "FoldAllLevel", level);
IupConfigSetVariableInt(config, "LuaScripter", "FoldAllLevelAction", action);
for (lin = 0; lin < count; lin++)
{
if (IupGetIntId(multitext, "FOLDLEVELHEADER", lin))
{
int foldLevel = IupGetIntId(multitext, "FOLDLEVEL", lin);
if (foldLevel + 1 == level) /* level at header is different from child */
{
switch (action)
{
case 0: /* Collapse */
if (IupGetIntId(multitext, "FOLDEXPANDED", lin))
IupSetfAttribute(multitext, "FOLDTOGGLE", "%d", lin);
break;
case 1: /* Expand */
if (!IupGetIntId(multitext, "FOLDEXPANDED", lin))
IupSetfAttribute(multitext, "FOLDTOGGLE", "%d", lin);
break;
case 2: /* Toggle */
IupSetfAttribute(multitext, "FOLDTOGGLE", "%d", lin);
break;
}
}
}
}
}
return IUP_DEFAULT;
}
static int item_blockcomment_action_cb(Ihandle* ih_item)
{
Ihandle* multitext = get_current_multitext(ih_item);
char *selpos = IupGetAttribute(multitext, "SELECTIONPOS");
int pos1 = 0, pos2 = 0;
if (!selpos)
return IUP_DEFAULT;
sscanf(selpos, "%d:%d", &pos1, &pos2);
IupSetAttribute(multitext, "UNDOACTION", "BEGIN");
IupSetAttributeId(multitext, "INSERT", pos1, "--[[");
IupSetAttributeId(multitext, "INSERT", pos2+4, "]]");
IupSetAttribute(multitext, "UNDOACTION", "END");
IupSetStrf(multitext, "SELECTIONPOS", "%d:%d", pos1, pos2 + 4 + 2);
return IUP_DEFAULT;
}
static int item_blockuncomment_action_cb(Ihandle* ih_item)
{
Ihandle* multitext = get_current_multitext(ih_item);
char *sel = IupGetAttribute(multitext, "SELECTION");
char *text_line;
int lin1, lin2, col1, col2, pos1, pos2;
if (!sel)
return IUP_DEFAULT;
sscanf(sel, "%d,%d:%d,%d", &lin1, &col1, &lin2, &col2);
text_line = IupGetAttributeId(multitext, "LINE", lin1);
if (text_line[col1] != '-' || text_line[col1 + 1] != '-' || text_line[col1 + 2] != '[' || text_line[col1 + 3] != '[')
return IUP_DEFAULT;
text_line = IupGetAttributeId(multitext, "LINE", lin2);
if (text_line[col2 - 1] != ']' || text_line[col2 - 2] != ']')
return IUP_DEFAULT;
IupTextConvertLinColToPos(multitext, lin1, col1, &pos1);
IupTextConvertLinColToPos(multitext, lin2, col2, &pos2);
IupSetAttribute(multitext, "UNDOACTION", "BEGIN");
IupSetStrf(multitext, "DELETERANGE", "%d,%d", pos1, 4);
IupSetStrf(multitext, "DELETERANGE", "%d,%d", pos2 - 4 - 2, 2);
IupSetAttribute(multitext, "UNDOACTION", "END");
IupSetStrf(multitext, "SELECTIONPOS", "%d:%d", pos1, pos2 - 4 - 2);
return IUP_DEFAULT;
}
static int item_linescomment_action_cb(Ihandle* ih_item)
{
Ihandle* multitext = get_current_multitext(ih_item);
char *sel = IupGetAttribute(multitext, "SELECTION");
char *text_line;
int lin, col, lin1, lin2, col1, col2;
if (!sel)
return IUP_DEFAULT;
sscanf(sel, "%d,%d:%d,%d", &lin1, &col1, &lin2, &col2);
IupSetAttribute(multitext, "UNDOACTION", "BEGIN");
for (lin = lin1; lin <= lin2; lin++)
{
int len, pos;
text_line = IupGetAttributeId(multitext, "LINE", lin);
len = (int)strlen(text_line);
for (col = 0; col < len; col++)
{
char c = text_line[col];
if (c != ' ' && c != '\t')
break;
}
IupTextConvertLinColToPos(multitext, lin, col, &pos);
IupSetAttributeId(multitext, "INSERT", pos, "-- ");
}
IupSetAttribute(multitext, "UNDOACTION", "END");
IupSetStrf(multitext, "SELECTION", "%d,0:%d,999", lin1, lin2);
return IUP_DEFAULT;
}
static int item_linesuncomment_action_cb(Ihandle* ih_item)
{
Ihandle* multitext = get_current_multitext(ih_item);
char *sel = IupGetAttribute(multitext, "SELECTION");
char *text_line;
int lin, col, lin1, lin2, col1, col2;
if (!sel)
return IUP_DEFAULT;
sscanf(sel, "%d,%d:%d,%d", &lin1, &col1, &lin2, &col2);
IupSetAttribute(multitext, "UNDOACTION", "BEGIN");
for (lin = lin1; lin <= lin2; lin++)
{
int len, pos, nChar;
text_line = IupGetAttributeId(multitext, "LINE", lin);
len = (int)strlen(text_line);
nChar = 0;
for (col = 0; col < len; col++)
{
if (text_line[col] == '-' && text_line[col+1] == '-')
{
nChar = 2;
if (text_line[col+2] == ' ')
nChar++;
break;
}
}
if (nChar == 0)
continue;
IupTextConvertLinColToPos(multitext, lin, col, &pos);
IupSetStrf(multitext, "DELETERANGE", "%d,%d", pos, nChar);
}
IupSetAttribute(multitext, "UNDOACTION", "END");
IupSetStrf(multitext, "SELECTION", "%d,0:%d,999", lin1, lin2);
return IUP_DEFAULT;
}
static int item_options_action_cb(Ihandle* ih_item)
{
Ihandle* ih = IupGetDialog(ih_item);
char dir[10240] = "";
char args[10240] = "";
char* value = IupGetAttribute(ih, "CURRENTDIRECTORY");
if (value)
strcpy(dir, value);
value = IupGetAttribute(ih, "ARGUMENTS");
if (value)
strcpy(args, value);
if (IupGetParam("Options", setparent_param_cb, ih,
"Current Directory: %f[dir||||]\n"
"Arguments: %s{Sets the table \"arg\".}\n",
dir, args, NULL))
{
Ihandle* config = get_config(ih);
IupSetStrAttribute(ih, "CURRENTDIRECTORY", dir);
IupSetStrAttribute(ih, "ARGUMENTS", args);
IupConfigSetVariableStr(config, "LuaScripter", "CurrentDirectory", dir);
IupConfigSetVariableStr(config, "LuaScripter", "Arguments", args);
}
return IUP_DEFAULT;
}
static int lua_menu_open_cb(Ihandle *ih_menu)
{
Ihandle* menu_foldall = IupGetDialogChild(ih_menu, "ITM_FOLD_ALL");
Ihandle* item_toggle_folding = IupGetDialogChild(ih_menu, "ITM_TOGGLE_FOLDING");
Ihandle* item_folding = IupGetDialogChild(ih_menu, "ITM_FOLDING");
Ihandle* item_comments = IupGetDialogChild(ih_menu, "ITM_COMMENTS");
Ihandle* multitext = get_current_multitext(ih_menu);
char *selpos = IupGetAttribute(multitext, "SELECTIONPOS");
if (IupGetInt(item_folding, "VALUE"))
{
IupSetAttribute(item_toggle_folding, "ACTIVE", "Yes");
IupSetAttribute(menu_foldall, "ACTIVE", "Yes");
}
else
{
IupSetAttribute(item_toggle_folding, "ACTIVE", "NO");
IupSetAttribute(menu_foldall, "ACTIVE", "NO");
}
if (selpos)
IupSetAttribute(item_comments, "ACTIVE", "Yes");
else
IupSetAttribute(item_comments, "ACTIVE", "NO");
return IUP_DEFAULT;
}
static int multitext_map_cb(Ihandle* multitext)
{
Ihandle* config = get_config(multitext);
const char *value;
IupSetAttribute(multitext, "LEXERLANGUAGE", "lua");
IupSetAttribute(multitext, "KEYWORDS0", getLuaKeywords());
IupSetAttribute(multitext, "STYLEFGCOLOR1", "0 128 0"); /* 1-Lua comment<6E>*/
IupSetAttribute(multitext, "STYLEFGCOLOR2", "0 128 0"); /* 2-Lua comment line<6E><65>*/
IupSetAttribute(multitext, "STYLEFGCOLOR4", "255 128 0"); /* 4-Number<65><72>*/
IupSetAttribute(multitext, "STYLEFGCOLOR5", "0 0 255"); /* 5-Keyword<72><64>*/
IupSetAttribute(multitext, "STYLEFGCOLOR6", "164 0 164"); /* 6-String<6E><67>*/
IupSetAttribute(multitext, "STYLEFGCOLOR7", "164 0 164"); /* 7-Character<65><72>*/
IupSetAttribute(multitext, "STYLEFGCOLOR10", "164 0 0"); /* 10-Operator<6F><72>*/
/* 3, 8 and 9 - are not used */
IupSetAttribute(multitext, "STYLEBOLD10", "YES");
IupSetAttribute(multitext, "MARKERHIGHLIGHT", "YES");
IupSetAttributeId(multitext, "MARKERBGCOLOR", 25, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDEREND */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 25, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDEREND */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 26, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDEROPENMID */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 26, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDEROPENMID */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 27, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDERMIDTAIL */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 27, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDERMIDTAIL */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 28, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDERTAIL */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 28, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDERTAIL */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 29, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDERSUB */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 29, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDERSUB */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 30, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDER */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 30, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDER */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 31, "0 0 0"); /* BGCOLOR para SC_MARKNUM_FOLDEROPEN */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 31, "255 255 255"); /* FGCOLOR para SC_MARKNUM_FOLDEROPEN */
IupSetAttribute(multitext, "PROPERTY", "fold=1");
IupSetAttribute(multitext, "PROPERTY", "fold.compact=0"); /* avoid folding of blank lines */
IupSetAttribute(multitext, "_IUP_FOLDDING", "1");
/* Folding margin=3 */
IupSetAttribute(multitext, "MARGINWIDTH3", FOLDING_MARGIN);
IupSetAttribute(multitext, "MARGINMASKFOLDERS3", "Yes");
IupSetAttribute(multitext, "MARGINSENSITIVE3", "YES");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDER=BOXPLUS");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDEROPEN=BOXMINUS");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDEREND=BOXPLUSCONNECTED");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDERMIDTAIL=TCORNER");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDEROPENMID=BOXMINUSCONNECTED");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDERSUB=VLINE");
IupSetAttribute(multitext, "MARKERDEFINE", "FOLDERTAIL=LCORNER");
IupSetAttribute(multitext, "FOLDFLAGS", "LINEAFTER_CONTRACTED");
value = IupConfigGetVariableStr(config, "LuaScripter", "CommentColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR1", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "CommentColor", IupGetAttribute(multitext, "STYLEFGCOLOR1"));
value = IupConfigGetVariableStr(config, "LuaScripter", "CommentLineColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR2", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "CommentLineColor", IupGetAttribute(multitext, "STYLEFGCOLOR2"));
value = IupConfigGetVariableStr(config, "LuaScripter", "NumberColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR4", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "NumberColor", IupGetAttribute(multitext, "STYLEFGCOLOR4"));
value = IupConfigGetVariableStr(config, "LuaScripter", "KeywordColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR5", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "KeywordColor", IupGetAttribute(multitext, "STYLEFGCOLOR5"));
value = IupConfigGetVariableStr(config, "LuaScripter", "StringColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR6", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "StringColor", IupGetAttribute(multitext, "STYLEFGCOLOR6"));
value = IupConfigGetVariableStr(config, "LuaScripter", "CharacterColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR7", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "CharacterColor", IupGetAttribute(multitext, "STYLEFGCOLOR7"));
value = IupConfigGetVariableStr(config, "LuaScripter", "OperatorColor");
if (value)
IupSetStrAttribute(multitext, "STYLEFGCOLOR10", value);
else
IupConfigSetVariableStr(config, "LuaScripter", "OperatorColor", IupGetAttribute(multitext, "STYLEFGCOLOR10"));
value = IupConfigGetVariableStr(config, "LuaScripter", "AutoCompletion");
if (value)
IupSetStrAttribute(multitext, "AUTOCOMPLETION", value);
value = IupConfigGetVariableStr(config, "LuaScripter", "Folding");
if (iupStrBoolean(value))
{
IupSetAttribute(multitext, "MARGINWIDTH3", FOLDING_MARGIN);
IupSetAttribute(multitext, "PROPERTY", "fold=1");
IupSetAttribute(multitext, "_IUP_FOLDDING", "1");
IupSetAttribute(multitext, "FOLDALL", "EXPAND");
}
else
{
IupSetAttribute(multitext, "MARGINWIDTH3", "0");
IupSetAttribute(multitext, "PROPERTY", "fold=0");
IupSetAttribute(multitext, "_IUP_FOLDDING", NULL);
}
return IUP_DEFAULT;
}
static int newtext_cb(Ihandle* ih, Ihandle *multitext)
{
(void)ih;
/* this is called before the multitext is mapped */
IupSetCallback(multitext, "VALUECHANGED_CB", (Icallback)multitext_valuechanged_cb);
IupSetCallback(multitext, "LINESCHANGED_CB", (Icallback)multitext_lineschanged_cb);
IupSetCallback(multitext, "K_ESC", (Icallback)multitext_kesc_cb);
IupSetCallback(multitext, "MAP_CB", (Icallback)multitext_map_cb);
IupSetCallback(multitext, "DWELL_CB", (Icallback)multitext_dwell_cb);
IupSetAttribute(multitext, "AUTOCOMPLETION", "OFF");
/* breakpoints margin=2 */
IupSetAttribute(multitext, "MARGINWIDTH2", BREAKPOINT_MARGIN);
IupSetAttribute(multitext, "MARGINTYPE2", "SYMBOL");
IupSetAttribute(multitext, "MARGINSENSITIVE2", "YES");
IupSetAttribute(multitext, "MARGINMASKFOLDERS2", "NO"); /* (disable folding) */
IupSetAttributeId(multitext, "MARGINMASK", 2, "14"); /* 1110 - marker=1 and marker=2 ad marker=3 */
/* breakpoints marker=1 */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 1, "255 0 0");
IupSetAttributeId(multitext, "MARKERBGCOLOR", 1, "255 0 0");
IupSetAttributeId(multitext, "MARKERSYMBOL", 1, "CIRCLE");
/* current line marker=2 (not shown in a margin, but uses margin=2 mask) */
IupSetAttributeId(multitext, "MARKERBGCOLOR", 2, "0 255 0");
IupSetAttributeId(multitext, "MARKERALPHA", 2, "80");
IupSetAttributeId(multitext, "MARKERSYMBOL", 2, "BACKGROUND");
/* current line marker=3 */
IupSetAttributeId(multitext, "MARKERFGCOLOR", 3, "0 0 0");
IupSetAttributeId(multitext, "MARKERBGCOLOR", 3, "0 255 0");
IupSetAttributeId(multitext, "MARKERALPHA", 3, "80");
IupSetAttributeId(multitext, "MARKERSYMBOL", 3, "SHORTARROW");
IupSetAttribute(multitext, "MOUSEDWELLTIME", "1000");
#ifdef WIN32
IupSetAttribute(multitext, "FONT", "Consolas, 11");
#else
IupSetAttribute(multitext, "FONT", "Monospace, 12");
/* Other alternatives for "Consolas" in Linux: "DejaVu Sans Mono", "Liberation Mono", "Nimbus Mono L", "FreeMono" */
#endif
return IUP_DEFAULT;
}
static int tree_globals_map(Ihandle* ih)
{
Ihandle* config = get_config(ih);
/* must load also here because we need the tree mapped */
load_globals(ih, config);
return IUP_NOERROR;
}
/********************************** Main *****************************************/
static Ihandle* buildLuaMenu(void)
{
Ihandle *item_autocomplete, *item_style_config, *item_expand, *item_toggle, *item_level,
*item_folding, *item_toggle_folding, *luaMenu, *item_options, *item_collapse,
*item_blockcomment, *item_blockuncomment, *item_linescomment, *item_linesuncomment;
item_autocomplete = IupItem("Auto Completion", NULL);
IupSetAttribute(item_autocomplete, "NAME", "ITM_AUTOCOMPLETE");
IupSetCallback(item_autocomplete, "ACTION", (Icallback)item_autocomplete_action_cb);
item_style_config = IupItem("Syntax Colors...", NULL);
IupSetAttribute(item_style_config, "NAME", "ITM_STYLE");
IupSetCallback(item_style_config, "ACTION", (Icallback)item_style_config_action_cb);
item_folding = IupItem("Folding", NULL);
IupSetAttribute(item_folding, "NAME", "ITM_FOLDING");
IupSetCallback(item_folding, "ACTION", (Icallback)item_folding_action_cb);
item_toggle_folding = IupItem("Toggle Fold\tF8", NULL);
IupSetAttribute(item_toggle_folding, "NAME", "ITM_TOGGLE_FOLDING");
IupSetCallback(item_toggle_folding, "ACTION", (Icallback)item_toggle_folding_action_cb);
item_collapse = IupItem("Collapse", NULL);
IupSetAttribute(item_collapse, "NAME", "ITM_COLLAPSE");
IupSetCallback(item_collapse, "ACTION", (Icallback)item_fold_collapse_action_cb);
item_expand = IupItem("Expand", NULL);
IupSetAttribute(item_expand, "NAME", "ITM_EXPAND");
IupSetCallback(item_expand, "ACTION", (Icallback)item_fold_expand_action_cb);
item_toggle = IupItem("Toggle", NULL);
IupSetAttribute(item_toggle, "NAME", "ITM_TOGGLE");
IupSetCallback(item_toggle, "ACTION", (Icallback)item_fold_toggle_action_cb);
item_level = IupItem("by Level...", NULL);
IupSetAttribute(item_level, "NAME", "ITM_LEVEL");
IupSetCallback(item_level, "ACTION", (Icallback)item_fold_level_action_cb);
item_blockcomment = IupItem("Block Comment", NULL);
IupSetCallback(item_blockcomment, "ACTION", (Icallback)item_blockcomment_action_cb);
item_blockuncomment = IupItem("Block Uncomment", NULL);
IupSetCallback(item_blockuncomment, "ACTION", (Icallback)item_blockuncomment_action_cb);
item_linescomment = IupItem("Lines Comment", NULL);
IupSetCallback(item_linescomment, "ACTION", (Icallback)item_linescomment_action_cb);
item_linesuncomment = IupItem("Lines Uncomment", NULL);
IupSetCallback(item_linesuncomment, "ACTION", (Icallback)item_linesuncomment_action_cb);
item_options = IupItem("Options...", NULL);
IupSetCallback(item_options, "ACTION", (Icallback)item_options_action_cb);
luaMenu = IupMenu(
item_folding,
item_toggle_folding,
IupSubmenu("Fold All",
IupSetAttributes(IupMenu(
item_collapse,
item_expand,
item_toggle,
item_level,
NULL), "NAME=ITM_FOLD_ALL")),
IupSeparator(),
IupSubmenu("Comments",
IupSetAttributes(IupMenu(
item_blockcomment,
item_blockuncomment,
item_linescomment,
item_linesuncomment,
NULL), "NAME=ITM_COMMENTS")),
IupSeparator(),
item_autocomplete,
IupSeparator(),
item_style_config,
item_options,
NULL);
iupLuaScripterDebuggerAddMenuItems(luaMenu);
IupSetCallback(luaMenu, "OPEN_CB", (Icallback)lua_menu_open_cb);
return IupSubmenu("&Lua", luaMenu);
}
static int iLuaScripterDlgCreateMethod(Ihandle* ih, void** params)
{
lua_State *L;
Ihandle *menu, *luaMenu;
Ihandle *toolbar, *panelTabs, *multitextTabs;
L = (lua_State*)IupGetGlobal("_IUP_LUA_DEFAULT_STATE");
IupSetAttribute(ih, "LUASTATE", (char*)L);
/* File Open/Save filters */
IupSetAttribute(ih, "EXTRAFILTERS", "Lua Files|*.lua|");
IupSetAttribute(ih, "DEFAULT_EXT", "lua");
/* Additional hot keys */
IupSetCallback(ih, "K_F8", (Icallback)item_toggle_folding_action_cb);
iupLuaScripterDebuggerAddHotKeys(ih);
/* configuring the IupScintillaDlg */
IupSetCallback(ih, "EXIT_CB", (Icallback)exit_cb);
IupSetCallback(ih, "MARKERCHANGED_CB", (Icallback)marker_changed_cb);
IupSetCallback(ih, "RESTOREMARKERS_CB", (Icallback)restoremarkers_cb);
IupSetCallback(ih, "CONFIGSAVE_CB", (Icallback)configsave_cb);
IupSetCallback(ih, "CONFIGLOAD_CB", (Icallback)configload_cb);
IupSetCallback(ih, "NEWTEXT_CB", (Icallback)newtext_cb);
IupSetCallback(ih, "NEWFILENAME_CB", (Icallback)newfilename_cb);
/* Call NEW_TEXT_CB because the first tab was already created */
newtext_cb(ih, get_current_multitext(ih));
/* Additional toolbar buttons */
toolbar = IupGetDialogChild(ih, "TOOLBAR");
iupLuaScripterDebuggerAddToolbarButtons(toolbar);
luaMenu = buildLuaMenu();
menu = IupGetAttributeHandle(ih, "MENU");
IupInsert(menu, IupGetChild(menu, IupGetChildCount(menu) - 1), luaMenu); /* penultimate submenu as reference */
panelTabs = IupGetDialogChild(ih, "PANEL_TABS");
multitextTabs = IupGetDialogChild(ih, "MULTITEXT_TABS");
iuplua_push_name(L, "ConsoleCreate");
iuplua_pushihandle(L, panelTabs);
iuplua_call_raw(L, 1, 0);
iupLuaScripterDebuggerCreateTabs(panelTabs);
iuplua_push_name(L, "DebuggerInit");
iuplua_pushihandle(L, panelTabs);
iuplua_pushihandle(L, multitextTabs);
iuplua_call_raw(L, 2, 0);
{
Ihandle* treeGlobals = IupGetDialogChild(ih, "DEBUG_TREE_GLOBAL");
IupSetCallback(treeGlobals, "MAP_CB", (Icallback)tree_globals_map);
}
(void)params;
return IUP_NOERROR;
}
static int iLuaScripterDebuggerCreate(lua_State *L)
{
Ihandle* panelTabs = iuplua_checkihandle(L, 1);
Ihandle* multitextTabs = iuplua_checkihandle(L, 2);
IupSetAttribute(IupGetDialog(panelTabs), "LUASTATE", (char*)L);
iupLuaScripterDebuggerCreateTabs(panelTabs);
iuplua_push_name(L, "DebuggerInit");
iuplua_pushihandle(L, panelTabs);
iuplua_pushihandle(L, multitextTabs);
iuplua_call_raw(L, 2, 0);
return 0;
}
static int iLuaScripterDebuggerAddToolbarButtons(lua_State *L)
{
Ihandle* toolbar = iuplua_checkihandle(L, 1);
iupLuaScripterDebuggerAddToolbarButtons(toolbar);
return 0;
}
static int iLuaScripterDebuggerAddMenuItems(lua_State *L)
{
Ihandle* lua_menu = iuplua_checkihandle(L, 1);
iupLuaScripterDebuggerAddMenuItems(lua_menu);
return 0;
}
static int iLuaScripterDebuggerAddHotKeys(lua_State *L)
{
Ihandle* ih = iuplua_checkihandle(L, 1);
iupLuaScripterDebuggerAddHotKeys(ih);
return 0;
}
static Iclass* iupLuaScripterDlgNewClass(void)
{
Iclass* ic = iupClassNew(iupRegisterFindClass("scintilladlg"));
ic->New = iupLuaScripterDlgNewClass;
ic->Create = iLuaScripterDlgCreateMethod;
ic->name = "luascripterdlg";
ic->cons = "LuaScripterDlg";
ic->nativetype = IUP_TYPEDIALOG;
ic->is_interactive = 1;
ic->childtype = IUP_CHILDNONE;
ic->has_attrib_id = 1; /* has attributes with IDs that must be parsed */
iupClassRegisterReplaceAttribDef(ic, "SUBTITLE", IUPAF_SAMEASSYSTEM, "Scripter");
if (!IupGetHandle("IUP_stepinto"))
load_all_images_step_images();
return ic;
}
Ihandle* IupLuaScripterDlg(void)
{
return IupCreate("luascripterdlg");
}
void IupLuaScripterDlgOpen(lua_State *L)
{
if (!IupGetGlobal("_IUP_LUASCRIPTERDLG_OPEN"))
{
IupScintillaOpen();
IupImageLibOpen();
#if LUA_VERSION_NUM < 502
lua_pushliteral(L, LUA_RELEASE " " LUA_COPYRIGHT);
#else
lua_pushliteral(L, LUA_COPYRIGHT);
#endif
lua_setglobal(L, "_COPYRIGHT"); /* set global _COPYRIGHT */
#ifdef IUPLUA_USELOH
#include "debugger.loh"
#include "console.loh"
#else
#ifdef IUPLUA_USELH
#include "debugger.lh"
#include "console.lh"
#else
iuplua_dofile(L, "console.lua");
iuplua_dofile(L, "debugger.lua");
#endif
#endif
iuplua_register(L, iLuaScripterDebuggerCreate, "DebuggerCreate");
iuplua_register(L, iLuaScripterDebuggerAddToolbarButtons, "DebuggerAddToolbarButtons");
iuplua_register(L, iLuaScripterDebuggerAddMenuItems, "DebuggerAddMenuItems");
iuplua_register(L, iLuaScripterDebuggerAddHotKeys, "DebuggerAddHotKeys");
iupRegisterClass(iupLuaScripterDlgNewClass());
IupSetGlobal("_IUP_LUASCRIPTERDLG_OPEN", "1");
}
}
/* TODO:
- ** condicional Breakpoints, Hit Count, When Hit
- sub-folder level for Projects
- multi-language (Portuguese, Spanish)
- detachable Console, Debug, Breakpoints (problem with IupGetDialogChild(NAME))?
- detachable Multitext?
*/