diff options
Diffstat (limited to 'love2dToAPK/tools/tools/zbstudio-win/src/main.lua')
-rw-r--r-- | love2dToAPK/tools/tools/zbstudio-win/src/main.lua | 774 |
1 files changed, 774 insertions, 0 deletions
diff --git a/love2dToAPK/tools/tools/zbstudio-win/src/main.lua b/love2dToAPK/tools/tools/zbstudio-win/src/main.lua new file mode 100644 index 0000000..4d6b68c --- /dev/null +++ b/love2dToAPK/tools/tools/zbstudio-win/src/main.lua @@ -0,0 +1,774 @@ +-- Copyright 2011-15 Paul Kulchenko, ZeroBrane LLC +-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch) +--------------------------------------------------------- + +-- put bin/ and lualibs/ first to avoid conflicts with included modules +-- that may have other versions present somewhere else in path/cpath. +local function isproc() + local file = io.open("/proc") + if file then file:close() end + return file ~= nil +end +local iswindows = os.getenv('WINDIR') or (os.getenv('OS') or ''):match('[Ww]indows') +local islinux = not iswindows and isproc() +local arch = "x86" -- use 32bit by default +local unpack = table.unpack or unpack + +if islinux then + local file = io.popen("uname -m") + if file then + local machine=file:read("*l") + local archtype= { x86_64="x64", armv7l="armhf" } + arch = archtype[machine] or "x86" + file:close() + end +end + +package.cpath = ( + iswindows and 'bin/?.dll;bin/clibs/?.dll;' or + islinux and ('bin/linux/%s/lib?.so;bin/linux/%s/clibs/?.so;'):format(arch,arch) or + --[[isosx]] 'bin/lib?.dylib;bin/clibs/?.dylib;') + .. package.cpath +package.path = 'lualibs/?.lua;lualibs/?/?.lua;lualibs/?/init.lua;lualibs/?/?/?.lua;lualibs/?/?/init.lua;' + .. package.path + +require("wx") +require("bit") +require("mobdebug") +if jit and jit.on then jit.on() end -- turn jit "on" as "mobdebug" may turn it off for LuaJIT + +dofile "src/util.lua" + +----------- +-- IDE +-- +local pendingOutput = {} +ide = { + MODPREF = "* ", + MAXMARGIN = 4, + config = { + path = { + projectdir = "", + app = nil, + }, + editor = { + autoactivate = false, + foldcompact = true, + checkeol = true, + saveallonrun = false, + caretline = true, + showfncall = false, + autotabs = false, + usetabs = false, + tabwidth = 2, + usewrap = true, + wrapmode = wxstc.wxSTC_WRAP_WORD, + calltipdelay = 500, + smartindent = true, + fold = true, + autoreload = true, + indentguide = true, + backspaceunindent = true, + }, + debugger = { + verbose = false, + hostname = nil, + port = nil, + runonstart = nil, + redirect = nil, + maxdatalength = 400, + maxdatanum = 400, + maxdatalevel = 3, + }, + default = { + name = 'untitled', + fullname = 'untitled.lua', + interpreter = 'luadeb', + }, + outputshell = { + usewrap = true, + }, + filetree = { + mousemove = true, + }, + outline = { + jumptocurrentfunction = true, + showanonymous = '~', + showcurrentfunction = true, + showcompact = false, + showflat = false, + showmethodindicator = false, + showonefile = false, + sort = false, + }, + commandbar = { + prefilter = 250, -- number of records after which to apply filtering + maxitems = 30, -- max number of items to show + width = 0.35, -- <1 -- size in proportion to the app frame width; >1 -- size in pixels + showallsymbols = true, + }, + staticanalyzer = { + infervalue = false, -- off by default as it's a slower mode + }, + search = { + autocomplete = true, + contextlinesbefore = 2, + contextlinesafter = 2, + showaseditor = false, + zoom = 0, + autohide = false, + }, + print = { + magnification = -3, + wrapmode = wxstc.wxSTC_WRAP_WORD, + colourmode = wxstc.wxSTC_PRINT_BLACKONWHITE, + header = "%S\t%D\t%p/%P", + footer = nil, + }, + toolbar = { + icons = {}, + iconmap = {}, + }, + + keymap = {}, + imagemap = { + ['VALUE-MCALL'] = 'VALUE-SCALL', + }, + messages = {}, + language = "en", + + styles = nil, + stylesoutshell = nil, + + autocomplete = true, + autoanalyzer = true, + acandtip = { + shorttip = true, + nodynwords = true, + ignorecase = false, + symbols = true, + droprest = true, + strategy = 2, + width = 60, + maxlength = 450, + warning = true, + }, + arg = {}, -- command line arguments + api = {}, -- additional APIs to load + + format = { -- various formatting strings + menurecentprojects = "%f | %i", + apptitle = "%T - %F", + }, + + activateoutput = true, -- activate output/console on Run/Debug/Compile + unhidewindow = false, -- to unhide a gui window + projectautoopen = true, + autorecoverinactivity = 10, -- seconds + outlineinactivity = 0.250, -- seconds + markersinactivity = 0.500, -- seconds + symbolindexinactivity = 2, -- seconds + filehistorylength = 20, + projecthistorylength = 20, + bordersize = 2, + savebak = false, + singleinstance = false, + singleinstanceport = 0xe493, + showmemoryusage = false, + showhiddenfiles = false, + hidpi = false, -- HiDPI/Retina display support + hotexit = false, + -- file exclusion lists + excludelist = {".svn/", ".git/", ".hg/", "CVS/", "*.pyc", "*.pyo", "*.exe", "*.dll", "*.obj","*.o", "*.a", "*.lib", "*.so", "*.dylib", "*.ncb", "*.sdf", "*.suo", "*.pdb", "*.idb", ".DS_Store", "*.class", "*.psd", "*.db"}, + binarylist = {"*.jpg", "*.jpeg", "*.png", "*.gif", "*.ttf", "*.tga", "*.dds", "*.ico", "*.eot", "*.pdf", "*.swf", "*.jar", "*.zip", ".gz", ".rar"}, + }, + specs = { + none = { + sep = "\1", + } + }, + tools = {}, + iofilters = {}, + interpreters = {}, + packages = {}, + apis = {}, + timers = {}, + onidle = {}, + + proto = {}, -- prototypes for various classes + + app = nil, -- application engine + interpreter = nil, -- current Lua interpreter + frame = nil, -- gui related + debugger = {}, -- debugger related info + filetree = nil, -- filetree + findReplace = nil, -- find & replace handling + settings = nil, -- user settings (window pos, last files..) + session = { + projects = {}, -- project configuration for the current session + lastupdated = nil, -- timestamp of the last modification in any of the editors + lastsaved = nil, -- timestamp of the last recovery information saved + }, + + -- misc + exitingProgram = false, -- are we currently exiting, ID_EXIT + infocus = nil, -- last component with a focus + editorApp = wx.wxGetApp(), + editorFilename = nil, + openDocuments = {},-- open notebook editor documents[winId] = { + -- editor = wxStyledTextCtrl, + -- index = wxNotebook page index, + -- filePath = full filepath, nil if not saved, + -- fileName = just the filename, + -- modTime = wxDateTime of disk file or nil, + -- isModified = bool is the document modified? } + ignoredFilesList = {}, + font = { + eNormal = nil, + eItalic = nil, + oNormal = nil, + oItalic = nil, + fNormal = nil, + }, + + osname = wx.wxPlatformInfo.Get():GetOperatingSystemFamilyName(), + osarch = arch, + oshome = os.getenv("HOME") or (iswindows and os.getenv('HOMEDRIVE') and os.getenv('HOMEPATH') + and (os.getenv('HOMEDRIVE')..os.getenv('HOMEPATH'))), + wxver = string.match(wx.wxVERSION_STRING, "[%d%.]+"), + + test = {}, -- local functions used for testing + + Print = function(self, ...) + if DisplayOutputLn then + -- flush any pending output + while #pendingOutput > 0 do DisplayOutputLn(unpack(table.remove(pendingOutput, 1))) end + -- print without parameters can be used for flushing, so skip the printing + if select('#', ...) > 0 then DisplayOutputLn(...) end + return + end + pendingOutput[#pendingOutput + 1] = {...} + end, +} + +-- add wx.wxMOD_RAW_CONTROL as it's missing in wxlua 2.8.12.3; +-- provide default for wx.wxMOD_CONTROL as it's missing in wxlua 2.8 that +-- is available through Linux package managers +if not wx.wxMOD_CONTROL then wx.wxMOD_CONTROL = 0x02 end +if not wx.wxMOD_RAW_CONTROL then + wx.wxMOD_RAW_CONTROL = ide.osname == 'Macintosh' and 0x10 or wx.wxMOD_CONTROL +end +-- ArchLinux running 2.8.12.2 doesn't have wx.wxMOD_SHIFT defined +if not wx.wxMOD_SHIFT then wx.wxMOD_SHIFT = 0x04 end +-- wxDIR_NO_FOLLOW is missing in wxlua 2.8.12 as well +if not wx.wxDIR_NO_FOLLOW then wx.wxDIR_NO_FOLLOW = 0x10 end +if not wxaui.wxAUI_TB_PLAIN_BACKGROUND then wxaui.wxAUI_TB_PLAIN_BACKGROUND = 2^8 end + +if not setfenv then -- Lua 5.2 + -- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html + -- this assumes f is a function + local function findenv(f) + local level = 1 + repeat + local name, value = debug.getupvalue(f, level) + if name == '_ENV' then return level, value end + level = level + 1 + until name == nil + return nil end + getfenv = function (f) return(select(2, findenv(f)) or _G) end + setfenv = function (f, t) + local level = findenv(f) + if level then debug.setupvalue(f, level, t) end + return f end +end + +dofile "src/version.lua" + +for _, file in ipairs({"proto", "ids", "style", "keymap", "toolbar"}) do + dofile("src/editor/"..file..".lua") +end + +ide.config.styles = StylesGetDefault() +ide.config.stylesoutshell = StylesGetDefault() + +local function setLuaPaths(mainpath, osname) + -- use LUA_DEV to setup paths for Lua for Windows modules if installed + local luadev = osname == "Windows" and os.getenv('LUA_DEV') + if luadev and not wx.wxDirExists(luadev) then luadev = nil end + local luadev_path = (luadev + and ('LUA_DEV/?.lua;LUA_DEV/?/init.lua;LUA_DEV/lua/?.lua;LUA_DEV/lua/?/init.lua') + :gsub('LUA_DEV', (luadev:gsub('[\\/]$',''))) + or nil) + local luadev_cpath = (luadev + and ('LUA_DEV/?.dll;LUA_DEV/?51.dll;LUA_DEV/clibs/?.dll;LUA_DEV/clibs/?51.dll') + :gsub('LUA_DEV', (luadev:gsub('[\\/]$',''))) + or nil) + + if luadev then + local path, clibs = os.getenv('PATH'), luadev:gsub('[\\/]$','')..'\\clibs' + if not path:find(clibs, 1, true) then wx.wxSetEnv('PATH', path..';'..clibs) end + end + + -- (luaconf.h) in Windows, any exclamation mark ('!') in the path is replaced + -- by the path of the directory of the executable file of the current process. + -- this effectively prevents any path with an exclamation mark from working. + -- if the path has an excamation mark, allow Lua to expand it as this + -- expansion happens only once. + if osname == "Windows" and mainpath:find('%!') then mainpath = "!/../" end + + -- if LUA_PATH or LUA_CPATH is not specified, then add ;; + -- ;; will be replaced with the default (c)path by the Lua interpreter + wx.wxSetEnv("LUA_PATH", + (os.getenv("LUA_PATH") or ';') .. ';' + .. "./?.lua;./?/init.lua;./lua/?.lua;./lua/?/init.lua" .. ';' + .. mainpath.."lualibs/?/?.lua;"..mainpath.."lualibs/?.lua;" + .. mainpath.."lualibs/?/?/init.lua;"..mainpath.."lualibs/?/init.lua" + .. (luadev_path and (';' .. luadev_path) or '')) + + ide.osclibs = -- keep the list to use for other Lua versions + osname == "Windows" and mainpath.."bin/?.dll;"..mainpath.."bin/clibs/?.dll" or + osname == "Macintosh" and mainpath.."bin/lib?.dylib;"..mainpath.."bin/clibs/?.dylib" or + osname == "Unix" and mainpath..("bin/linux/%s/lib?.so;"):format(arch) + ..mainpath..("bin/linux/%s/clibs/?.so"):format(arch) or + assert(false, "Unexpected OS name") + + wx.wxSetEnv("LUA_CPATH", + (os.getenv("LUA_CPATH") or ';') .. ';' .. ide.osclibs + .. (luadev_cpath and (';' .. luadev_cpath) or '')) + + -- on some OSX versions, PATH is sanitized to not include even /usr/local/bin; add it + if osname == "Macintosh" then + local ok, path = wx.wxGetEnv("PATH") + if ok then wx.wxSetEnv("PATH", (#path > 0 and path..":" or "").."/usr/local/bin") end + end +end + +ide.test.setLuaPaths = setLuaPaths + +--------------- +-- process args +local filenames = {} +local configs = {} +do + local arg = {...} + -- application name is expected as the first argument + local fullPath = arg[1] or "zbstudio" + + ide.arg = arg + + -- on Windows use GetExecutablePath, which is Unicode friendly, + -- whereas wxGetCwd() is not (at least in wxlua 2.8.12.2). + -- some wxlua version on windows report wx.dll instead of *.exe. + local exepath = wx.wxStandardPaths.Get():GetExecutablePath() + if ide.osname == "Windows" and exepath:find("%.exe$") then + fullPath = exepath + elseif not wx.wxIsAbsolutePath(fullPath) then + fullPath = wx.wxGetCwd().."/"..fullPath + end + + ide.editorFilename = fullPath + ide.appname = fullPath:match("([%w_-%.]+)$"):gsub("%.[^%.]*$","") + assert(ide.appname, "no application path defined") + + for index = 2, #arg do + if (arg[index] == "-cfg" and index+1 <= #arg) then + table.insert(configs,arg[index+1]) + elseif arg[index-1] ~= "-cfg" + -- on OSX command line includes -psn... parameter, don't include these + and (ide.osname ~= 'Macintosh' or not arg[index]:find("^-psn")) then + table.insert(filenames,arg[index]) + end + end + + setLuaPaths(GetPathWithSep(ide.editorFilename), ide.osname) +end + +---------------------- +-- process application + +ide.app = dofile(ide.appname.."/app.lua") +local app = assert(ide.app) + +local function loadToTab(filter, folder, tab, recursive, proto) + if filter and type(filter) ~= 'function' then + filter = app.loadfilters[filter] or nil + end + for _, file in ipairs(FileSysGetRecursive(folder, recursive, "*.lua")) do + if not filter or filter(file) then + LoadLuaFileExt(tab, file, proto) + end + end + return tab +end + +local function loadInterpreters(filter) + loadToTab(filter or "interpreters", "interpreters", ide.interpreters, false, + ide.proto.Interpreter) +end + +-- load tools +local function loadTools(filter) + loadToTab(filter or "tools", "tools", ide.tools, false) +end + +-- load packages +local function processPackages(packages) + -- check dependencies and assign file names to each package + local skip = {} + for fname, package in pairs(packages) do + if type(package.dependencies) == 'table' + and package.dependencies.osname + and not package.dependencies.osname:find(ide.osname, 1, true) then + ide:Print(("Package '%s' not loaded: requires %s platform, but you are running %s.") + :format(fname, package.dependencies.osname, ide.osname)) + skip[fname] = true + end + + local needsversion = tonumber(package.dependencies) + or type(package.dependencies) == 'table' and tonumber(package.dependencies[1]) + or -1 + local isversion = tonumber(ide.VERSION) + if isversion and needsversion > isversion then + ide:Print(("Package '%s' not loaded: requires version %s, but you are running version %s.") + :format(fname, needsversion, ide.VERSION)) + skip[fname] = true + end + package.fname = fname + end + + for fname, package in pairs(packages) do + if not skip[fname] then ide.packages[fname] = package end + end +end + +function UpdateSpecs() + for _, spec in pairs(ide.specs) do + spec.sep = spec.sep or "\1" -- default separator doesn't match anything + spec.iscomment = {} + spec.iskeyword0 = {} + spec.isstring = {} + if (spec.lexerstyleconvert) then + if (spec.lexerstyleconvert.comment) then + for _, s in pairs(spec.lexerstyleconvert.comment) do + spec.iscomment[s] = true + end + end + if (spec.lexerstyleconvert.keywords0) then + for _, s in pairs(spec.lexerstyleconvert.keywords0) do + spec.iskeyword0[s] = true + end + end + if (spec.lexerstyleconvert.stringtxt) then + for _, s in pairs(spec.lexerstyleconvert.stringtxt) do + spec.isstring[s] = true + end + end + end + end +end + +-- load specs +local function loadSpecs(filter) + loadToTab(filter or "specs", "spec", ide.specs, true) + UpdateSpecs() +end + +function GetIDEString(keyword, default) + return app.stringtable[keyword] or default or keyword +end + +---------------------- +-- process config + +-- set ide.config environment +do + ide.configs = { + system = MergeFullPath("cfg", "user.lua"), + user = ide.oshome and MergeFullPath(ide.oshome, "."..ide.appname.."/user.lua"), + } + ide.configqueue = {} + + local num = 0 + local package = setmetatable({}, { + __index = function(_,k) return package[k] end, + __newindex = function(_,k,v) package[k] = v end, + __call = function(_,p) + -- package can be defined inline, like "package {...}" + if type(p) == 'table' then + num = num + 1 + local name = 'config'..num..'package' + ide.packages[name] = setmetatable(p, ide.proto.Plugin) + -- package can be included as "package 'file.lua'" or "package 'folder/'" + elseif type(p) == 'string' then + local config = ide.configqueue[#ide.configqueue] + local pkg + for _, packagepath in ipairs({'.', 'packages/', '../packages/'}) do + local p = config and MergeFullPath(config.."/../"..packagepath, p) + pkg = wx.wxDirExists(p) and loadToTab(nil, p, {}, false, ide.proto.Plugin) + or wx.wxFileExists(p) and LoadLuaFileExt({}, p, ide.proto.Plugin) + or wx.wxFileExists(p..".lua") and LoadLuaFileExt({}, p..".lua", ide.proto.Plugin) + if pkg then + processPackages(pkg) + break + end + end + if not pkg then ide:Print(("Can't find '%s' to load package from."):format(p)) end + else + ide:Print(("Can't load package based on parameter of type '%s'."):format(type(p))) + end + end, + }) + + local includes = {} + local include = function(c) + if c then + for _, config in ipairs({ide.configqueue[#ide.configqueue], ide.configs.user, ide.configs.system}) do + local p = config and MergeFullPath(config.."/../", c) + includes[p] = (includes[p] or 0) + 1 + if includes[p] > 1 or LoadLuaConfig(p) or LoadLuaConfig(p..".lua") then return end + includes[p] = includes[p] - 1 + end + ide:Print(("Can't find configuration file '%s' to process."):format(c)) + end + end + + setmetatable(ide.config, { + __index = setmetatable({ + load = {interpreters = loadInterpreters, specs = loadSpecs, tools = loadTools}, + package = package, + include = include, + }, {__index = _G or _ENV}) + }) +end + +LoadLuaConfig(ide.appname.."/config.lua") + +ide.editorApp:SetAppName(GetIDEString("settingsapp")) + +-- check if the .ini file needs to be migrated on Windows +if ide.osname == 'Windows' and ide.wxver >= "2.9.5" then + -- Windows used to have local ini file kept in wx.wxGetHomeDir (before 2.9), + -- but since 2.9 it's in GetUserConfigDir(), so migrate it. + local ini = ide.editorApp:GetAppName() .. ".ini" + local old = wx.wxFileName(wx.wxGetHomeDir(), ini) + local new = wx.wxFileName(wx.wxStandardPaths.Get():GetUserConfigDir(), ini) + if old:FileExists() and not new:FileExists() then + FileCopy(old:GetFullPath(), new:GetFullPath()) + ide:Print(("Migrated configuration file from '%s' to '%s'.") + :format(old:GetFullPath(), new:GetFullPath())) + end +end + +---------------------- +-- process plugins + +if app.preinit then app.preinit() end + +loadInterpreters() +loadSpecs() +loadTools() + +do + -- process configs + LoadLuaConfig(ide.configs.system) + LoadLuaConfig(ide.configs.user) + + -- process all other configs (if any) + for _, v in ipairs(configs) do LoadLuaConfig(v, true) end + configs = nil + + -- check and apply default styles in case a user resets styles in the config + for _, styles in ipairs({"styles", "stylesoutshell"}) do + if not ide.config[styles] then + ide:Print(("Ignored incorrect value of '%s' setting in the configuration file") + :format(styles)) + ide.config[styles] = StylesGetDefault() + end + end + + local sep = GetPathSeparator() + if ide.config.language then + LoadLuaFileExt(ide.config.messages, "cfg"..sep.."i18n"..sep..ide.config.language..".lua") + end + -- always load 'en' as it's requires as a fallback for pluralization + if ide.config.language ~= 'en' then + LoadLuaFileExt(ide.config.messages, "cfg"..sep.."i18n"..sep.."en.lua") + end +end + +processPackages(loadToTab(nil, "packages", {}, false, ide.proto.Plugin)) +if ide.oshome then + local userpackages = MergeFullPath(ide.oshome, "."..ide.appname.."/packages") + if wx.wxDirExists(userpackages) then + processPackages(loadToTab(nil, userpackages, {}, false, ide.proto.Plugin)) + end +end + +--------------- +-- Load App + +for _, file in ipairs({ + "settings", "singleinstance", "iofilters", "package", "markup", + "gui", "filetree", "output", "debugger", "outline", "commandbar", + "editor", "findreplace", "commands", "autocomplete", "shellbox", "markers", + "menu_file", "menu_edit", "menu_search", + "menu_view", "menu_project", "menu_tools", "menu_help", + "print", "inspect" }) do + dofile("src/editor/"..file..".lua") +end + +-- register all the plugins +PackageEventHandle("onRegister") + +-- initialization that was delayed until configs processed and packages loaded +ProjectUpdateInterpreters() + +-- load rest of settings +SettingsRestoreFramePosition(ide.frame, "MainFrame") +SettingsRestoreView() +SettingsRestoreFileHistory(SetFileHistory) +SettingsRestoreEditorSettings() +SettingsRestoreProjectSession(FileTreeSetProjects) +SettingsRestoreFileSession(function(tabs, params) + if params and params.recovery + then return SetOpenTabs(params) + else return SetOpenFiles(tabs, params) end +end) + +-- --------------------------------------------------------------------------- +-- Load the filenames + +do + for _, filename in ipairs(filenames) do + if filename ~= "--" then + if wx.wxDirExists(filename) then + ProjectUpdateProjectDir(filename) + elseif not ActivateFile(filename) then + DisplayOutputLn(("Can't open file '%s': %s"):format(filename, wx.wxSysErrorMsg())) + end + end + end + if ide:GetEditorNotebook():GetPageCount() == 0 then NewFile() end +end + +if app.postinit then app.postinit() end + +-- this is a workaround for a conflict between global shortcuts and local +-- shortcuts (like F2) used in the file tree or a watch panel. +-- because of several issues on OSX (as described in details in this thread: +-- https://groups.google.com/d/msg/wx-dev/juJj_nxn-_Y/JErF1h24UFsJ), +-- the workaround installs a global event handler that manually re-routes +-- conflicting events when the current focus is on a proper object. +-- non-conflicting shortcuts are handled through key-down events. +local remap = { + [ID_ADDWATCH] = ide:GetWatch(), + [ID_EDITWATCH] = ide:GetWatch(), + [ID_DELETEWATCH] = ide:GetWatch(), + [ID_RENAMEFILE] = ide:GetProjectTree(), + [ID_DELETEFILE] = ide:GetProjectTree(), +} + +local function rerouteMenuCommand(obj, id) + -- check if the conflicting shortcut is enabled: + -- (1) SetEnabled wasn't called or (2) Enabled was set to `true`. + local uievent = wx.wxUpdateUIEvent(id) + obj:ProcessEvent(uievent) + if not uievent:GetSetEnabled() or uievent:GetEnabled() then + obj:AddPendingEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, id)) + end +end + +local function remapkey(event) + local keycode = event:GetKeyCode() + local mod = event:GetModifiers() + for id, obj in pairs(remap) do + local focus = obj:FindFocus() + if focus and focus:GetId() == obj:GetId() then + local ae = wx.wxAcceleratorEntry(); ae:FromString(KSC(id)) + if ae:GetFlags() == mod and ae:GetKeyCode() == keycode then + rerouteMenuCommand(obj, id) + return + end + end + end + event:Skip() +end +ide:GetWatch():Connect(wx.wxEVT_KEY_DOWN, remapkey) +ide:GetProjectTree():Connect(wx.wxEVT_KEY_DOWN, remapkey) + +local function resolveConflict(localid, globalid) + return function(event) + local shortcut = ide.config.keymap[localid] + for id, obj in pairs(remap) do + if ide.config.keymap[id]:lower() == shortcut:lower() then + local focus = obj:FindFocus() + if focus and focus:GetId() == obj:GetId() then + obj:AddPendingEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_MENU_SELECTED, id)) + return + -- also need to check for children of objects + -- to avoid re-triggering events when labels are being edited + elseif focus and focus:GetParent():GetId() == obj:GetId() then + return + end + end + end + rerouteMenuCommand(ide.frame, globalid) + end +end + +local at = {} +for lid in pairs(remap) do + local shortcut = ide.config.keymap[lid] + -- find a (potential) conflict for this shortcut (if any) + for gid, ksc in pairs(ide.config.keymap) do + -- if the same shortcut is used elsewhere (not one of IDs being checked) + if shortcut:lower() == ksc:lower() and not remap[gid] then + local fakeid = NewID() + ide.frame:Connect(fakeid, wx.wxEVT_COMMAND_MENU_SELECTED, + resolveConflict(lid, gid)) + + local ae = wx.wxAcceleratorEntry(); ae:FromString(ksc) + table.insert(at, wx.wxAcceleratorEntry(ae:GetFlags(), ae:GetKeyCode(), fakeid)) + end + end +end + +if ide.osname == 'Macintosh' then + table.insert(at, wx.wxAcceleratorEntry(wx.wxACCEL_CTRL, ('M'):byte(), ID_VIEWMINIMIZE)) +end +ide.frame:SetAcceleratorTable(wx.wxAcceleratorTable(at)) + +-- only set menu bar *after* postinit handler as it may include adding +-- app-specific menus (Help/About), which are not recognized by MacOS +-- as special items unless SetMenuBar is done after menus are populated. +ide.frame:SetMenuBar(ide.frame.menuBar) + +ide:Print() -- flush pending output (if any) + +PackageEventHandle("onAppLoad") + +-- The status bar content is drawn incorrectly if it is shown +-- after being initially hidden. +-- Show the statusbar and hide it after showing the frame, which fixes the issue. +local statusbarfix = ide.osname == 'Windows' and not ide.frame:GetStatusBar():IsShown() +if statusbarfix then ide.frame:GetStatusBar():Show(true) end + +ide.frame:Show(true) + +if statusbarfix then ide.frame:GetStatusBar():Show(false) end + +-- somehow having wxAuiToolbar "steals" the focus from the editor on OSX; +-- have to set the focus implicitly on the current editor (if any) +if ide.osname == 'Macintosh' then + local editor = GetEditor() + if editor then editor:SetFocus() end +end + +wx.wxGetApp():MainLoop() + +-- There are several reasons for this call: +-- (1) to fix a crash on OSX when closing with debugging in progress. +-- (2) to fix a crash on Linux 32/64bit during GC cleanup in wxlua +-- after an external process has been started from the IDE. +-- (3) to fix exit on Windows when started as "bin\lua src\main.lua". +os.exit() |