annotate Devian.lua @ 17:48a1d9c14af5

Commented out debug prints
author Nenue
date Sun, 20 Dec 2015 02:26:36 -0500
parents 5254d1ba6013
children 01c32c98e72a
rev   line source
Nenue@0 1 -- User: Krakyn
Nenue@0 2 -- Created: 11/30/2015 7:46 AM
Nenue@0 3 if not LibStub then
Nenue@0 4 print('Something has happened...')
Nenue@0 5 end
Nenue@0 6 Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0")
Nenue@13 7 local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@'
Nenue@0 8 local D = _G.Devian
Nenue@0 9 local STATE_LOW, STATE_HIGH = 1, 2
Nenue@0 10 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName()
Nenue@13 11 local DEVIAN_FRAME = 'DevianConsole'
Nenue@7 12 local print = function(...)
Nenue@13 13 _G.print('Dvn', ...)
Nenue@7 14 end
Nenue@9 15 local db
Nenue@13 16 local defaults = {
Nenue@13 17 ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}},
Nenue@13 18 ['tags'] = {},
Nenue@13 19 ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}},
Nenue@14 20 primary_channel = 1,
Nenue@13 21 current_channel = 1,
Nenue@14 22 toggle = true,
Nenue@13 23 dnd_status = true,
Nenue@13 24 dnd_message = "Debugging. Your messages may get eaten.",
Nenue@13 25 font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]],
Nenue@13 26 fontsize = 13,
Nenue@13 27 fontoutline = 'NONE',
Nenue@14 28 backdrop = {1,1,1,0.2},
Nenue@14 29 backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5},
Nenue@14 30 backblend = 'BLEND',
Nenue@14 31 frontdrop = {1,1,1,1},
Nenue@14 32 frontgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.9, 0, 0, 0, 0.9},
Nenue@14 33 frontblend = 'BLEND'
Nenue@13 34 }
Nenue@9 35
Nenue@4 36
Nenue@13 37 local function ScanAddOnList(cmd, ...)
Nenue@0 38 local list_state
Nenue@0 39
Nenue@14 40 local args = {}
Nenue@14 41 local arg, n = D:GetArgs(cmd, 1)
Nenue@14 42 while arg do
Nenue@14 43 table.insert(args, arg)
Nenue@14 44 arg, n = D:GetArgs(cmd,1,n)
Nenue@14 45 end
Nenue@14 46 local mode, tag, dest = unpack(args)
Nenue@0 47
Nenue@13 48
Nenue@14 49 -- no args, toggle ui
Nenue@0 50 if mode == nil then
Nenue@0 51 list_state = db.enabled and STATE_LOW or STATE_HIGH
Nenue@0 52 db.enabled = (db.enabled == false) and true or false
Nenue@17 53 --print(list_state, db.enabled)
Nenue@0 54
Nenue@0 55 if list_state == STATE_LOW then
Nenue@0 56 end
Nenue@14 57 elseif mode == 'stack' then
Nenue@14 58 return D:StackFrames()
Nenue@14 59 elseif mode == 'grid' then
Nenue@14 60 return D:DistributeFrames()
Nenue@14 61 elseif mode == 'tag' then -- tagging
Nenue@14 62 if tag ~= nil and dest ~= nil then
Nenue@14 63 if not D.console[dest] and not D.sig[dest] then
Nenue@14 64 local sig = dest:match('%a')
Nenue@14 65 local id = dest:match('%d')
Nenue@14 66 if not id then
Nenue@14 67 id = self.last_channel + 1
Nenue@14 68 end
Nenue@14 69 if not sig then
Nenue@14 70 sig = tag
Nenue@14 71 end
Nenue@14 72 D:SetChannel(sig, id)
Nenue@14 73 end
Nenue@14 74 D:Print('Assigning |cFFFFFF00'..tag..'|r to |cFF00FFFF'.. dest .. '|r')
Nenue@14 75 else
Nenue@14 76 D:Print('Usage: /dvn tag <prefix> <console name or number>')
Nenue@14 77 end
Nenue@14 78 return
Nenue@14 79 elseif mode ~= nil then
Nenue@14 80 mode = tonumber(mode)
Nenue@0 81 if mode > 2 then
Nenue@17 82 --print('Something has happened.')
Nenue@0 83 return
Nenue@0 84 end
Nenue@0 85 list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH
Nenue@0 86 end
Nenue@0 87 local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state]
Nenue@0 88
Nenue@0 89 local playername = UnitName("player")
Nenue@0 90
Nenue@0 91 for i = 1, GetNumAddOns() do
Nenue@0 92 local name = GetAddOnInfo(i)
Nenue@0 93 local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i)
Nenue@0 94
Nenue@0 95 if mode == STATE_LOW or mode == STATE_HIGH then
Nenue@0 96 char_list[name] = enableState
Nenue@0 97 global_list[name] = globalState
Nenue@0 98 else
Nenue@13 99 if char_list[name] or global_list[name] then
Nenue@0 100
Nenue@0 101 if char_list[name] ~= 0 and global_list[name] ~= 0 then
Nenue@0 102 local value = false
Nenue@0 103 if char_list[name] == 2 and global_list[name] == 1 then
Nenue@0 104 value = UnitName("player")
Nenue@0 105 elseif global_list[name] == 2 then
Nenue@0 106 value = true
Nenue@0 107 end
Nenue@17 108 --print('EnableAddOn(', i, ',', value,')')
Nenue@0 109 EnableAddOn(i, value)
Nenue@0 110 else
Nenue@0 111 local value = true
Nenue@0 112 if char_list[name] == 2 and global_list[name] == 1 then
Nenue@0 113 value = UnitName("player")
Nenue@0 114 end
Nenue@17 115 --print('DisableAddOn(', i, ',', value,')')
Nenue@0 116 DisableAddOn(i,value)
Nenue@0 117 end
Nenue@13 118 end
Nenue@0 119
Nenue@0 120 end
Nenue@0 121 end
Nenue@0 122
Nenue@0 123 if mode == nil then
Nenue@0 124 ReloadUI()
Nenue@0 125 end
Nenue@0 126 if mode == STATE_LOW then
Nenue@0 127 D:Print('Developement AddOn list saved.')
Nenue@0 128 else
Nenue@0 129 D:Print('Standard AddOn list saved.')
Nenue@0 130 end
Nenue@0 131 end
Nenue@0 132
Nenue@0 133
Nenue@13 134 local function Console_MinMax(self)
Nenue@13 135 if self.minimized then
Nenue@7 136 self:Maximize()
Nenue@7 137 else
Nenue@7 138 self:Minimize()
Nenue@7 139 end
Nenue@7 140 end
Nenue@13 141
Nenue@13 142 local function Console_Minimize(self)
Nenue@13 143 self:SetHeight(20)
Nenue@13 144 self:SetMaxResize(GetScreenWidth(),20)
Nenue@13 145 self.minimized = true
Nenue@14 146 self.out:Hide()
Nenue@14 147 self:Save()
Nenue@7 148 end
Nenue@0 149
Nenue@13 150 local function Console_Maximize(self)
Nenue@13 151 local db = db.channels[self.index]
Nenue@13 152 self:SetHeight(db.height)
Nenue@13 153 self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
Nenue@13 154 self.minimized = nil
Nenue@14 155 self.out:Show()
Nenue@14 156 self:Save()
Nenue@13 157 end
Nenue@13 158
Nenue@13 159
Nenue@13 160 local function Console_Save(self)
Nenue@13 161 local db = db.channels[self.index]
Nenue@14 162 if self.x then
Nenue@14 163 db.x = self.x
Nenue@14 164 else
Nenue@14 165 db.x = self:GetLeft()
Nenue@14 166 end
Nenue@14 167
Nenue@14 168 if self.y then
Nenue@14 169 db.y = self.y
Nenue@14 170 else
Nenue@14 171 db.y = (self:GetTop() - GetScreenHeight())
Nenue@14 172 end
Nenue@14 173
Nenue@14 174 if self.width then
Nenue@14 175 db.width = self.width
Nenue@14 176 else
Nenue@14 177 db.width = self:GetWidth()
Nenue@14 178 end
Nenue@14 179
Nenue@13 180 if not self.minimized then
Nenue@14 181 if self.height then
Nenue@14 182 db.height = self.height
Nenue@14 183 else
Nenue@14 184 db.height = self:GetHeight()
Nenue@14 185 end
Nenue@14 186 self:SetHeight(db.height)
Nenue@13 187 end
Nenue@14 188
Nenue@14 189 db.minimized = self.minimized and true or nil
Nenue@14 190 db.enabled = self:IsVisible() and true or nil
Nenue@14 191 db.active = self.active and true or nil
Nenue@17 192 --print('save:', db.signature, 'min=', db.minimized, ' enabled=', db.enabled, ' active = ', db.active, 'x=', db.x, 'y=', db.y, 'h=', db.height, 'w=', db.width)
Nenue@13 193 self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
Nenue@14 194 self:SetWidth(db.width)
Nenue@13 195 end
Nenue@13 196
Nenue@14 197 -- Console frame toggler
Nenue@14 198 -- @paramsig [...]
Nenue@14 199 -- @param ... one or more space-seperated channel keys
Nenue@13 200 local function Console_Toggle(input)
Nenue@14 201 local search = {}
Nenue@14 202 local key, n = D:GetArgs(input, 1)
Nenue@14 203 if key then
Nenue@14 204 repeat
Nenue@14 205 if D.sig[key] then
Nenue@14 206 table.insert(search, D.sig[key])
Nenue@14 207 elseif D.console[key] then
Nenue@14 208 table.insert(search, D.console[key])
Nenue@14 209 end
Nenue@14 210 key, n = D:GetArgs(input,1,n)
Nenue@14 211 until n == 1e9
Nenue@13 212 else
Nenue@13 213 search = D.console
Nenue@13 214 end
Nenue@13 215
Nenue@14 216 db.toggle = not db.toggle and true or nil
Nenue@13 217 for _, c in ipairs(search) do
Nenue@14 218 if db.toggle then
Nenue@14 219 c:Show()
Nenue@14 220 else
Nenue@14 221 c.enabled = nil
Nenue@14 222 c.minimized = nil
Nenue@14 223 c:Maximize()
Nenue@13 224 c:Hide()
Nenue@13 225 end
Nenue@13 226 end
Nenue@14 227
Nenue@14 228 if db.toggle then
Nenue@14 229 D:Print('toggled on?')
Nenue@14 230 else
Nenue@14 231 D:Print('toggled off?')
Nenue@14 232 end
Nenue@13 233 end
Nenue@13 234
Nenue@14 235 -- Bring console to the front
Nenue@14 236 local function Console_ToFront(c)
Nenue@14 237 --print(D.raise_ct, 'Raising', c.signature)
Nenue@14 238 --print(unpack(db.frontdrop))
Nenue@14 239 --print(unpack(db.frontgrad))
Nenue@14 240 --print(db.frontblend)
Nenue@14 241 D.raise_ct = D.raise_ct + 1
Nenue@14 242 c:Raise()
Nenue@14 243 c.out.backdrop:SetTexture(unpack(db.frontdrop))
Nenue@14 244 c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad))
Nenue@14 245 c.out.backdrop:SetBlendMode(db.frontblend)
Nenue@14 246
Nenue@14 247 for id, bc in pairs(D.console) do
Nenue@14 248 if id ~= c.index then
Nenue@14 249 --print(D.raise_ct, 'Lowering', bc.signature)
Nenue@14 250 --print(unpack(db.backdrop))
Nenue@14 251 --print(unpack(db.backgrad))
Nenue@14 252 --print(db.backblend)
Nenue@14 253 bc.out.backdrop:SetTexture(unpack(db.backdrop))
Nenue@14 254 bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad))
Nenue@14 255 bc.out.backdrop:SetBlendMode(db.backblend)
Nenue@14 256 end
Nenue@14 257 end
Nenue@14 258
Nenue@14 259 end
Nenue@14 260
Nenue@14 261 -- Generate a console frame
Nenue@14 262 -- @paramsig id, vars
Nenue@14 263 -- @param id channel number
Nenue@14 264 -- @param vars alternative config, else uses db.channels[id]
Nenue@13 265 local function CreateConsole(i, vars)
Nenue@14 266
Nenue@14 267 if not vars then
Nenue@14 268 vars = db.channels[i]
Nenue@14 269 end
Nenue@14 270
Nenue@17 271 --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height)
Nenue@13 272 local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME)
Nenue@14 273 f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y)
Nenue@13 274 f:SetSize(vars.width, vars.height)
Nenue@13 275 f:Lower()
Nenue@13 276 f.out:SetFont(db.font, db.fontsize, db.fontoutline)
Nenue@13 277 f.Save = Console_Save
Nenue@13 278 f.Minimize = Console_Minimize
Nenue@13 279 f.Maximize = Console_Maximize
Nenue@13 280 f.MinMax = Console_MinMax
Nenue@14 281 f.ToFront = Console_ToFront
Nenue@13 282 f.Toggle = D.Console_Toggle
Nenue@13 283 f.name = vars.name
Nenue@13 284 f.index = i
Nenue@14 285 f.signature = vars.signature
Nenue@14 286 f.format = vars.header
Nenue@14 287 f.x = vars.x
Nenue@14 288 f.y = vars.y
Nenue@14 289 f.width = vars.width
Nenue@14 290 f.height = vars.height
Nenue@13 291
Nenue@14 292 if vars.enabled then
Nenue@14 293 f.enabled = true
Nenue@14 294 if db.toggle then
Nenue@14 295 f:Show()
Nenue@14 296 end
Nenue@13 297 end
Nenue@14 298 if vars.minimized then
Nenue@13 299 f:Minimize()
Nenue@13 300 end
Nenue@13 301
Nenue@13 302 return f
Nenue@13 303 end
Nenue@13 304
Nenue@14 305 -- Print to Devian output
Nenue@14 306 -- @paramsig tag, ...
Nenue@14 307 -- @param tag channel signature or number used to select console
Nenue@14 308 -- @param ... print arguments
Nenue@0 309 local function Message(prefix, ...)
Nenue@1 310 if prefix == nil then
Nenue@13 311 prefix = 1
Nenue@1 312 end
Nenue@9 313
Nenue@13 314 local channel
Nenue@13 315 local byName = true
Nenue@13 316 if D.sig[prefix] then
Nenue@13 317 channel = D.sig[prefix]
Nenue@13 318 elseif D.console[prefix] then
Nenue@13 319 channel = D.console[prefix]
Nenue@13 320 byName = nil
Nenue@13 321 else
Nenue@13 322 channel = D.console[1]
Nenue@13 323 end
Nenue@9 324 -- color me timbers
Nenue@9 325 local pcolor
Nenue@13 326 if D.tags[prefix] then
Nenue@9 327 pcolor = db.tags[prefix]
Nenue@13 328 elseif byName then
Nenue@0 329 local c = {0, 0, 0 }
Nenue@0 330 local max = string.len(prefix)
Nenue@0 331 for i = 1, max, 3 do
Nenue@0 332 for k, v in ipairs(c) do
Nenue@0 333 local j = i + (k - 1)
Nenue@0 334 c[k] = c[k] + (j <= max and string.byte(prefix,j) or 0)
Nenue@0 335 end
Nenue@0 336 end
Nenue@0 337 for k,v in ipairs(c) do
Nenue@0 338 c[k] = c[k] % 255
Nenue@0 339 if c[k] < 64 then
Nenue@0 340 c[k] = 0
Nenue@0 341 elseif c[k] > 127 then
Nenue@0 342 c[k] = 255
Nenue@0 343 end
Nenue@0 344 end
Nenue@13 345 D.tags[prefix] = string.format('%02X%02X%02X', unpack(c))
Nenue@0 346 end
Nenue@0 347
Nenue@13 348 local buffer = {'|cFF'.. D.tags[prefix]..prefix ..'|r'}
Nenue@0 349 for i = 1, select('#',...) do
Nenue@0 350 local var = select(i, ...)
Nenue@0 351
Nenue@0 352 if type(var) == 'table' then
Nenue@0 353 var = '<table>'
Nenue@0 354 elseif type(var) == 'boolean' then
Nenue@0 355 var = var and 'true' or 'false'
Nenue@0 356 elseif type(var) == 'function' then
Nenue@0 357 var = '<funcref>'
Nenue@0 358 elseif type(var) == 'nil' then
Nenue@0 359 var = 'nil'
Nenue@0 360 end
Nenue@0 361
Nenue@0 362 table.insert(buffer, var)
Nenue@0 363 end
Nenue@13 364 channel.out:AddMessage(table.concat(buffer, ' '))
Nenue@0 365 table.wipe(buffer)
Nenue@0 366 end
Nenue@0 367
Nenue@14 368 -- Spaces each frame evenly across the screen
Nenue@14 369 function D:DistributeFrames() --
Nenue@17 370 --print('frame grid:', max, num_side)
Nenue@14 371 local max = self.num_channels
Nenue@14 372 local num_side = math.ceil(math.sqrt(max))
Nenue@14 373 local w = GetScreenWidth() / num_side
Nenue@14 374 local h = GetScreenHeight() / num_side
Nenue@14 375 for i, frame in pairs(D.console) do
Nenue@14 376 local dx = (i-1) % num_side
Nenue@14 377 local dy = math.floor((i-1) / num_side)
Nenue@14 378
Nenue@17 379 --print('move:', frame.signature, 'dx=', dx, 'dy=', dy)
Nenue@17 380 --print('move:', frame.signature, ' x=', dx * w, 'y=', -(dy * h), 'h=', h, 'w=', w)
Nenue@14 381 frame.width = w
Nenue@14 382 frame.height = h
Nenue@14 383 frame.x = dx * w
Nenue@14 384 frame.y = -(dy * h)
Nenue@14 385 frame:Save()
Nenue@14 386 end
Nenue@14 387
Nenue@14 388 end
Nenue@14 389
Nenue@14 390 -- Place all frames stacked beneath the primary frame
Nenue@14 391 -- @paramsig
Nenue@14 392 function D:StackFrames()
Nenue@14 393 local last
Nenue@14 394 for i, frame in pairs(self.console) do
Nenue@14 395 if last then
Nenue@14 396 frame.x = last.x
Nenue@14 397 frame.y = last.y - 20
Nenue@14 398 else
Nenue@14 399 frame.x = (GetScreenWidth()-frame:GetWidth())/2
Nenue@14 400 frame.y = 0
Nenue@14 401 end
Nenue@14 402 frame:Save()
Nenue@14 403 last = frame
Nenue@14 404 end
Nenue@14 405 end
Nenue@14 406
Nenue@14 407 -- Creates or updates a console frame
Nenue@14 408 -- @paramsig cinfo [, i]
Nenue@14 409 -- @param cinfo an array from db.channels[x] or the desired string signature
Nenue@14 410 -- @param id when set, the console at that index will be assigned all parameters in cinfo
Nenue@14 411 function D:SetChannel(cinfo, i)
Nenue@17 412 --print('join:', i , cinfo)
Nenue@14 413 local t_info = {}
Nenue@14 414 if type(cinfo) ~= 'table' then
Nenue@14 415 t_info.signature = tostring(cinfo)
Nenue@14 416 cinfo = {}
Nenue@14 417 end
Nenue@14 418 local srcdb = db.channels[self.primary_channel]
Nenue@14 419 if i ~= nil then
Nenue@14 420 i = tonumber(i)
Nenue@14 421 if db.channels[i] then
Nenue@17 422 --print('pull vars from '..db.channels[i].signature)
Nenue@14 423 cinfo = db.channels[i]
Nenue@14 424 srcdb = cinfo
Nenue@14 425 end
Nenue@14 426 end
Nenue@14 427
Nenue@14 428 for k,v in pairs(srcdb) do
Nenue@14 429 if not t_info[k] then
Nenue@14 430 if cinfo[k] then
Nenue@17 431 --print('- pulling', k..':',v)
Nenue@14 432 t_info[k] = cinfo[k]
Nenue@14 433 end
Nenue@14 434 end
Nenue@14 435 end
Nenue@14 436
Nenue@14 437 if not db.channels[i] then
Nenue@14 438 t_info.x = t_info.x + 20
Nenue@14 439 t_info.y = t_info.y - 20
Nenue@14 440 db.channels[i] = t_info
Nenue@14 441 end
Nenue@14 442 if not self.console[i] then
Nenue@14 443 self.console[i] = CreateConsole(i, t_info)
Nenue@14 444 end
Nenue@14 445
Nenue@14 446 self.sig[cinfo.signature] = self.console[i]
Nenue@14 447 self.sigID[cinfo.signature] = i
Nenue@14 448 self.IDsig[i] = cinfo.signature
Nenue@14 449 end
Nenue@14 450
Nenue@0 451 function D:OnEnable()
Nenue@13 452 -- commands
Nenue@13 453 local cmdlist = {
Nenue@13 454 ['dvn'] = ScanAddOnList,
Nenue@13 455 ['devian'] = ScanAddOnList,
Nenue@13 456 ['dvc'] = Console_Toggle,
Nenue@13 457 }
Nenue@13 458 for cmd, func in pairs(cmdlist) do
Nenue@13 459 self:RegisterChatCommand(cmd, func, true)
Nenue@13 460 end
Nenue@13 461
Nenue@11 462 if db.enabled == true then
Nenue@0 463 D:Print('Standard AddOn list active. Type /dvn to switch to development mode.')
Nenue@0 464 else
Nenue@0 465 D:Print('Development AddOn list active. Type /dvn to revert to regular operation.')
Nenue@0 466 end
Nenue@13 467
Nenue@0 468 end
Nenue@0 469
Nenue@0 470 function D:OnInitialize()
Nenue@13 471 -- emergency button
Nenue@13 472 self:RegisterChatCommand("cleandvn", function(args)
Nenue@13 473 DevianDB = nil
Nenue@13 474 ReloadUI()
Nenue@13 475 end)
Nenue@13 476
Nenue@13 477 -- savedvars
Nenue@13 478 local cherry = false
Nenue@9 479 if not _G.DevianDB then
Nenue@13 480 _G.DevianDB = defaults
Nenue@13 481 cherry = "Type /dvnsave to snapshot your current UI"
Nenue@9 482 end
Nenue@9 483 db = _G.DevianDB
Nenue@0 484
Nenue@0 485 if not db[PLAYER_REALM] then
Nenue@9 486 db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}
Nenue@0 487 if not cherry then
Nenue@0 488 cherry = "This character didn't have an AddOn table."
Nenue@0 489 end
Nenue@0 490 end
Nenue@0 491
Nenue@13 492 -- copy tags
Nenue@13 493 self.tags = {}
Nenue@13 494 for n, c in pairs(db.tags) do
Nenue@13 495 self.tags[n] = c
Nenue@13 496 end
Nenue@0 497 if cherry then
Nenue@0 498 D:Print(cherry)
Nenue@0 499 end
Nenue@0 500 D.oldprint = getprinthandler()
Nenue@0 501 if not _G.oldprint then
Nenue@0 502 _G.oldprint = D.oldprint
Nenue@0 503 end
Nenue@13 504
Nenue@14 505 self.raise_ct = 0
Nenue@14 506 self.last_channel = 0
Nenue@14 507 self.num_channels = 0
Nenue@13 508 self.console = {}
Nenue@13 509 self.sig = {}
Nenue@14 510 self.sigID = {}
Nenue@14 511 self.IDsig = {}
Nenue@14 512 for i, cinfo in pairs(db.channels) do
Nenue@14 513 i = tonumber(i)
Nenue@14 514 if not self.primary_channel then
Nenue@14 515 self.primary_channel = i
Nenue@14 516 end
Nenue@14 517 self:SetChannel(cinfo, i)
Nenue@14 518 if i > self.last_channel then
Nenue@14 519 self.last_channel = i
Nenue@14 520 end
Nenue@14 521 self.num_channels = self.num_channels + 1
Nenue@13 522 end
Nenue@0 523 setprinthandler(Message)
Nenue@13 524 print(MAJOR, MINOR)
Nenue@0 525 end