-- ------------------------------------------------------------------------- --
-- Project: Executive Assistant - Custom To-Do/Task List Manager
-- Author: VincentSDSH
-- Version: 1.4b - w9.0
-- ------------------------------------------------------------------------- --
-- Command: /ea or /exa
--
-- ------------------------------------------------------------------------- --
-- W9.x Notes
-- Blizzard: "Instead of always creating backdrops on every frame, they require each frame to explicitly inherit
-- backdrops. There is no change in functionality, only the default setting has been changed in an effort
-- to improve performance."
-- Adding "BackdropTemplate" as para4 to CreateFrame() to set things back to normal. Might be overkill but it'll save a lot of retesting
--
-- ------------------------------------------------------------------------- --
--
-- Optional
-- See line 72 of ea_Options.lua to change from 60min to 30min time intervals
--
-- [ ] Option for Command Line Target to be Per Character, set per character.
-- Task Resets (Occ Intern) should trigger a LDB Update
-- ------------------------------------------------------------------------- --
local AddonName = ...
ExecAssist = LibStub ( " AceAddon-3.0 " ) : NewAddon ( AddonName , " AceEvent-3.0 " , " AceTimer-3.0 " , " AceHook-3.0 " )
ExecAssist.Dialog = LibStub ( " AceConfigDialog-3.0 " )
ExecAssist.debug = function ( data , label , colorize ) if ExecAssist.db . sv.debug then local r , b , g if not colorize then r = 1 ; g = 1 ; b = .8 elseif ( label and data ) then r = 0 ; g = 1 ; b = 0 else r = 1 ; g = 0 ; b = 0 end ; local eaColon = ( " :: " ) : cf ( " EAblue " ) ; DEFAULT_CHAT_FRAME : AddMessage ( eaColon .. ( " EA_debug " ) : cf ( " EAtan " ) .. eaColon .. " " .. ( label and ( label .. " is: " ) or " " ) .. tostring ( data ) , r , g , b ) ; end end
local debug = ExecAssist.debug
local L = LibStub ( " AceLocale-3.0 " ) : GetLocale ( AddonName )
function ExecAssist : OnInitialize ( )
self.wowVer = " 9.0 "
self.FC = " Executive_Assistant_FileCabinet "
-- Extend Plumbing ------------------------------------------------------- --
self : extendStringFunc ( )
-- Defaults -------------------------------------------------------------- --
self.EventsRegistered = { } ; self.prototype = { }
self.prototype . Group = {
[ " isGroup " ] = true ,
[ " id " ] = " " , -- self handle :: pass (hGroup) rather than (hGroup, groupID) when asking a parent to operate on the child's /reference/ not just the child (e.g., .DO ops, etc)
[ " p " ] = " " , -- parent GroupID
[ " listName " ] = " Default New Group Name " ,
-- ["objbName"] = "Default New Group Name",
[ " defaultEnabled " ] = true , -- ENABLED
[ " hideDays " ] = { } , -- {Sun -> Sat}
[ " DO " ] = { }
}
self.prototype . Task = {
[ " isTask " ] = true ,
[ " id " ] = " " , -- taskID
[ " p " ] = " " , -- parent GroupID
[ " taskName " ] = " Default New Task Name " ,
-- ["objbName"] = "Default New Task Name",
[ " defaultEnabled " ] = true , -- ENABLED
[ " resetType " ] = " Daily Automatic " , -- {Daily, Weekly, Other}
[ " hideDays " ] = { } -- {Sun -> Sat} Primed b/c the multiselect control returns
}
self.icons = {
[ " defaultLDBIcon " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_appIcon]] ) : format ( AddonName ) ,
[ " ldb_Complete " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_on]] ) : format ( AddonName ) ,
[ " ldb_Incomplete " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_off]] ) : format ( AddonName ) ,
[ " enabled " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_on]] ) : format ( AddonName ) ,
[ " disabled " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_off]] ) : format ( AddonName ) ,
[ " used " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_used]] ) : format ( AddonName ) ,
[ " notused " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_notused]] ) : format ( AddonName ) ,
[ " used_R " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_used_reminder]] ) : format ( AddonName ) ,
[ " notused_R " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_notused_reminder]] ) : format ( AddonName ) ,
[ " disabledGroup " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_disabled]] ) : format ( AddonName ) ,
[ " twExpanded " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_twExpanded]] ) : format ( AddonName ) ,
[ " twCollapsed " ] = ( [[Interface\Addons\%s\icons\ExecutiveAssistant_twCollapsed]] ) : format ( AddonName ) ,
[ " ldb_Expanded_h " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_Expanded_header]] ) : format ( AddonName ) ,
[ " ldb_Collapsed_h " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_Collapsed_header]] ) : format ( AddonName ) ,
[ " ldb_Expanded " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_Expanded]] ) : format ( AddonName ) ,
[ " ldb_Collapsed " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_Collapsed]] ) : format ( AddonName ) ,
[ " ldb_OneChar " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_showOne]] ) : format ( AddonName ) ,
[ " ldb_AllChar " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_showAll]] ) : format ( AddonName ) ,
[ " ldb_tt_PGT " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_PGT]] ) : format ( AddonName ) ,
[ " ldb_tt_GTP " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_GTP]] ) : format ( AddonName ) ,
[ " ldb_showGroups " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_showGroups]] ) : format ( AddonName ) ,
[ " ldb_hideGroups " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_hideGroups]] ) : format ( AddonName ) ,
[ " ldb_showALLgroups " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_showALLGroups]] ) : format ( AddonName ) ,
[ " ldb_ShowOnlySelectedGroup " ] = ( [[Interface\AddOns\%s\icons\ExecutiveAssistant_ShowOnlySelectedGroup]] ) : format ( AddonName ) ,
[ " tw_config " ] = ( [[Interface\Addons\%s\icons\ExecAssist_Config]] ) : format ( AddonName ) ,
[ " tw_config_push " ] = ( [[Interface\Addons\%s\icons\ExecAssist_Config_push]] ) : format ( AddonName ) ,
}
-- Setup AceDB
self.DBDefaults = {
-- why GLOBAL vs PROFILE or CHAR for charStem data? Profiles coonotate being able to 'change hats' mid-session
-- which would mean 'being someone else' in the context of this addon, making it confusing to say the least,
-- or to swap to different sub-sets of actions, which is understandable but a less-in-control way of doing it.
-- Moreover, I'd still have to dig into the .sv[*] end of the db var to find the other profiles to list out
-- the other characters for the GTP orientation or the full PGT orientation.
-- This same thinking applies to placing the data in Char. It doesn't make accessing it that much easier
-- (though it would be technically faster/more-efficient when only looking at the current character, that
-- measurement is in miniscule fractions of a milisecond second) and I'd still have to traverse the .sv[*]
-- end of the AceDB structure when looking at all chars.
-- Doing it this way means I can have a standard method (charStem vs self.db.char & self.db.sv.char) and
-- have no chance of running afoul of some profile-related giggery-pokery of which I might be unaware.
-- The db.char route is used for things I found a need to be character-specific, depending on the class &
-- addons used, usage might differ (e.g., minimap button position & hide/show; task-window usage & position
-- (heavy user) vs ldb-tooltip (alt with few tasks) )
[ " char " ] = {
[ " charSpecificCmdLineTarget " ] = false ,
[ " DBIconTable " ] = { [ " hide " ] = false } ,
[ " useTaskWindow " ] = true ,
[ " useDataBrokerTooltip " ] = true ,
[ " map " ] = { [ " char " ] = nil , [ " TW " ] = nil , [ " GTP " ] = nil } ,
} ,
[ " global " ] = {
[ " Options " ] = {
[ " AllowAPI " ] = false ,
[ " configConfig " ] = {
[ " scale " ] = 1 , -- ExecAssist.Dialog.OpenFrames[ExecAssist.opts.f_reg].frame:SetScale(1.2)
[ " width " ] = 800 ,
[ " height " ] = 700 ,
} ,
[ " ldbLabel " ] = L.appName ,
[ " showLoginAlerts " ] = false ,
[ " WeeklyResetDay " ] = 3 ,
[ " DailyResetTime " ] = 6 ,
[ " cfg_groupColor " ] = { [ " r " ] = 1 , [ " g " ] = 1 , [ " b " ] = 0 } ,
[ " ldbIcon " ] = " defaultLDBIcon " ,
[ " SaveCollapseMap " ] = true ,
} ,
[ " acctwideStem " ] = { -- subbing agg to make space for possible future metadata...
[ " agg " ] = { -- Not /technically/ an agglomeration since only taskID completion tags would be in play
}
} ,
[ " charStem " ] = {
} ,
[ " groupStem " ] = {
[ " garden " ] = { -- Starting Point (DO) for Groups (it was this or a hidden faux-'parent')
} ,
[ " agg " ] = { -- The Great Agglomeration, groupIDs and taskIDs >> groupID.DO = Display Order
[ " garden " ] = { -- Starting Point (DO) for Groups (it was this or a hidden faux-'parent')
[ " id " ] = " garden " ,
[ " listName " ] = " garden " ,
[ " DO " ] = { }
} ,
} ,
} ,
[ " taskWindow " ] = {
[ " locked " ] = false ,
[ " hidebuttons " ] = false ,
[ " widthMethod " ] = false ,
[ " MinWidth_FontString " ] = 120 ,
[ " FixedWidth_FontString " ] = 380 ,
[ " useRemembered_toggleState " ] = true , -- 0.9.9j
[ " toggleState_ToggledOff " ] = nil , -- 0.9.9j
[ " useDragFrame " ] = true ,
[ " strata " ] = " LOW " ,
[ " pos " ] = {
[ " idx " ] = 1 ,
[ " relTW " ] = " CENTER " ,
[ " posW_rel " ] = " CENTER " ,
[ " posW_relP " ] = " CENTER " ,
[ " xOff " ] = 0 ,
[ " yOff " ] = 0 ,
} ,
[ " HideEmptyGroups " ] = true ,
[ " defaultCollapse " ] = false ,
[ " opacity_mouseover " ] = 1 ,
[ " opacity_faded " ] = 1 ,
[ " hideincombat " ] = false ,
[ " ButtonPos " ] = 2 ,
[ " useMouseoverHighlight " ] = true ,
[ " useCounts_onHeaders " ] = true ,
[ " displayType_onHeaders " ] = 1 ,
[ " rightMouse_togglesShowChecked " ] = true ,
[ " showChecked " ] = true ,
[ " enableTooltipTooltips " ] = true ,
[ " widthMethod " ] = 1 ,
[ " style " ] = {
[ " background " ] = " Solid " , -- "Blizzard Tooltip",
[ " border " ] = " Blizzard Tooltip " ,
[ " bgcolor " ] = { [ " r " ] = 0.01 , [ " g " ] = 0.01 , [ " b " ] = 0.01 , [ " a " ] = 1 } ,
[ " bdrcolor " ] = { [ " r " ] = 0.01 , [ " g " ] = 0.01 , [ " b " ] = 0.01 , [ " a " ] = 1 } ,
} ,
[ " fontshadow " ] = {
[ " shadowcolor " ] = { [ " r " ] = 0 , [ " g " ] = 0 , [ " b " ] = 0 , [ " a " ] = .75 } ,
[ " offset " ] = { [ " x " ] = 1 , [ " y " ] = - 1 }
} ,
} ,
[ " tooltip " ] = {
[ " AutoHideDelay " ] = .01 , -- seconds before the libQTip disappears
[ " HideChar_ifNoIncomplete " ] = false ,
[ " HideEmptyGroups " ] = true ,
[ " defaultCollapse " ] = false ,
[ " rightMouse_togglesShowChecked " ] = true ,
[ " showChecked " ] = true ,
[ " defaultExpandSelf " ] = true ,
[ " OnlyCurrentChar " ] = true ,
[ " AllChar_GroupCharNames " ] = true ,
[ " ShowServerNames " ] = true ,
[ " useMouseoverHighlight " ] = true ,
[ " default_tooltipType " ] = " PGT " ,
[ " standard_font " ] = " Friz Quadrata TT " ,
[ " standard_size " ] = 10 ,
[ " header_font " ] = " Friz Quadrata TT " ,
[ " header_size " ] = 12 ,
[ " snowflake_font " ] = " Friz Quadrata TT " ,
[ " snowflake_size " ] = 9 ,
[ " fontshadow " ] = {
[ " shadowcolor " ] = { [ " r " ] = 0 , [ " g " ] = 0 , [ " b " ] = 0 , [ " a " ] = .75 } ,
[ " offset " ] = { [ " x " ] = 1 , [ " y " ] = - 1 }
} ,
[ " npc " ] = {
[ " npcColor " ] = { [ " r " ] = 0.4 , [ " g " ] = 0.4 , [ " b " ] = 0.4 , [ " a " ] = 1 } ,
} ,
[ " tooltipStyle " ] = {
[ " useStyle " ] = false ,
[ " bgFile " ] = " Solid " , -- "Interface/Tooltips/UI-Tooltip-Background"
[ " edgeFile " ] = " Blizzard Tooltip " , -- "Interface/Tooltips/UI-Tooltip-Border"
[ " edgeSize " ] = 16 ,
[ " insets " ] = 4 ,
[ " bgcolor " ] = { [ " r " ] = 0 , [ " g " ] = 0 , [ " b " ] = 0 , [ " a " ] = 1 } ,
[ " bdrcolor " ] = { [ " r " ] = 0.6 , [ " g " ] = 0.6 , [ " b " ] = 0.6 , [ " a " ] = 1 } ,
} ,
[ " useCounts_onHeaders " ] = true ,
[ " displayType_onHeaders " ] = 1 ,
[ " useCounts_onLDB " ] = true ,
[ " displayType_onLDB " ] = 1 ,
[ " default_GroupDisplayMode_PGT " ] = 1 , -- default & override group display mode
[ " ShowGroupNames_PGT " ] = true , -- group display modes
[ " ShowAllGroups_PGT " ] = true , -- group display modes
[ " ShowOnlySelectedGroup_PGT " ] = true , -- group display modes
[ " HideGroupNames_PGT " ] = true , -- group display modes
[ " default_GroupDisplayMode_GTP " ] = 1 , -- default & override group display mode
[ " ShowAllGroups_GTP " ] = true , -- group display modes
[ " HideGroupNames_GTP " ] = true , -- group display modes
[ " tooltipButtonPos " ] = 1 ,
[ " color_Group " ] = { [ " r " ] = 0.78 , [ " g " ] = 0.61 , [ " b " ] = 0.43 } ,
[ " color_TaskName " ] = { [ " r " ] = 1 , [ " g " ] = 1 , [ " b " ] = 1 } ,
[ " color_taskCounts " ] = { [ " r " ] = 0.43 , [ " g " ] = 0.61 , [ " b " ] = 0.78 } ,
[ " enableTooltipTooltips " ] = true ,
[ " SM " ] = { -- Style Manager
[ " acctwide " ] = {
[ " useStyle " ] = true ,
[ " useText " ] = 2 ,
[ " useText_text " ] = " * " ,
[ " useColor " ] = 2 ,
[ " color " ] = { [ " r " ] = 0 , [ " g " ] = 0.94 , [ " b " ] = 0.94 } ,
} ,
[ " purgable " ] = {
[ " useStyle " ] = true ,
[ " useText " ] = 2 ,
[ " useText_text " ] = " (p) " ,
[ " useColor " ] = 2 ,
[ " color " ] = { [ " r " ] = 1 , [ " g " ] = 0 , [ " b " ] = 0.5 } ,
} ,
[ " hidden " ] = {
[ " useStyle " ] = true ,
[ " useText " ] = 2 ,
[ " useText_text " ] = " (i) " ,
[ " useColor " ] = 2 ,
[ " color " ] = { [ " r " ] = 0.73 , [ " g " ] = 0.61 , [ " b " ] = 0.78 } ,
} ,
[ " cmdLineTarget " ] = {
[ " useStyle " ] = true ,
[ " useText " ] = 2 ,
[ " useText_text " ] = " (c) " ,
[ " useColor " ] = 2 ,
[ " color " ] = { [ " r " ] = 0.33 , [ " g " ] = 0.54 , [ " b " ] = 0.52 } ,
} ,
[ " snowflake " ] = {
[ " useStyle " ] = true ,
[ " useText " ] = 2 ,
[ " useText_text " ] = " [Z] " ,
[ " useColor " ] = 2 ,
[ " color " ] = { [ " r " ] = 1 , [ " g " ] = 0.49 , [ " b " ] = 0.4 } ,
} ,
} ,
} ,
-- ["clickmapOrder"] -> local clickmapOrder = {} in ea_Options to allow for safe injection from modules that isn't processed when they are disabled
[ " clickmap " ] = { -- LDB -- since it's not user alterable or put in the sv file, could move the full clickmap into this...but that would make any 3rd-party extensibility problematic at best; easy enough to stuff in for 1-index maint if the API idea is shelved
[ " CONFIG " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = ( L.clickmap_CONFIG_name ) : format ( L.appName ) ,
[ " desc " ] = ( L.clickmap_CONFIG_desc ) : format ( L.appName ) ,
[ " func " ] = function ( ) ExecAssist : doLoadConfig ( ) end ,
} ,
[ " HELP " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = ( L.clickmap_HELP_name ) : format ( L.appName ) ,
[ " desc " ] = ( L.clickmap_HELP_desc ) : format ( L.appName ) ,
[ " func " ] = function ( ) ExecAssist : doLoadHelp ( ) end ,
} ,
[ " CLICKMAP " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_CLICKMAP_name ,
[ " desc " ] = L.clickmap_CLICKMAP_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadClickMap ( ) end ,
} ,
[ " TACM " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_TACM_name ,
[ " desc " ] = L.clickmap_TACM_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadTaskMaint ( ) end ,
} ,
[ " STYLEMGR " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_STYLEMGR_name ,
[ " desc " ] = L.clickmap_STYLEMGR_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadSyleMgr ( ) end ,
} ,
[ " TOOLTIP CONFIG " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_TOOLTIPCONFIG_name ,
[ " desc " ] = L.clickmap_TOOLTIPCONFIG_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadTooltipConfig ( ) end ,
} ,
[ " TASKWIN CONFIG " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_TASKWINCONFIG_name ,
[ " desc " ] = L.clickmap_TASKWINCONFIG_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadTaskWindow ( ) end ,
} ,
[ " RESET " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_RESET_name ,
[ " desc " ] = L.clickmap_RESET_desc ,
[ " func " ] = function ( ) ExecAssist : doLoadResetOpts ( ) end ,
} ,
[ " reset_Manual " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_reset_Manual_name ,
[ " desc " ] = L.clickmap_reset_Manual_desc ,
[ " func " ] = function ( ) ExecAssist : resetTasks ( nil , nil , true ) end ,
} ,
[ " purgePurgables " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_purgePurgables_name ,
[ " desc " ] = ( L.clickmap_purgePurgables_desc ) : format ( L.appName ) ,
[ " func " ] = function ( ) ExecAssist : resetTasks ( nil , nil , nil , true ) end , -- purge purgables
} ,
[ " ToggleTaskWindow " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_ToggleTaskWindow_name ,
[ " desc " ] = L.clickmap_ToggleTaskWindow_desc ,
[ " func " ] = function ( ) ExecAssist : doToggleTaskWindow ( ) end ,
} ,
[ " ShowDataBrokerTT " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_ShowDataBrokerTT_name ,
[ " desc " ] = L.clickmap_ShowDataBrokerTT_desc ,
[ " func " ] = function ( ) ExecAssist : doShowDataBrokerTooltip ( ) end ,
} ,
[ " ClickMap_Config " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_CLICKMAPconfig_name ,
[ " desc " ] = L.clickmap_CLICKMAPconfig_desc ,
[ " func " ] = function ( ) ExecAssist : configureClickMap ( ) end ,
} ,
[ " ToggleTooltipTips " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_ToggleTooltipTips_name ,
[ " desc " ] = L.clickmap_ToggleTooltipTips_desc ,
[ " func " ] = function ( ) ExecAssist : toggleTooltipTips ( ) end ,
} ,
[ " ToggleShowTWControlButtons " ] = {
[ " code " ] = nil , [ " m " ] = false , [ " s " ] = nil , [ " a " ] = nil , [ " c " ] = nil , [ " notify " ] = true ,
[ " name " ] = L.clickmap_HideTaskWindowControlButtons_name ,
[ " desc " ] = L.clickmap_HideTaskWindowControlButtons_desc ,
[ " func " ] = function ( ) ExecAssist : doToggleShowTWControlButtons ( ) end ,
} ,
} ,
} ,
}
self.db = LibStub ( " AceDB-3.0 " ) : New ( " ExecAssistDB " , self.DBDefaults , true )
-- Prime char vars and charStem
self.userCurrent = UnitName ( " player " ) .. " - " .. GetRealmName ( ) ; self.userConfigDisplay = self.userCurrent
if not self.db . global.charStem [ self.userCurrent ] then self.db . global.charStem [ self.userCurrent ] = { [ " agg " ] = { } } end -- new user, establish agglomeration
debug ( " * Debugging Mode Active * " ) -- dev sanity check
-- Register Options ------------------------------------------------------ --
self : regOptions ( )
-- Commandline ----------------------------------------------------------- --
local cmdLine = {
type = " group " ,
name = " " ,
args = {
config = {
type = " execute " ,
name = " " ,
desc = L.AddonConfiguration ,
func = function ( ) ExecAssist : doLoadConfig ( ) end ,
order = 0
} ,
manage = {
type = " execute " ,
name = " " ,
desc = L.CommandLineHelp_manage ,
func = function ( ) ExecAssist : doLoadTaskMaint ( ) end ,
order = 2
} ,
task = {
type = " execute " ,
name = " " ,
desc = L.CommandLineHelp_task ,
func = function ( ... ) ExecAssist : doAddPurgableTask ( ... ) end ,
order = 3
} ,
mytask = {
type = " execute " ,
name = " " ,
desc = L.CommandLineHelp_mytask ,
func = function ( ... ) ExecAssist : doAddPersonalPurgableTask ( ... ) end ,
order = 4
} ,
setgroup = {
type = " execute " ,
name = " " ,
desc = L.CommandLineHelp_setgroup ,
func = function ( ... ) ExecAssist : doResetTargetGroup ( ... ) end ,
order = 5
} ,
npc = {
type = " execute " ,
name = " " ,
desc = " Create an NPC " ,
func = function ( ... ) ExecAssist : doCreateNPC ( ... ) end ,
order = 6
} ,
debug = {
cmdHidden = true ,
type = " execute " ,
name = " " ,
desc = " Toggles Debug Mode " ,
func = function ( ) ExecAssist : doDebuggingMode ( ) end ,
order = 30
} ,
}
}
LibStub ( " AceConfig-3.0 " ) : RegisterOptionsTable ( L.appName .. " CmdLine " , cmdLine , { " ea " , " exa " } )
-- libDataBroker and DBIcon ---------------------------------------------- --
self.meatPopcicle = self : ldb_ObjectCreate ( )
LibStub ( " LibDBIcon-1.0 " ) : Register ( AddonName , self.meatPopcicle , self.db . char.DBIconTable )
end
function ExecAssist : OnEnable ( )
local sdbg = self.db . global
-- char prime
sdbg.charStem [ self.userCurrent ] . charClass = select ( 2 , UnitClass ( " player " ) ) -- reset each time in case a char is deleted and remade w/ new class and same name
self : mkCharList ( ) -- make Alphabetized Character List
-- ------------------------------------------------------------------------------------------------------------------------------ --
-- taskTypes Loader
self.taskTypes = L.optsTable_base . TaskTypes
-- iterate intern modules --
self.loadedModules = { }
for name , module in self : IterateModules ( ) do -- module:Enable() is implicit
self.loadedModules [ name ] = true
self : clickmapExtend ( name , module : intern_getClickMap ( ) )
self : amalgamExtend ( module : intern_getOptionsPanel ( ) )
self : helpExtend ( module : intern_getExtendedHelp ( ) )
self : taskTypeExtend ( module : intern_getNewTaskTypes ( ) )
end
-- taskTypes OrderedList (post all loaded modules so any extenders are captured)
self.taskTypes_Index = { } ; self.isAvail_taskType = { }
-- stublist keeps consistent order in default internal types
for n = 1 , 7 do table.insert ( self.taskTypes_Index , L.optsTable_base . TaskTypes_stublist [ n ] ) ; self.isAvail_taskType [ L.optsTable_base . TaskTypes_stublist [ n ] ] = true end
for k , v in pairs ( self.taskTypes ) do if not self.isAvail_taskType [ k ] then table.insert ( self.taskTypes_Index , k ) ; self.isAvail_taskType [ k ] = true end end
-- add Missing Module to taskType (must NOT be in Index
self.taskTypes [ L.optsTable_missingmodule_label ] = L.optsTable_missingmodule
-- ------------------------------------------------------------------------------------------------------------------------------ --
-- Load the DB into Options Tables
self : loadGroups_toOptionsTable ( )
-- Check for Resets & set timer
self.timers = { }
self : doResetCheck ( )
-- reset At Login tasks
self : resetTasks ( nil , nil , nil , nil , true )
-- collapse map
self : pushCollapseMap ( )
-- Load the Task Window if needed
local sdbc = self.db . char
if sdbc.useTaskWindow then -- useTaskWindow is always char specific; internal settings may or may not be, thus the getHandle
self : CreateTaskWindow ( )
local twStem = self : getHandle_TaskWindow ( )
if twStem.hideincombat then self : registerCombatEvents ( true ) end -- Register Events
if twStem.useRemembered_toggleState and twStem.toggleState_ToggledOff then
self : doToggleTaskWindow ( true ) -- forceHide=true
else
if twStem.toggleState_ToggledOff then twStem.toggleState_ToggledOff = false end -- If state isn't remembered, _ToggledOff must be false
-- DevNote: should have a rummage and see if .toggleState_ToggledOff has any legacy connections, otherwise
-- if not .useRemembered_toggleState then this shoudln't even be set in the first place.
end
end
-- Update LDB if needed
if sdbg.tooltip . useCounts_onLDB and not self.taskWindow then self : ldb_refreshCounts ( ) end
-- tooltip mode pool
local I = self.icons
self.mode_PGT = sdbg.tooltip . default_GroupDisplayMode_PGT
self.mode_GTP = sdbg.tooltip . default_GroupDisplayMode_GTP
self.modePool = {
[ 1 ] = { [ " b " ] = " ShowGroupNames " , [ " i " ] = self : mkLink ( I.ldb_showGroups , 16 ) , [ " PGT " ] = true ; [ " GTP " ] = false } ,
[ 2 ] = { [ " b " ] = " ShowAllGroups " , [ " i " ] = self : mkLink ( I.ldb_showALLgroups , 16 ) , [ " PGT " ] = true ; [ " GTP " ] = true } ,
[ 3 ] = { [ " b " ] = " ShowOnlySelectedGroup " , [ " i " ] = self : mkLink ( I.ldb_ShowOnlySelectedGroup , 16 ) , [ " PGT " ] = true ; [ " GTP " ] = false } ,
[ 4 ] = { [ " b " ] = " HideGroupNames " , [ " i " ] = self : mkLink ( I.ldb_hideGroups , 16 ) , [ " PGT " ] = true ; [ " GTP " ] = true }
}
-- Brand New User, Setup Initial Tasks and Clickmapping
if not sdbg.IsOldHat then
local groupStem = sdbg.groupStem
local groupID = self : AddGroup ( L.NewUserTasks , groupStem.agg [ " garden " ] )
local hGroup = groupStem.agg [ groupID ]
hGroup.cmdLineTarget = true
groupStem.cmdLineTarget = hGroup.id
local function newTask ( taskName , suppressRefresh_cmdline )
local hTask = self : AddTask ( hGroup , nil , suppressRefresh_cmdline )
hTask.taskName = taskName
hTask.resetType = L.Manual
hTask.isAcctWide = true
end
local hTask = sdbg.groupStem . agg [ hGroup.DO [ 1 ] ]
hTask.taskName = L.BrandNewUserTask_0
hTask.resetType = L.Manual
hTask.isAcctWide = true
newTask ( L.BrandNewUserTask_1 , true )
newTask ( L.BrandNewUserTask_2 , true )
newTask ( L.BrandNewUserTask_3 , true )
newTask ( L.BrandNewUserTask_4 , true )
newTask ( L.BrandNewUserTask_5 , true )
newTask ( L.BrandNewUserTask_6 , true )
newTask ( L.BrandNewUserTask_7 , true )
newTask ( L.BrandNewUserTask_8 , true )
newTask ( L.BrandNewUserTask_9 , true )
newTask ( L.BrandNewUserTask_10 , true )
newTask ( L.BrandNewUserTask_11 , false ) -- initial run has Task Window enabled
-- Update GroupMaintenance var, so new tasks show in the list
self : loadGroups_toOptionsTable ( )
hGroup.cmdLineTarget = false
groupStem.cmdLineTarget = nil
-- inject defaults into the ClickMap
local cm = self.db . global.clickmap
cm [ " CONFIG " ] [ " code " ] = " Lm " ; cm [ " CONFIG " ] [ " m " ] = " LeftButton " ; cm [ " CONFIG " ] [ " notify " ] = false
cm [ " TACM " ] [ " code " ] = " Rm " ; cm [ " TACM " ] [ " m " ] = " RightButton " ; cm [ " TACM " ] [ " notify " ] = false
cm [ " HELP " ] [ " code " ] = " Rms " ; cm [ " HELP " ] [ " m " ] = " RightButton " ; cm [ " HELP " ] [ " s " ] = true ; cm [ " HELP " ] [ " notify " ] = true
cm [ " ClickMap_Config " ] [ " code " ] = " Rmsc " ; cm [ " ClickMap_Config " ] [ " m " ] = " RightButton " ; cm [ " ClickMap_Config " ] [ " s " ] = true ; cm [ " ClickMap_Config " ] [ " c " ] = true ; cm [ " ClickMap_Config " ] [ " notify " ] = true
sdbg.IsOldHat = true
end
-- Init quickTaskEntry
self : quickTaskEntry_SingleTask_Setup ( )
-- establish the ClickMap
self : build_clickmapServiceIndex ( ) -- builds the Service Index (mouse/key combination)
self : build_clickmapOptions ( ) -- builds options dynamically from DBDefaults
end
-- Time and Reset funcs --
function ExecAssist : doResetCheck ( )
local sdbg = self.db . global
-- Timer Trap -------------------------------------------------------------------------- --
if not sdbg.nextMidnightReset then sdbg.nextMidnightReset = self : happyMidnight ( time ( ) ) end
if not sdbg.nextDailyReset then sdbg.nextDailyReset = self : happyDaily ( time ( ) ) end
if not sdbg.nextWeeklyReset then sdbg.nextWeeklyReset = self : happyWeekly ( time ( ) ) end
-- -------------------------------------------------------------------------- Timer Trap --
-- rc > 0 tasks need to be reset
if time ( ) - sdbg.nextMidnightReset > 0 then self : resetTasks ( nil , nil , nil , nil , nil , true , true ) end
if time ( ) - sdbg.nextDailyReset > 0 then self : resetTasks ( true ) end
if time ( ) - sdbg.nextWeeklyReset > 0 then self : resetTasks ( nil , true ) end
-- reset timer to next Resetcheck (cancel then set next-lowest as next doResetCheck (midnight or daily reset time)
local timerResetCheck = self.timers . doResetCheck
if timerResetCheck then self : CancelTimer ( timerResetCheck ) end
timerResetCheck = self : ScheduleTimer ( " doResetCheck " , sdbg.nextMidnightReset < sdbg.nextDailyReset and ( sdbg.nextMidnightReset - time ( ) ) or ( sdbg.nextDailyReset - time ( ) ) )
end
-- normalizing the execution-time makes the comparitor a hard-trigger; wonder if there are n-day resetables worth worrying about -- debug( date("%Y-%m-%d %H:%M:%S", timedateObj) )
function ExecAssist : timeWarp ( oriTime , daysToWarp ) return ( oriTime + ( daysToWarp * 86400 ) ) end -- could have done last+(n*86400) but RHPS
function ExecAssist : happyMidnight ( oriTime , Options_SetExplicitDay )
-- returns midnight of the date given -- returns Midnight Tomorrow (00:00am)
local t
if Options_SetExplicitDay then
t = date ( " *t " , oriTime ) -- exact time
else
t = date ( " *t " , oriTime + 86400 ) -- pushes 24hrs
end
t.hour = 0 -- set happy hour
t.min = 0 -- set happy minute
t.sec = 0 -- set happy seconds
return time ( t )
end
function ExecAssist : happyWeekly ( oriTime ) -- Normalizes a time numeric to the last WeeklyResetDay (perfect comparitor)
local real_weeklyDoW = date ( " *t " , oriTime ) . wday -- find the oriTime day-of-week
local walkbackDays = 0 -- # days that real_ needs to wind back to become perfect_
local WeeklyResetDay = self.db . global.Options . WeeklyResetDay -- get proper weekly reset day
if WeeklyResetDay == real_weeklyDoW then -- today = weekly reset day
walkbackDays = 0
elseif WeeklyResetDay < real_weeklyDoW then
walkbackDays = real_weeklyDoW - WeeklyResetDay -- week has not wrapped
else
walkbackDays = ( 7 - WeeklyResetDay ) + real_weeklyDoW -- week has wrapped
end
-- print( tostring( date("*t", time()).wday ).." - "..tostring(ExecAssist.db.global.Options.WeeklyResetDay) )
-- /script print( date("%c",ExecAssist.db.global.nextWeeklyReset))
-- /script print( date("%c",ExecAssist.db.global.nextDailyReset))
return self : happyTime ( self : timeWarp ( oriTime , ( 7 - walkbackDays ) ) ) -- adjust the requsite # of days, normalize the time of day, then return
end
function ExecAssist : happyDaily ( oriTime ) -- Normalizes a time numeric to the DailyResetTime (perfect comparitor)
if difftime ( time ( ) , self : happyTime ( time ( ) ) ) > 0 then
return self : happyTime ( self : timeWarp ( oriTime , 1 ) )
else
return self : happyTime ( oriTime )
end
end
function ExecAssist : happyTime ( oriTime ) -- Inserts the user selected Reset Time into the time numeric
local s_DailyResetTime = self.optValues . ResetTimesList [ self.db . global.Options . DailyResetTime ]
local t = date ( " *t " , oriTime ) -- get a table of Time numeric, time() needs this table structure to reconstruct a time numeric
t.hour = s_DailyResetTime : sub ( 1 , 2 ) -- set happy hour
t.min = s_DailyResetTime : sub ( 4 ) -- set happy minute
t.sec = 0 -- set happy seconds
return time ( t ) -- return happy time
end
function ExecAssist : resetTasks ( resetDaily , resetWeekly , resetManual , purgePurgables , resetAtLogins , resetReminder , resetCalendar )
local sdbg = self.db . global
local charStem_base = sdbg.charStem
local aggStem = sdbg.groupStem . agg
local self_happyMidnightToday = self : happyMidnight ( time ( ) , true )
local function sendAlerts ( )
if resetDaily then self : alert ( L.resetAlert_resetDaily ) end
if resetWeekly then self : alert ( L.resetAlert_resetWeekly ) end
if resetManual then self : alert ( L.resetAlert_resetManual ) end
if purgePurgables then self : alert ( L.resetAlert_purgePurgables ) end
if resetAtLogins then self : alert ( L.resetAlert_resetAtLogins ) end
if resetReminder then self : alert ( L.resetAlert_resetReminder ) end
if resetCalendar then self : alert ( L.resetAlert_resetCalendar ) end
end
local function reset_ifInScope ( hTask_cS , taskID , charName ) -- cS=charStem
-- This handles PER-CHARACTER .checked field related activities.
-- DATE-RELATED activties (Calender Automatic, Reminder) are handled AFTER
local hTask = aggStem [ taskID ]
-- if not hTask then ExecAssist.db.global.problemchild2 = taskID; return end
if hTask_cS.checked then -- uncheck the .checked
if ( resetDaily and hTask.resetType == L.DailyAutomatic ) or
( resetWeekly and hTask.resetType == L.WeeklyAutomatic ) or
( resetManual and hTask.resetType == L.Manual ) or
( resetAtLogins and hTask.resetType == L.AtEachLogin ) or
( resetReminder and hTask.resetType == L.Reminder ) then -- L.Reminder MIGHT be converted from something else and .checked, better safe than sorry
hTask_cS.checked = nil
elseif purgePurgables and hTask.resetType == L.Purgable then
if hTask.isAcctWide then
-- If Account Wide, we kill it now since we're here b/c for AW, checked = ALL CHECKED
self : DeleteTask ( hTask , aggStem [ hTask.p ] . G ) -- hItem & parent Geneaology for hardPrune()
else
-- Disable for charName (leaving checked in case I ever have to debug an sv file)
hTask_cS.userOverride = 3 -- Disable
hTask_cS.checked = nil -- remove .checked so we don't keep reprocessing it
end
-- -----------------------------------------
elseif resetCalendar and hTask.resetType == L.CalendarAutomatic then
if hTask.resetDate_Next <= self_happyMidnightToday then
hTask_cS.checked = nil
end
-- ------------------------------------------
end
end
end
-- Char Level Scans
for charName , charStem in pairs ( charStem_base ) do -- character-level completes
for itemID , hItem in pairs ( charStem.agg ) do -- agg=agglomeration
if itemID : isTask ( ) then
reset_ifInScope ( hItem , itemID , charName ) -- charStem entries don't carry .id & purged purgables need to find the actual task entry hTask to nix & prune
end
end
end
for itemID , hItem in pairs ( sdbg.acctwideStem . agg ) do -- account-wide completes (always items)
reset_ifInScope ( hItem , itemID )
end
-- Task Level Scans (Date-Related Activities and purgePurgables)
if resetReminder or resetCalendar or purgePurgables then
for itemID , hItem in pairs ( aggStem ) do -- agg=agglomeration
if itemID : isTask ( ) then
if resetReminder and hItem.resetType == L.Reminder then -- Reminder
if hItem.resetDate_Next and hItem.resetDate_Next <= self_happyMidnightToday then hItem.resetType = L.Purgable end
elseif resetCalendar and hItem.resetType == L.CalendarAutomatic then -- Calendar Automatic
if hItem.resetDate_Next and hItem.resetDate_Next <= self_happyMidnightToday then
-- Advance the _Next date to one in the future; then set _Last to 'previous cycle'
local paranoia = 0
while ( hItem.resetDate_Next <= self_happyMidnightToday ) and ( paranoia < 100 ) do
paranoia = paranoia + 1
hItem.resetDate_Next = hItem.resetDate_Next + ( 86400 * hItem.offsetDays )
end
hItem.resetDate_Last = hItem.resetDate_Next - ( 86400 * hItem.offsetDays )
if paranoia >= 100 then self : alert ( L.paranoia_Alert .. hItem.taskName ) end
end
elseif purgePurgables and hItem.resetType == L.Purgable then -- purgePurgables
-- hardCheck for Purgables ------------------------------------------------------------------------------------------------
local purge = true
for i = 1 , # ExecAssist.charList do if self : hasCleanGenes ( ExecAssist.charList [ i ] , itemID ) then purge = false ; break ; end end
if purge then self : DeleteTask ( hItem , aggStem [ hItem.p ] . G ) end -- hItem & parent Geneaology for hardPrune()
-- ------------------------------------------------------------------------------------------------------------------------
end
end
end
end
-- alerts
if ExecAssist.notLoginReset then sendAlerts ( )
else ExecAssist.notLoginReset = true ;
if sdbg.Options . showLoginAlerts then sendAlerts ( ) end
end
-- reset runtimes
if resetDaily then sdbg.nextDailyReset = self : happyDaily ( time ( ) ) end
if resetWeekly then sdbg.nextWeeklyReset = self : happyWeekly ( time ( ) ) end
if resetReminder or resetCalendar then sdbg.nextMidnightReset = self : happyMidnight ( time ( ) ) end
if sdbg.tooltip . useCounts_onLDB then self : ldb_refreshCounts ( ) end
self : UpdateWindow ( )
-- notify Modules of reset
for name , module in self : IterateModules ( ) do
module : intern_resetHandler ( resetDaily , resetWeekly , resetManual , purgePurgables , resetAtLogins , resetReminder , resetCalendar )
end
end
-- Click-Map (active) --
local clickmapServiceIndex = { }
function ExecAssist : get_clickmapService ( cmSvcTag ) return self.db . global.clickmap [ cmSvcTag ] end -- used in building options
function ExecAssist : isBusy_clickmapServiceHandle ( mouse , shift , alt , ctrl )
return clickmapServiceIndex [ self : formatClick ( mouse , shift , alt , ctrl ) ]
end
function ExecAssist : formatClick ( mouse , shift , alt , ctrl ) return ( mouse == " LeftButton " and " Lm " or " Rm " ) .. ( shift and " s " or " " ) .. ( alt and " a " or " " ) .. ( ctrl and " c " or " " ) end
function ExecAssist : build_clickmapServiceIndex ( )
local cmStem = self.db . global.clickmap
clickmapServiceIndex = { }
for cmSvcTag , SvcOpts in pairs ( cmStem ) do
if SvcOpts.m then -- m=add since all click kinda need a mouse
clickmapServiceIndex [ self : formatClick ( SvcOpts.m , SvcOpts.s , SvcOpts.a , SvcOpts.c ) ] = cmSvcTag
end
end
end
function ExecAssist : ldbClickMap ( mouse , shift , alt , ctrl )
local userRequestedAction
local clickmapService = clickmapServiceIndex [ self : formatClick ( mouse , shift , alt , ctrl ) ]
local cm = self.db . global.clickmap
if clickmapService then
userRequestedAction = cm [ clickmapService ]
if userRequestedAction.func then -- if .func=nil then Service is provided by an Intern or otherwise unloaded module/addon as .func is not saved into the savedvar file.
if cm [ clickmapService ] . notify then self : alert ( L.cm_running .. userRequestedAction.name ) end
userRequestedAction.func ( )
end
end
end
-- simple actions
function ExecAssist : doDebuggingMode ( ) ExecAssist.db . sv.debug = not ExecAssist.db . sv.debug ; ReloadUI ( ) end
function ExecAssist : doUpdateStatusField ( subSectionName , isCore )
self.Dialog . OpenFrames [ self.opts . f_reg ] : SetStatusText (
( L.statusText ) : cf ( " cream " ) : format (
L.StatusField_appName : cf ( " EAtan " , " cream " ) ,
GetAddOnMetadata ( AddonName , ' Version ' ) : cf ( " grass " , " cream " ) ,
L.authorName : cf ( " EAtan " ) ,
( isCore and ( " Page " ) : cf ( " cyan " , " white " ) or ( " Module " ) : cf ( " fuglyYellow " , " white " ) ) ,
subSectionName : cf ( " grass " , " cream " )
)
)
end
function ExecAssist : doResetScale ( )
local dlg = self.aceDlg
if dlg then
dlg.frame : SetScale ( dlg.scale )
self : Unhook ( dlg.frame , " OnHide " )
self.aceDlg = nil
end
end
function ExecAssist : doOpenConfigWindow ( pathTable )
PlaySound ( SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON )
self.Dialog : Open ( self.opts . f_reg )
-- Ace window scale is 1.0 with no methods to change it; however, you never know when someone's done a universal upscale so...
if not self.aceDlg then
self.aceDlg = { [ " frame " ] = self.Dialog . OpenFrames [ self.opts . f_reg ] . frame }
local dlg = self.aceDlg ; dlg.scale = self.aceDlg . frame : GetScale ( )
dlg.frame : SetScale ( self.db . global.Options . configConfig.scale )
-- Only one hook is needed and many ':doOpenConfigWindow()' calls may be made using diffent ldb click actions before a window close
if not self : IsHooked ( dlg.frame , " OnHide " ) then self : HookScript ( dlg.frame , " OnHide " , " doResetScale " ) end -- :IsHooked() should always be nil; but paranoia rules the day
-- ---------------------------------------------------------------------------------------------------------------------------
end
if type ( pathTable ) == " string " then
self.Dialog : SelectGroup ( self.opts . f_reg , pathTable )
else
self.Dialog : SelectGroup ( self.opts . f_reg , unpack ( pathTable ) ) ; -- table.unpack() is nil but unpack() is a thing...
end
end
function ExecAssist : doLoadConfig ( ) self : doOpenConfigWindow ( self.opts . f_MainOpts ) end
function ExecAssist : doLoadHelp ( subPage , subSubPage ) self : doOpenConfigWindow ( { self.opts . f_Help , subPage , subSubPage } ) end
function ExecAssist : doLoadClickMap ( ) self : doOpenConfigWindow ( self.opts . f_ClickMap ) end
function ExecAssist : doLoadSyleMgr ( ) self : doOpenConfigWindow ( self.opts . f_StyleMgr ) end
function ExecAssist : doLoadTaskMaint ( ) self : doOpenConfigWindow ( self.opts . f_TaskMaint ) end
function ExecAssist : doLoadTooltipConfig ( ) self : doOpenConfigWindow ( self.opts . f_ToolTip ) end
function ExecAssist : doLoadTaskWindow ( ) self : doOpenConfigWindow ( self.opts . f_TaskWindow ) end
-- self.opts.f_CmdLine Intentionally Left Blank (not in clickmap and no reason it should be)
function ExecAssist : doLoadResetOpts ( ) self : doOpenConfigWindow ( self.opts . f_ResetOpts ) end
function ExecAssist : doToggleShowTWControlButtons ( )
local twStem = self : getHandle_TaskWindow ( )
twStem.hidebuttons = not twStem.hidebuttons
self : UpdateWindow ( )
end
function ExecAssist : doToggleTaskWindow ( forceHide )
local sdbc = self.db . char
if sdbc.useTaskWindow or forceHide then -- forceHide only comes from Options toggle OFF
if self.taskWindow : IsShown ( ) or forceHide then
self.taskWindow : Hide ( )
self.taskWindow_posAnchor : Hide ( )
self.taskWindow_dragFrame : Hide ( )
self : getHandle_TaskWindow ( ) . toggleState_ToggledOff = true
else
local twStem = self : getHandle_TaskWindow ( )
self.taskWindow_posAnchor : Show ( )
self.taskWindow : Show ( )
if not twStem.locked and twStem.useDragFrame then self.taskWindow_dragFrame : Show ( ) end
twStem.toggleState_ToggledOff = false
end
else
self : alert ( L.TaskWindowNotEnabled , 1 , .1 , .1 )
end
end
function ExecAssist : doShowDataBrokerTooltip ( )
self : displayTooltip ( self.h_meatPopcicle , true )
end
function ExecAssist : toggleTooltipTips ( ) local ttStem = self.db . global.tooltip ; ttStem.enableTooltipTooltips = not ttStem.enableTooltipTooltips end
-- libDataBroker create func
function ExecAssist : ldb_ObjectCreate ( )
local tmpBackdrop , safeBackdrop = { } -- tooltip style handling
local ttsStem = ExecAssist.db . global.tooltip . tooltipStyle
return LibStub ( " LibDataBroker-1.1 " ) : NewDataObject ( AddonName , {
type = ' data source ' ,
label = self.db . global.Options . ldbLabel , -- L.appName
text = " " ,
icon = self.icons [ ExecAssist.db . global.Options . ldbIcon ] ,
-- can have EITHER OnTooltipShow OR OnEnter, not both --> OnTooltipShow = function(tooltip) end
OnEnter = function ( self )
if ttsStem.useStyle then
safeBackdrop = GameTooltip : GetBackdrop ( )
tmpBackdrop.bgFile = AceGUIWidgetLSMlists.background [ ttsStem.bgFile ]
tmpBackdrop.edgeFile = AceGUIWidgetLSMlists.border [ ttsStem.edgeFile ]
tmpBackdrop.edgeSize = ttsStem.edgeSize
tmpBackdrop.insets = { left = ttsStem.insets , right = ttsStem.insets , top = ttsStem.insets , bottom = ttsStem.insets }
GameTooltip : SetBackdrop ( tmpBackdrop )
GameTooltip : SetBackdropBorderColor ( ttsStem.bdrcolor . r , ttsStem.bdrcolor . g , ttsStem.bdrcolor . b , ttsStem.bdrcolor . a )
end
ExecAssist : displayTooltip ( self )
end , -- self in this context is the ldbObject
OnLeave = function ( self )
-- Restore Border
if ttsStem.useStyle then
GameTooltip : SetBackdrop ( safeBackdrop )
GameTooltip : SetBackdropBorderColor ( TOOLTIP_DEFAULT_COLOR.r , TOOLTIP_DEFAULT_COLOR.g , TOOLTIP_DEFAULT_COLOR.b ) ;
GameTooltip : SetBackdropColor ( TOOLTIP_DEFAULT_BACKGROUND_COLOR.r , TOOLTIP_DEFAULT_BACKGROUND_COLOR.g , TOOLTIP_DEFAULT_BACKGROUND_COLOR.b ) ;
end
end ,
OnClick = function ( self , button ) ExecAssist.h_meatPopcicle = self ; ExecAssist : ldbClickMap ( button , IsShiftKeyDown ( ) , IsAltKeyDown ( ) , IsControlKeyDown ( ) ) end ,
} )
end
-- Task Window Related Combat Events
function ExecAssist : registerCombatEvents ( combatEventsEnabled )
if combatEventsEnabled then
self : Register ( " PLAYER_REGEN_DISABLED " , " EVENT_combatStart " )
self : Register ( " PLAYER_REGEN_ENABLED " , " EVENT_combatEnd " )
else
self : Unregister ( " PLAYER_REGEN_DISABLED " )
self : Unregister ( " PLAYER_REGEN_ENABLED " )
end
end
function ExecAssist : EVENT_combatStart ( ) if self.taskWindow then self.taskWindow : Hide ( ) end end
function ExecAssist : EVENT_combatEnd ( ) if self.taskWindow then self.taskWindow : Show ( ) end end
-- purgatorium
function ExecAssist : getFreshTaskStem ( )
local groupStem = self.db . global.groupStem
if groupStem.cmdLineTarget ~= nil then
if groupStem.agg [ groupStem.cmdLineTarget ] then
local hTask = ExecAssist : AddTask ( groupStem.cmdLineTarget , nil , true )
return hTask
else
self : alert ( L.cm_unableToFindGroup )
end
else
self : alert ( L.cm_NoTagetSelected )
end
end
local function getArgTable ( data )
local data , argT , sendTo = data : trim ( ) , { }
local validArgs = {
[ " + " ] = {
[ " +aw " ] = true ,
[ " +daily " ] = L.DailyAutomatic ,
[ " +weekly " ] = L.WeeklyAutomatic ,
[ " +manual " ] = L.Manual ,
[ " +calendar " ] = L.CalendarAutomatic ,
[ " +reminder " ] = L.Reminder ,
[ " +login " ] = L.AtEachLogin
-- Module Injected Keys...
-- Precise Control Name is already added into the Task Types list; would only need a diminutive key (+<...>)
-- The /help/ for it would be the problem, getting it to display in an /ea list. That would mean extending
-- the Localized text (annotating it in fact) Maybe hold off on this...see if there's really a call for it first.
} ,
[ " > " ] = true
}
local function getNextArg ( data )
local nextArg , validArg
local f = data : find ( " " )
if f then
nextArg = data : sub ( 1 , f - 1 )
data = data : sub ( f + 1 ) : trim ( )
validArg = true
else
nextArg = data
data = " "
validArg = true
end
return nextArg , data , validArg -- if abort, nextArg is invalid arg
end
local validArg = true
while validArg and # data > 2 and validArgs [ data : sub ( 1 , 1 ) ] do -- smallest possible arg = 3 (+aw)
local nextArg
nextArg , data , validArg = getNextArg ( data )
if validArg then
if nextArg : sub ( 1 , 1 ) == " > " then
local charStem_base = ExecAssist.db . global.charStem
nextArg = nextArg : sub ( 2 ) : lower ( )
local CCL = ExecAssist.compressed_charList -- for partial matches
local bits
for comp_charName , charName in pairs ( CCL ) do
bits = comp_charName : sub ( 1 , nextArg : len ( ) ) : lower ( )
if nextArg == bits then
if not sendTo then
sendTo = charName
else -- collision
sendTo = nil
ExecAssist : alert ( " [ " .. nextArg .. " ] was not sufficiently unique, unable to establish character name. " )
break ;
end
end
end
if not sendTo then
ExecAssist : alert ( " Unable to find Character " .. nextArg ) ; validArg = nil ;
break ;
end
else
if validArgs [ " + " ] [ nextArg ] then
if nextArg == " +aw " then
argT [ " isAcctWide " ] = true
elseif validArgs [ " + " ] [ nextArg ] then -- cheat to check for 3x at once
argT [ " resetType " ] = validArgs [ " + " ] [ nextArg ]
end
else
ExecAssist : alert ( " Unrecognized argument: " .. nextArg ) ; validArg = nil
end
end
else
ExecAssist : alert ( " Unrecognized argument: " .. nextArg ) ; validArg = nil
end
end
return argT , sendTo , data , validArg
end
local function mkTaskExclusive ( hTask , charName )
hTask.defaultEnabled = false
local charStem = ExecAssist.db . global.charStem [ charName ]
if not charStem.agg [ hTask.id ] then charStem.agg [ hTask.id ] = { } end
charStem.agg [ hTask.id ] . userOverride = 2
if ExecAssist : isCharIgnored ( charName , charStem ) then
ExecAssist : alert ( " Nota Bene: [ " .. charName .. " ] is flagged 'Ignore Character' and Task will not be usable " , 1 , 1 , 0 )
end
end
function ExecAssist : doAddPurgableTask ( aceTable , forceCurrentChar )
local data = aceTable.input : sub ( 6 ) : trim ( )
local argT , sendTo , taskName , validArg = getArgTable ( data )
local groupStem = self.db . global.groupStem
if validArg then
local hTask = ExecAssist : getFreshTaskStem ( )
if hTask then
if taskName ~= " " then hTask.taskName = taskName : gsub ( " // " , " | " ) end -- if no name, it will be default
hTask.resetType = true and argT [ " resetType " ] or L.Purgable
hTask.isAcctWide = argT [ " isAcctWide " ]
if sendTo or forceCurrentChar then mkTaskExclusive ( hTask , forceCurrentChar and self.userCurrent or sendTo ) end
-- adds default dates and computes default offsets, otherwise the resetter function will have nils-to-numbers headaches
if hTask.resetType == L.Reminder or hTask.resetType == L.CalendarAutomatic then self : primeDateBased_TaskTypes ( hTask ) end
self : semiSmart_regrow ( groupStem.agg [ groupStem.cmdLineTarget ] . G ) -- add to options table
self : UpdateWindow ( ) -- since refresh was suppressed in :AddTask()
self : alert ( ( ( forceCurrentChar and L.personal .. " " or " " ) .. L.taskCreated ) : format ( ( true and ( ( taskName ~= nil and taskName ~= " " ) and taskName or nil ) or L.DefaultTaskName ) : cf ( " EAtan " ) ) )
end
end -- msg already delivered
end
function ExecAssist : doAddPersonalPurgableTask ( aceTable )
-- easy redirector to make default->sendTo items for the current user
aceTable.input = aceTable.input : sub ( 2 ) -- doAdd assumes 6chr of task input
self : doAddPurgableTask ( aceTable , true )
end
function ExecAssist : reset_CmdLineTarget ( hGroup , mayNotBeNil )
local groupStem = self.db . global.groupStem
if hGroup.id == groupStem.cmdLineTarget then
if not mayNotBeNil then -- mayNotBeNil is passed by command line reset ops to keep to user from accidentally unsetting a target
groupStem.cmdLineTarget = nil
hGroup.cmdLineTarget = false
end
else
if groupStem.cmdLineTarget then
groupStem.agg [ groupStem.cmdLineTarget ] . cmdLineTarget = false -- tell old target they can take the night off
end
hGroup.cmdLineTarget = true -- new sherrif in town
groupStem.cmdLineTarget = hGroup.id -- making it official
end
return groupStem.cmdLineTarget
end
function ExecAssist : doResetTargetGroup ( aceTable )
local groupName = aceTable.input : sub ( 10 ) : trim ( )
local groupName_lower = groupName : lower ( )
local groupStem = self.db . global.groupStem
for elementID , hElement in pairs ( groupStem.agg ) do
if elementID : isGroup ( ) and hElement.listName : lower ( ) == groupName_lower then
if self : reset_CmdLineTarget ( hElement , true ) then
self : alert ( ( L.cmdlinetargetsetto ) : format ( hElement.listName : cf ( " EAtan " ) ) )
end
return
end
end
self : alert ( ( L.unabletofindgroup ) : format ( ( groupName ) : cf ( " EAtan " ) ) )
end
function ExecAssist : doCreateNPC ( aceTable )
local charStem = self.db . global.charStem
local npcName = aceTable.input : sub ( 4 ) : trim ( )
if npcName == " " then
self : alert ( L.NPC_NoNameEntered : cf ( " hard_red " ) )
else
if charStem [ npcName ] then
-- self:alert( (L.unabletofindgroup):format((groupName):cf("EAtan")))
self : alert ( L.NPC_openTag : cf ( " hard_red " ) .. npcName : cf ( " white " ) .. L.NPC_closingTag_Exists : cf ( " hard_red " ) )
else
charStem [ npcName ] = { [ " agg " ] = { } }
self : mkCharList ( ) -- sort
self : alert ( L.NPC_openTag : cf ( " hard_green " ) .. npcName : cf ( " white " ) .. L.NPC_closingTag_Created : cf ( " hard_green " ) )
end
end
end