|
andrewtknoll@33
|
1 --- **LibModuleDBShare-1.0** provides a shared profile manager for addons without a central core.
|
|
andrewtknoll@33
|
2 -- A basic options panel for the group is added to the Blizzard options panel, as well as a
|
|
andrewtknoll@33
|
3 -- standard profile manager as a subpanel. Changes through the profiles panel are propagated
|
|
andrewtknoll@33
|
4 -- to member databases. The root panel can be used as a parent for your module config panels,
|
|
andrewtknoll@33
|
5 -- to keep all your addon's config in one place. The root panel's name is the same as the group's
|
|
andrewtknoll@33
|
6 -- name.\\
|
|
andrewtknoll@33
|
7 -- \\
|
|
andrewtknoll@35
|
8 -- A group can be created using the ':NewGroup' library method. The returned object inherits all
|
|
andrewtknoll@35
|
9 -- methods of the DBGroup object described below.\\
|
|
andrewtknoll@33
|
10 -- \\
|
|
andrewtknoll@33
|
11 -- **LibDualSpec Support**\\
|
|
andrewtknoll@33
|
12 -- LibModuleDBShare can use LibDualSpec to manage automatic profile switching with talent spec
|
|
andrewtknoll@33
|
13 -- changes. This integration is handled by the library; there is no need to use LibDualSpec
|
|
andrewtknoll@40
|
14 -- on member databases directly.\\
|
|
andrewtknoll@40
|
15 -- \\
|
|
andrewtknoll@40
|
16 -- **Slash Command Support**\\
|
|
andrewtknoll@40
|
17 -- LibModuleDBShare can associate a slash command with a DBGroup. The default handler function
|
|
andrewtknoll@40
|
18 -- for the slash command opens the root options panel.\\
|
|
andrewtknoll@40
|
19 -- Additional handler functions can be registered to respond to specific arguments given to the
|
|
andrewtknoll@44
|
20 -- slash command. If you provide a custom handler function for the slash command, that function
|
|
andrewtknoll@44
|
21 -- is responsible for detecting secondary commands.
|
|
>@5
|
22 --
|
|
>@5
|
23 -- @usage
|
|
andrewtknoll@33
|
24 -- local database;
|
|
andrewtknoll@33
|
25 -- -- this function is called after the ADDON_LOADED event fires
|
|
andrewtknoll@33
|
26 -- function initializeDB()
|
|
andrewtknoll@33
|
27 -- database = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true);
|
|
andrewtknoll@33
|
28 -- local group = LibStub("LibModuleDBShare-1.0"):GetGroup("Group Name");
|
|
andrewtknoll@33
|
29 -- if not group then
|
|
andrewtknoll@33
|
30 -- group = LibStub("LibModuleDBShare-1.0"):NewGroup("Group Name", "A description for this group.", database);
|
|
andrewtknoll@33
|
31 -- else
|
|
andrewtknoll@33
|
32 -- group:AddDB(database);
|
|
andrewtknoll@33
|
33 -- end
|
|
andrewtknoll@40
|
34 -- -- if you want to add a slash command
|
|
andrewtknoll@40
|
35 -- if not group:HasSlashCommand() then
|
|
andrewtknoll@40
|
36 -- group:EnableSlashCommand("COMMAND_NAME", "/groupname");
|
|
andrewtknoll@40
|
37 -- end
|
|
andrewtknoll@33
|
38 -- end
|
|
>@5
|
39 -- @class file
|
|
andrewtknoll@33
|
40 -- @name LibModuleDBShare-1.0
|
|
andrewtknoll@39
|
41 local MAJOR, MINOR = "LibModuleDBShare-1.0", 5
|
|
>@3
|
42 local LibModuleDBShare, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
|
>@3
|
43
|
|
>@4
|
44 if not LibModuleDBShare then return end -- No upgrade needed
|
|
>@4
|
45
|
|
andrewtknoll@29
|
46 -- Lua functions
|
|
andrewtknoll@26
|
47 local error, type, pairs, time = error, type, pairs, time;
|
|
andrewtknoll@15
|
48
|
|
andrewtknoll@17
|
49 -- Required Libraries
|
|
@12
|
50 local AceDB = LibStub("AceDB-3.0");
|
|
andrewtknoll@17
|
51 local AceDBOptions = LibStub("AceDBOptions-3.0");
|
|
andrewtknoll@17
|
52 local AceConfigRegistry = LibStub("AceConfigRegistry-3.0");
|
|
andrewtknoll@17
|
53 local AceConfigDialog = LibStub("AceConfigDialog-3.0");
|
|
@12
|
54
|
|
andrewtknoll@28
|
55 -- Optional Libraries
|
|
andrewtknoll@28
|
56 local LibDualSpec = LibStub("LibDualSpec-1.0", true);
|
|
andrewtknoll@28
|
57
|
|
>@4
|
58 LibModuleDBShare.groups = LibModuleDBShare.groups or {};
|
|
>@4
|
59
|
|
>@5
|
60 local DBGroup = {};
|
|
>@5
|
61
|
|
>@5
|
62 --- Creates a new DB group.
|
|
andrewtknoll@42
|
63 -- @paramsig groupName, groupDescription, initialDB[, usesDualSpec]
|
|
andrewtknoll@40
|
64 -- @param groupName The name of the new DB group, as shown in the options panel. (string)
|
|
andrewtknoll@40
|
65 -- @param groupDescription A description of the group to be shown in the root options panel. (string)
|
|
andrewtknoll@40
|
66 -- @param initialDB The first DB to add to the group. (table)
|
|
andrewtknoll@40
|
67 -- @param usesDualSpec True if this group should use LibDualSpec, false otherwise. (boolean or nil)
|
|
andrewtknoll@44
|
68 -- @return the new DB group object (table)
|
|
andrewtknoll@21
|
69 function LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec)
|
|
andrewtknoll@35
|
70 -- check to see if LibDualSpec has been loaded
|
|
andrewtknoll@35
|
71 if not LibDualSpec then
|
|
andrewtknoll@35
|
72 LibDualSpec = LibStub("LibDualSpec-1.0", true);
|
|
andrewtknoll@35
|
73 end
|
|
andrewtknoll@21
|
74 -- verify parameters
|
|
andrewtknoll@26
|
75 if type(groupName) ~= "string" then
|
|
andrewtknoll@26
|
76 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupName' must be a string.", 2);
|
|
andrewtknoll@26
|
77 elseif type(groupDescription) ~= "string" then
|
|
andrewtknoll@26
|
78 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupDescription' must be a string.", 2);
|
|
andrewtknoll@26
|
79 elseif type(LibModuleDBShare.groups[groupName]) ~= "nil" then
|
|
andrewtknoll@31
|
80 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): group '"..groupName.."' already exists.", 2);
|
|
andrewtknoll@27
|
81 elseif type(initialDB) ~= "table" or not AceDB.db_registry[initialDB] then
|
|
andrewtknoll@31
|
82 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'initialDB' must be an AceDB-3.0 database.", 2);
|
|
andrewtknoll@31
|
83 elseif initialDB.parent then
|
|
andrewtknoll@31
|
84 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'initialDB' must not be a namespace.", 2)
|
|
andrewtknoll@28
|
85 elseif type(usesDualSpec) ~= "boolean" and type(usesDualSpec) ~= "nil" then
|
|
andrewtknoll@31
|
86 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'usesDualSpec' must be a boolean or nil.", 2);
|
|
andrewtknoll@28
|
87 elseif usesDualSpec and not LibDualSpec then
|
|
andrewtknoll@31
|
88 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'usesDualSpec' cannot be true without LibDualSpec-1.0 installed.", 2);
|
|
andrewtknoll@26
|
89 end
|
|
andrewtknoll@21
|
90 -- create group
|
|
@12
|
91 local group = {}
|
|
@12
|
92 group.name = groupName;
|
|
andrewtknoll@21
|
93 group.members = {};
|
|
andrewtknoll@21
|
94 -- create root option panel for group
|
|
andrewtknoll@17
|
95 group.rootOptionsTable = {
|
|
andrewtknoll@17
|
96 type = "group",
|
|
andrewtknoll@17
|
97 name = groupName,
|
|
andrewtknoll@17
|
98 args = {
|
|
andrewtknoll@17
|
99 text = {
|
|
andrewtknoll@17
|
100 type = "description",
|
|
andrewtknoll@21
|
101 name = groupDescription,
|
|
andrewtknoll@17
|
102 },
|
|
andrewtknoll@17
|
103 },
|
|
andrewtknoll@17
|
104 };
|
|
andrewtknoll@17
|
105 AceConfigRegistry:RegisterOptionsTable(groupName, group.rootOptionsTable);
|
|
andrewtknoll@17
|
106 AceConfigDialog:AddToBlizOptions(groupName);
|
|
andrewtknoll@21
|
107 -- create sync DB and profile options page
|
|
@12
|
108 group.syncDBTable = {};
|
|
andrewtknoll@21
|
109 group.syncDB = AceDB:New(group.syncDBTable, nil, initialDB:GetCurrentProfile());
|
|
andrewtknoll@17
|
110 group.profileOptionsTable = AceDBOptions:GetOptionsTable(group.syncDB, false);
|
|
andrewtknoll@28
|
111 if usesDualSpec then
|
|
andrewtknoll@29
|
112 group.usesDualSpec = true;
|
|
andrewtknoll@28
|
113 LibDualSpec:EnhanceDatabase(group.syncDB, groupName);
|
|
andrewtknoll@28
|
114 LibDualSpec:EnhanceOptions(group.profileOptionsTable, group.syncDB);
|
|
andrewtknoll@29
|
115 else
|
|
andrewtknoll@29
|
116 group.usesDualSpec = false;
|
|
andrewtknoll@28
|
117 end
|
|
andrewtknoll@17
|
118 AceConfigRegistry:RegisterOptionsTable(groupName.."Profiles", group.profileOptionsTable);
|
|
andrewtknoll@18
|
119 AceConfigDialog:AddToBlizOptions(groupName.."Profiles", group.profileOptionsTable.name, groupName);
|
|
andrewtknoll@21
|
120 -- add all profiles from initialDB to syncDB
|
|
andrewtknoll@21
|
121 for i, profile in pairs(initialDB:GetProfiles()) do
|
|
andrewtknoll@21
|
122 group.syncDB:SetProfile(profile);
|
|
andrewtknoll@21
|
123 end
|
|
andrewtknoll@28
|
124 -- load profile info from initialDB
|
|
andrewtknoll@21
|
125 group.syncDB:SetProfile(initialDB:GetCurrentProfile());
|
|
andrewtknoll@27
|
126 group.members[initialDB] = initialDB:GetNamespace(MAJOR, true) or initialDB:RegisterNamespace(MAJOR);
|
|
andrewtknoll@29
|
127 local storedData = group.members[initialDB].char;
|
|
andrewtknoll@29
|
128 if type(storedData.logoutTimestamp) == "number" then
|
|
andrewtknoll@29
|
129 group.profileTimestamp = storedData.logoutTimestamp;
|
|
andrewtknoll@22
|
130 else
|
|
andrewtknoll@22
|
131 group.profileTimestamp = 0;
|
|
andrewtknoll@22
|
132 end
|
|
andrewtknoll@35
|
133 if usesDualSpec then
|
|
andrewtknoll@35
|
134 local LDSnamespace = group.syncDB:GetNamespace("LibDualSpec-1.0");
|
|
andrewtknoll@35
|
135 LDSnamespace.char.enabled = storedData.dualSpecEnabled;
|
|
andrewtknoll@35
|
136 LDSnamespace.char.profile = storedData.altProfile;
|
|
andrewtknoll@35
|
137 LDSnamespace.char.specGroup = storedData.activeSpecGroup;
|
|
andrewtknoll@30
|
138 group.syncDB:CheckDualSpecState();
|
|
andrewtknoll@35
|
139 else
|
|
andrewtknoll@35
|
140 group.syncDB.char.enabled = storedData.dualSpecEnabled;
|
|
andrewtknoll@35
|
141 group.syncDB.char.profile = storedData.altProfile;
|
|
andrewtknoll@35
|
142 group.syncDB.char.specGroup = storedData.activeSpecGroup;
|
|
andrewtknoll@28
|
143 end
|
|
andrewtknoll@21
|
144 -- add methods and callbacks
|
|
@12
|
145 for k, v in pairs(DBGroup) do
|
|
@12
|
146 group[k] = v;
|
|
@12
|
147 end
|
|
andrewtknoll@19
|
148 group.syncDB.RegisterCallback(group, "OnProfileChanged", "OnProfileChanged");
|
|
andrewtknoll@19
|
149 group.syncDB.RegisterCallback(group, "OnProfileDeleted", "OnProfileDeleted");
|
|
andrewtknoll@19
|
150 group.syncDB.RegisterCallback(group, "OnProfileCopied", "OnProfileCopied");
|
|
andrewtknoll@19
|
151 group.syncDB.RegisterCallback(group, "OnProfileReset", "OnProfileReset");
|
|
andrewtknoll@28
|
152 group.syncDB.RegisterCallback(group, "OnDatabaseShutdown", "OnSyncShutdown");
|
|
andrewtknoll@41
|
153 group.members[initialDB].RegisterCallback(group, "OnDatabaseShutdown", "OnMemberShutdown"); -- register the namespace, not the base db
|
|
andrewtknoll@20
|
154 group.squelchCallbacks = false;
|
|
andrewtknoll@19
|
155 LibModuleDBShare.groups[groupName] = group;
|
|
@12
|
156 return group;
|
|
>@4
|
157 end
|
|
>@4
|
158
|
|
>@5
|
159 --- Retrieves an existing DB group.
|
|
andrewtknoll@40
|
160 -- @param groupName The name of the DB group to retrieve. (string)
|
|
andrewtknoll@44
|
161 -- @return the DB group object, or ##nil## if not found (table)
|
|
>@5
|
162 function LibModuleDBShare:GetGroup(groupName)
|
|
andrewtknoll@27
|
163 if type(groupName) ~= "string" then
|
|
andrewtknoll@27
|
164 error("Usage: LibModuleDBShare:GetGroup(groupName): 'groupName' must be a string.", 2);
|
|
andrewtknoll@27
|
165 end
|
|
@12
|
166 return LibModuleDBShare.groups[groupName];
|
|
>@4
|
167 end
|
|
>@5
|
168
|
|
>@5
|
169 --- Adds a database to the group.
|
|
andrewtknoll@40
|
170 -- @param newDB The database to add. (table)
|
|
andrewtknoll@22
|
171 function DBGroup:AddDB(newDB)
|
|
andrewtknoll@22
|
172 -- verify parameters
|
|
andrewtknoll@26
|
173 if type(newDB) ~= "table" or not AceDB.db_registry[newDB] then
|
|
andrewtknoll@31
|
174 error("Usage: DBGroup:AddDB(newDB): 'newDB' must be an AceDB-3.0 database.", 2);
|
|
andrewtknoll@31
|
175 elseif newDB.parent then
|
|
andrewtknoll@31
|
176 error("Usage: DBGroup:AddDB(newDB): 'newDB' must not be a namespace.", 2)
|
|
andrewtknoll@26
|
177 elseif type(self.members[newDB]) ~= "nil" then
|
|
andrewtknoll@31
|
178 error("Usage: DBGroup:AddDB(newDB): 'newDB' is already a member of DBGroup.", 2);
|
|
andrewtknoll@31
|
179 end
|
|
andrewtknoll@31
|
180 for groupName, group in pairs(LibModuleDBShare.groups) do
|
|
andrewtknoll@31
|
181 if group.members[newDB] ~= nil then
|
|
andrewtknoll@31
|
182 error("Usage: DBGroup:AddDB(newDB): 'newDB' is already a member of group '"..groupName.."'.", 2);
|
|
andrewtknoll@31
|
183 end
|
|
andrewtknoll@26
|
184 end
|
|
andrewtknoll@22
|
185 -- record current profile
|
|
andrewtknoll@20
|
186 local syncProfile = self.syncDB:GetCurrentProfile();
|
|
andrewtknoll@22
|
187 -- add new profiles to syncDB
|
|
andrewtknoll@20
|
188 self.squelchCallbacks = true;
|
|
andrewtknoll@22
|
189 for i, profile in pairs(newDB:GetProfiles()) do
|
|
andrewtknoll@20
|
190 self.syncDB:SetProfile(profile);
|
|
andrewtknoll@20
|
191 end
|
|
andrewtknoll@22
|
192 -- set current profile based on timestamps
|
|
andrewtknoll@27
|
193 local namespace = newDB:GetNamespace(MAJOR, true) or newDB:RegisterNamespace(MAJOR);
|
|
andrewtknoll@29
|
194 local storedData = namespace.char;
|
|
andrewtknoll@29
|
195 if type(storedData.logoutTimestamp) == "number" and storedData.logoutTimestamp > self.profileTimestamp then
|
|
andrewtknoll@22
|
196 self.squelchCallbacks = false;
|
|
andrewtknoll@22
|
197 self.syncDB:SetProfile(newDB:GetCurrentProfile());
|
|
andrewtknoll@29
|
198 self.profileTimestamp = storedData.logoutTimestamp;
|
|
andrewtknoll@35
|
199 if self.usesDualSpec and storedData.altProfile then
|
|
andrewtknoll@35
|
200 local LDSnamespace = group.syncDB:GetNamespace("LibDualSpec-1.0");
|
|
andrewtknoll@35
|
201 LDSnamespace.char.enabled = storedData.dualSpecEnabled;
|
|
andrewtknoll@35
|
202 LDSnamespace.char.profile = storedData.altProfile;
|
|
andrewtknoll@35
|
203 LDSnamespace.char.specGroup = storedData.activeSpecGroup;
|
|
andrewtknoll@30
|
204 group.syncDB:CheckDualSpecState();
|
|
andrewtknoll@35
|
205 elseif storedData.altProfile then
|
|
andrewtknoll@35
|
206 self.syncDB.char.enabled = storedData.dualSpecEnabled;
|
|
andrewtknoll@35
|
207 self.syncDB.char.profile = storedData.altProfile;
|
|
andrewtknoll@35
|
208 self.syncDB.char.specGroup = storedData.activeSpecGroup;
|
|
andrewtknoll@28
|
209 end
|
|
andrewtknoll@20
|
210 else
|
|
andrewtknoll@20
|
211 self.syncDB:SetProfile(syncProfile);
|
|
andrewtknoll@22
|
212 newDB:SetProfile(syncProfile);
|
|
andrewtknoll@22
|
213 self.squelchCallbacks = false;
|
|
andrewtknoll@20
|
214 end
|
|
andrewtknoll@22
|
215 -- add to members list
|
|
andrewtknoll@27
|
216 self.members[newDB] = namespace;
|
|
andrewtknoll@41
|
217 namespace.RegisterCallback(self, "OnDatabaseShutdown", "OnMemberShutdown"); -- register the namespace, not the base db
|
|
>@5
|
218 end
|
|
andrewtknoll@18
|
219
|
|
andrewtknoll@39
|
220 -- LibDualSpec support
|
|
andrewtknoll@39
|
221
|
|
andrewtknoll@35
|
222 --- Checks to see if this group uses LibDualSpec.
|
|
andrewtknoll@44
|
223 -- @return ##true## if this group uses LibDualSpec, ##false## otherwise (boolean)
|
|
andrewtknoll@35
|
224 function DBGroup:IsUsingDualSpec()
|
|
andrewtknoll@35
|
225 return self.usesDualSpec;
|
|
andrewtknoll@35
|
226 end
|
|
andrewtknoll@35
|
227
|
|
andrewtknoll@35
|
228 --- Enables dual spec support if not already enabled.
|
|
andrewtknoll@35
|
229 function DBGroup:EnableDualSpec()
|
|
andrewtknoll@35
|
230 if not LibDualSpec then
|
|
andrewtknoll@35
|
231 LibDualSpec = LibStub("LibDualSpec-1.0"); -- this will error if LDS isn't found
|
|
andrewtknoll@35
|
232 end
|
|
andrewtknoll@35
|
233 if not self.usesDualSpec then
|
|
andrewtknoll@35
|
234 LibDualSpec:EnhanceDatabase(self.syncDB, self.name);
|
|
andrewtknoll@35
|
235 LibDualSpec:EnhanceOptions(self.profileOptionsTable, self.syncDB);
|
|
andrewtknoll@37
|
236 AceConfigRegistry:NotifyChange(self.name.."Profiles");
|
|
andrewtknoll@35
|
237 self.usesDualSpec = true;
|
|
andrewtknoll@35
|
238 local namespace = self.syncDB:GetNamespace("LibDualSpec-1.0");
|
|
andrewtknoll@35
|
239 namespace.char.enabled = self.syncDB.char.enabled;
|
|
andrewtknoll@35
|
240 namespace.char.profile = self.syncDB.char.profile;
|
|
andrewtknoll@35
|
241 namespace.char.specGroup = self.syncDB.char.specGroup;
|
|
andrewtknoll@35
|
242 self.syncDB:CheckDualSpecState();
|
|
andrewtknoll@35
|
243 end
|
|
andrewtknoll@35
|
244 end
|
|
andrewtknoll@35
|
245
|
|
andrewtknoll@39
|
246 -- slash command support
|
|
andrewtknoll@39
|
247
|
|
andrewtknoll@39
|
248 --- Adds a slash command to the group.
|
|
andrewtknoll@42
|
249 -- @paramsig slug, commandList[, handler]
|
|
andrewtknoll@40
|
250 -- @param slug The base identifier to use for the slash command. (string)
|
|
andrewtknoll@40
|
251 -- @param commandList The command itself, or a list of commands to use. (string or table)
|
|
andrewtknoll@40
|
252 -- @param handler A handler function for the command. If nil, defaults to a function that
|
|
andrewtknoll@40
|
253 -- calls the appropriate secondary command, or opens the root options panel. (function)
|
|
andrewtknoll@39
|
254 function DBGroup:EnableSlashCommand(slug, commandList, handler)
|
|
andrewtknoll@39
|
255 if self.slug then
|
|
andrewtknoll@39
|
256 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): group already has a slash command.", 2);
|
|
andrewtknoll@39
|
257 elseif type(slug) ~= "string" then
|
|
andrewtknoll@39
|
258 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'slug' must be a string.", 2);
|
|
andrewtknoll@39
|
259 elseif type(commandList) ~= "string" and type(commandList) ~= "table" then
|
|
andrewtknoll@39
|
260 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'commandList' must be a string or table.", 2);
|
|
andrewtknoll@39
|
261 elseif handler and type(handler) ~= "function" then
|
|
andrewtknoll@39
|
262 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'handler' must be nil or a function.", 2);
|
|
andrewtknoll@39
|
263 elseif type(commandList) == "table" then
|
|
andrewtknoll@39
|
264 for i = 1, #commandList do
|
|
andrewtknoll@39
|
265 if type(commandList[i]) ~= "string" then
|
|
andrewtknoll@39
|
266 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'commandList' must contain only strings.", 2);
|
|
andrewtknoll@39
|
267 end
|
|
andrewtknoll@39
|
268 end
|
|
andrewtknoll@39
|
269 end
|
|
andrewtknoll@39
|
270
|
|
andrewtknoll@39
|
271 self.slug = slug;
|
|
andrewtknoll@39
|
272 self.subCmdList = {};
|
|
andrewtknoll@39
|
273 if type(commandList) == "string" then
|
|
andrewtknoll@39
|
274 _G["SLASH_"..slug.."1"] = commandList;
|
|
andrewtknoll@39
|
275 else
|
|
andrewtknoll@39
|
276 for i = 1, #commandList do
|
|
andrewtknoll@39
|
277 _G["SLASH_"..slug..i] = commandList[i];
|
|
andrewtknoll@39
|
278 end
|
|
andrewtknoll@39
|
279 end
|
|
andrewtknoll@39
|
280
|
|
andrewtknoll@40
|
281 if handler then
|
|
andrewtknoll@40
|
282 SlashCmdList[slug] = handler;
|
|
andrewtknoll@40
|
283 else
|
|
andrewtknoll@40
|
284 SlashCmdList[slug] = function(msg, editBox)
|
|
andrewtknoll@40
|
285 for cmd, func in pairs(self.subCmdList) do
|
|
andrewtknoll@40
|
286 if msg == cmd then
|
|
andrewtknoll@40
|
287 func("", editBox);
|
|
andrewtknoll@39
|
288 return;
|
|
andrewtknoll@40
|
289 elseif msg:len() > cmd:len() then
|
|
andrewtknoll@40
|
290 if msg:sub(1, cmd:len() + 1) == (cmd.." ") then
|
|
andrewtknoll@40
|
291 func(msg:sub(cmd:len() + 2), editBox);
|
|
andrewtknoll@40
|
292 return;
|
|
andrewtknoll@40
|
293 end
|
|
andrewtknoll@39
|
294 end
|
|
andrewtknoll@39
|
295 end
|
|
andrewtknoll@39
|
296
|
|
andrewtknoll@40
|
297 for k, button in pairs(InterfaceOptionsFrameAddOns.buttons) do
|
|
andrewtknoll@46
|
298 if button.element and button.element.name == self.name and button.element.collapsed then
|
|
andrewtknoll@40
|
299 OptionsListButtonToggle_OnClick(button.toggle);
|
|
andrewtknoll@40
|
300 break;
|
|
andrewtknoll@40
|
301 end
|
|
andrewtknoll@39
|
302 end
|
|
andrewtknoll@40
|
303 InterfaceOptionsFrame_OpenToCategory(self.name);
|
|
andrewtknoll@40
|
304 end;
|
|
andrewtknoll@40
|
305 end
|
|
andrewtknoll@39
|
306 end
|
|
andrewtknoll@39
|
307
|
|
andrewtknoll@40
|
308 --- Checks to see if this group has a slash command.
|
|
andrewtknoll@44
|
309 -- @return ##true## if this group has a slash command, ##false## otherwise (boolean)
|
|
andrewtknoll@40
|
310 function DBGroup:HasSlashCommand()
|
|
andrewtknoll@40
|
311 if self.slug then
|
|
andrewtknoll@40
|
312 return true;
|
|
andrewtknoll@40
|
313 else
|
|
andrewtknoll@40
|
314 return false;
|
|
andrewtknoll@40
|
315 end
|
|
andrewtknoll@40
|
316 end
|
|
andrewtknoll@40
|
317
|
|
andrewtknoll@40
|
318 --- Adds an alias for the slash command.
|
|
andrewtknoll@40
|
319 -- @param alias The alternate name for the slash command. (string)
|
|
andrewtknoll@39
|
320 function DBGroup:AddSlashCommandAlias(alias)
|
|
andrewtknoll@39
|
321 if type(alias) ~= "string" then
|
|
andrewtknoll@39
|
322 error("Usage: DBGroup:AddSlashCommandAlias(alias): 'alias' must be a string.", 2);
|
|
andrewtknoll@39
|
323 elseif not self.slug then
|
|
andrewtknoll@39
|
324 error("Usage: DBGroup:AddSlashCommandAlias(alias): slash commands for this group have not be enabled.", 2);
|
|
andrewtknoll@39
|
325 end
|
|
andrewtknoll@39
|
326
|
|
andrewtknoll@39
|
327 local i = 1;
|
|
andrewtknoll@39
|
328 while _G["SLASH_"..self.slug..i] do
|
|
andrewtknoll@39
|
329 i = i + 1;
|
|
andrewtknoll@39
|
330 end
|
|
andrewtknoll@39
|
331
|
|
andrewtknoll@39
|
332 _G["SLASH_"..self.slug..i] = alias;
|
|
andrewtknoll@39
|
333 end
|
|
andrewtknoll@39
|
334
|
|
andrewtknoll@39
|
335 --- Adds a secondary command handler to the slash command for this group.
|
|
andrewtknoll@40
|
336 -- This handler will be called if the argument to the slash command matches the name provided.
|
|
andrewtknoll@42
|
337 -- @paramsig name, handler[, silent]
|
|
andrewtknoll@40
|
338 -- @param name The name of the secondary command. (string)
|
|
andrewtknoll@40
|
339 -- @param handler The function to handle the command. (function)
|
|
andrewtknoll@42
|
340 -- @param silent ##True## if you want to replace the currently registered command, ##false##
|
|
andrewtknoll@40
|
341 -- otherwise. (boolean)
|
|
andrewtknoll@42
|
342 function DBGroup:AddSecondaryCommand(name, handler, silent)
|
|
andrewtknoll@39
|
343 if type(name) ~= "string" then
|
|
andrewtknoll@40
|
344 error("Usage: DBGroup:AddSecondaryCommand(name, handler[, overwrite]): 'name' must be a string.", 2);
|
|
andrewtknoll@42
|
345 elseif type(handler) ~= "function" then
|
|
andrewtknoll@40
|
346 error("Usage: DBGroup:AddSecondaryCommand(name, handler[, overwrite]): 'handler' must be a function.", 2);
|
|
andrewtknoll@42
|
347 elseif not self.slug then
|
|
andrewtknoll@40
|
348 error("Usage: DBGroup:AddSecondaryCommand(name, handler[, overwrite]): slash commands for this group have not be enabled.", 2);
|
|
andrewtknoll@40
|
349 elseif type(overwrite) ~= "boolean" and type(overwrite) ~= "nil" then
|
|
andrewtknoll@40
|
350 error("Usage: DBGroup:AddSecondaryCommand(name, handler[, overwrite]): 'overwrite' must be a boolean or nil", 2);
|
|
andrewtknoll@39
|
351 end
|
|
andrewtknoll@42
|
352 if not silent then
|
|
andrewtknoll@40
|
353 for k, v in pairs(self.subCmdList) do
|
|
andrewtknoll@40
|
354 if k == name then
|
|
andrewtknoll@40
|
355 error("Usage: DBGroup:AddSecondaryCommand(name, handler[, overwrite]): command '"..name.."' already exists.", 2);
|
|
andrewtknoll@40
|
356 end
|
|
andrewtknoll@39
|
357 end
|
|
andrewtknoll@39
|
358 end
|
|
andrewtknoll@40
|
359
|
|
andrewtknoll@39
|
360 self.subCmdList[name] = handler;
|
|
andrewtknoll@39
|
361 end
|
|
andrewtknoll@39
|
362
|
|
andrewtknoll@44
|
363 --- Returns the list of secondary commands registered with this group.
|
|
andrewtknoll@44
|
364 -- @return A table containing name-function pairs for secondary commands. (table)
|
|
andrewtknoll@44
|
365 function DBGroup:GetSecondaryCommands()
|
|
andrewtknoll@44
|
366 if not self.slug then
|
|
andrewtknoll@44
|
367 error("Usage: DBGroup:GetSecondaryCommands(): Slash commands for this group have not been enabled", 2);
|
|
andrewtknoll@44
|
368 end
|
|
andrewtknoll@44
|
369 return self.subCmdList;
|
|
andrewtknoll@44
|
370 end
|
|
andrewtknoll@44
|
371
|
|
andrewtknoll@19
|
372 -- callback handlers (new profiles are handled by OnProfileChanged)
|
|
andrewtknoll@19
|
373
|
|
andrewtknoll@24
|
374 function DBGroup:OnProfileChanged(callback, syncDB, profile)
|
|
andrewtknoll@24
|
375 if not self.squelchCallbacks then
|
|
andrewtknoll@24
|
376 for db, _ in pairs(self.members) do
|
|
andrewtknoll@25
|
377 db:SetProfile(profile);
|
|
andrewtknoll@24
|
378 end
|
|
andrewtknoll@24
|
379 end
|
|
andrewtknoll@18
|
380 end
|
|
andrewtknoll@18
|
381
|
|
andrewtknoll@24
|
382 function DBGroup:OnProfileDeleted(callback, syncDB, profile)
|
|
andrewtknoll@24
|
383 for db, _ in pairs(self.members) do
|
|
andrewtknoll@24
|
384 db:DeleteProfile(profile, true);
|
|
andrewtknoll@24
|
385 end
|
|
andrewtknoll@18
|
386 end
|
|
andrewtknoll@18
|
387
|
|
andrewtknoll@24
|
388 function DBGroup:OnProfileCopied(callback, syncDB, profile)
|
|
andrewtknoll@24
|
389 for db, _ in pairs(self.members) do
|
|
andrewtknoll@24
|
390 db:CopyProfile(profile, true);
|
|
andrewtknoll@24
|
391 end
|
|
andrewtknoll@18
|
392 end
|
|
andrewtknoll@18
|
393
|
|
andrewtknoll@24
|
394 function DBGroup:OnProfileReset(callback, syncDB)
|
|
andrewtknoll@24
|
395 for db, _ in pairs(self.members) do
|
|
andrewtknoll@24
|
396 db:ResetProfile(false, false);
|
|
andrewtknoll@24
|
397 end
|
|
andrewtknoll@18
|
398 end
|
|
andrewtknoll@23
|
399
|
|
andrewtknoll@42
|
400 -- shutdown handling
|
|
andrewtknoll@42
|
401
|
|
andrewtknoll@29
|
402 local altProfile = nil;
|
|
andrewtknoll@29
|
403 local dualSpecEnabled = nil;
|
|
andrewtknoll@29
|
404 local activeSpecGroup = nil;
|
|
andrewtknoll@28
|
405
|
|
andrewtknoll@28
|
406 function DBGroup:OnSyncShutdown(callback, syncDB)
|
|
andrewtknoll@29
|
407 if self.usesDualSpec and not altProfile then
|
|
andrewtknoll@29
|
408 altProfile = syncDB:GetDualSpecProfile();
|
|
andrewtknoll@29
|
409 dualSpecEnabled = syncDB:IsDualSpecEnabled();
|
|
andrewtknoll@29
|
410 activeSpecGroup = GetActiveSpecGroup();
|
|
andrewtknoll@28
|
411 end
|
|
andrewtknoll@28
|
412 end
|
|
andrewtknoll@28
|
413
|
|
andrewtknoll@24
|
414 local timestamp = nil;
|
|
andrewtknoll@24
|
415
|
|
andrewtknoll@28
|
416 function DBGroup:OnMemberShutdown(callback, db)
|
|
andrewtknoll@27
|
417 if not timestamp then -- ensure uniform timestamps to minimize
|
|
andrewtknoll@27
|
418 timestamp = time(); -- calls to SetProfile in NewGroup
|
|
andrewtknoll@24
|
419 end
|
|
andrewtknoll@41
|
420 db.char.logoutTimestamp = timestamp; -- namespace is registered for callback, not base db
|
|
andrewtknoll@29
|
421 if self.usesDualSpec then
|
|
andrewtknoll@29
|
422 if not altProfile then
|
|
andrewtknoll@29
|
423 altProfile = self.syncDB:GetDualSpecProfile();
|
|
andrewtknoll@29
|
424 dualSpecEnabled = self.syncDB:IsDualSpecEnabled();
|
|
andrewtknoll@29
|
425 activeSpecGroup = GetActiveSpecGroup();
|
|
andrewtknoll@29
|
426 end
|
|
andrewtknoll@41
|
427 db.char.altProfile = altProfile;
|
|
andrewtknoll@41
|
428 db.char.dualSpecEnabled = dualSpecEnabled;
|
|
andrewtknoll@41
|
429 db.char.activeSpecGroup = activeSpecGroup;
|
|
andrewtknoll@28
|
430 end
|
|
andrewtknoll@23
|
431 end
|
|
andrewtknoll@33
|
432
|
|
andrewtknoll@33
|
433 -- update existing groups
|
|
andrewtknoll@33
|
434 for groupName, group in pairs(LibModuleDBShare.groups) do
|
|
andrewtknoll@33
|
435 for funcName, func in pairs(DBGroup) do
|
|
andrewtknoll@33
|
436 group[funcName] = func;
|
|
andrewtknoll@33
|
437 end
|
|
andrewtknoll@33
|
438 end
|