1# gui.py 2# 3# main openipmi GUI handling 4# 5# Author: MontaVista Software, Inc. 6# Corey Minyard <minyard@mvista.com> 7# source@mvista.com 8# 9# Copyright 2005 MontaVista Software Inc. 10# 11# This program is free software; you can redistribute it and/or 12# modify it under the terms of the GNU Lesser General Public License 13# as published by the Free Software Foundation; either version 2 of 14# the License, or (at your option) any later version. 15# 16# 17# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 18# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 23# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27# 28# You should have received a copy of the GNU Lesser General Public 29# License along with this program; if not, write to the Free 30# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31# 32try: 33 import Tix 34except: 35 import tkinter 36 from tkinter import tix as Tix 37 38import OpenIPMI 39from openipmigui import _saveprefs 40from openipmigui import _oi_logging 41from openipmigui import gui_domainDialog 42from openipmigui import gui_errstr 43from openipmigui import gui_cmdwin 44from openipmigui import gui_list 45from openipmigui import gui_popup 46from openipmigui import gui_winsys 47 48init_treenamewidth = 150 49init_sashposition = 400 50init_isashposition = 300 51init_bsashposition = 350 52init_windowwidth = 800 53init_windowheight = 700 54init_logevents = False 55init_fullevents = False 56init_impt_objs = [ ] 57 58refresh_timer_time = 10000 59 60class IPMITreeDummyItem: 61 def __init__(self, treestr): 62 self.treestr = treestr 63 return 64 65 pass 66 67class IPMICloser: 68 def __init__(self, ui, count): 69 self.ui = ui 70 self.count = count 71 return 72 73 def domain_cb(self, domain): 74 domain.close(self) 75 return 76 77 def domain_close_done_cb(self): 78 self.count = self.count - 1 79 return 80 81 def wait_done(self): 82 while (self.count > 0): 83 OpenIPMI.wait_io(1000) 84 pass 85 self.ui.mainhandler.init_history = self.ui.cmdwindow.history 86 return 87 88 pass 89 90class ImptObj: 91 def __init__(self, gui, type, name, obj): 92 self.gui = gui 93 self.type = type 94 self.name = name 95 self.obj = obj 96 return 97 98 def HandleMenu(self, event, key, point): 99 data = self.obj 100 if (data != None) and (hasattr(data, "HandleMenu")): 101 data.HandleMenu(event) 102 pass 103 else: 104 menul = [ [ "Remove from watch values", self.remove_impt ] ] 105 gui_popup.popup(self.gui, event, menul) 106 return 107 108 def remove_impt(self, event): 109 self.gui.remove_impt_data(self) 110 return 111 112 pass 113 114class IPMIGUI(Tix.Frame): 115 def __init__(self, top, mainhandler): 116 Tix.Frame.__init__(self, top, bd=2, relief=Tix.RAISED) 117 118 self.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1) 119 120 self.top = top 121 122 self.mainhandler = mainhandler 123 124 self.inactive_style = Tix.DisplayStyle(Tix.TEXT, fg="dark grey", 125 selectforeground="dark grey", 126 selectbackground="beige", 127 refwindow=top) 128 self.active_style = Tix.DisplayStyle(Tix.TEXT, fg="black", 129 selectforeground="black", 130 selectbackground="beige", 131 refwindow=top) 132 self.critical_style = Tix.DisplayStyle(Tix.TEXT, fg="blue", 133 selectforeground="blue", 134 selectbackground="beige", 135 refwindow=top) 136 self.severe_style = Tix.DisplayStyle(Tix.TEXT, fg="red", 137 selectforeground="red", 138 selectbackground="beige", 139 refwindow=top) 140 self.warn_style = Tix.DisplayStyle(Tix.TEXT, fg="burlywood4", 141 selectforeground="burlywood4", 142 selectbackground="beige", 143 refwindow=top) 144 145 self.logeventsv = Tix.IntVar() 146 self.logeventsv.set(init_logevents) 147 self.logevents = init_logevents 148 self.fulleventsv = Tix.IntVar() 149 self.fulleventsv.set(init_fullevents) 150 OpenIPMI.cmdlang_set_evinfo(self.fulleventsv.get()) 151 152 fileb = Tix.Menubutton(self, text="File", underline=0, takefocus=0) 153 filemenu = Tix.Menu(fileb, tearoff=0) 154 fileb["menu"] = filemenu 155 filemenu.add_command(label="Exit", underline=1, accelerator="Ctrl+Q", 156 command = lambda self=self: self.quit() ) 157 top.bind_all("<Control-Q>", self.quit) 158 top.bind_all("<Control-q>", self.quit) 159 filemenu.add_command(label="Open Domain", underline=1, 160 accelerator="Ctrl+O", 161 command = lambda self=self: self.openDomain() ) 162 top.bind_all("<Control-O>", self.openDomain) 163 top.bind_all("<Control-o>", self.openDomain) 164 filemenu.add_command(label="Save Prefs", underline=1, 165 accelerator="Ctrl+S", 166 command = lambda self=self: self.savePrefs() ) 167 top.bind_all("<Control-S>", self.savePrefs) 168 top.bind_all("<Control-s>", self.savePrefs) 169 170 viewb = Tix.Menubutton(self, text="View", underline=0, takefocus=0) 171 viewmenu = Tix.Menu(viewb, tearoff=0) 172 viewb["menu"] = viewmenu 173 viewmenu.add_command(label="Expand All", underline=1, 174 accelerator="Ctrl+E", 175 command = lambda self=self: self.ExpandAll() ) 176 top.bind_all("<Control-E>", self.ExpandAll) 177 top.bind_all("<Control-e>", self.ExpandAll) 178 viewmenu.add_command(label="Collapse All", underline=1, 179 accelerator="Ctrl+C", 180 command = lambda self=self: self.CollapseAll() ) 181 top.bind_all("<Control-C>", self.CollapseAll) 182 top.bind_all("<Control-c>", self.CollapseAll) 183 184 setb = Tix.Menubutton(self, text="Settings", underline=0, takefocus=0) 185 viewmenu = Tix.Menu(setb, tearoff=0) 186 setb["menu"] = viewmenu 187 viewmenu.add_checkbutton(label="Enable Events", underline=0, 188 command=lambda w=self: w.EnableEvents(), 189 variable=self.logeventsv) 190 viewmenu.add_checkbutton(label="Full Event Info", underline=0, 191 command=lambda w=self: w.FullEventInfo(), 192 variable=self.fulleventsv) 193 194 vpane = Tix.PanedWindow(self, orientation="vertical", 195 width=init_windowwidth, 196 height=init_windowheight) 197 self.vpane = vpane 198 objevpane = vpane.add("objectsevents", size=init_sashposition) 199 imptobjpane = vpane.add("importantobjects", 200 size = init_isashposition - init_sashposition) 201 cmdpane = vpane.add("command") 202 hpane = Tix.PanedWindow(objevpane, orientation="horizontal") 203 self.hpane = hpane 204 objpane = hpane.add("objects", size=init_bsashposition) 205 evpane = hpane.add("events") 206 207 self.tree = Tix.Tree(objpane, options="hlist.columns 2") 208 # FIXME: This doesn't work, and I don't know why 209 self.tree.hlist.configure(selectbackground="beige") 210 self.tree.hlist.add("D", itemtype=Tix.TEXT, text="Domains") 211 self.tree.setmode("D", "none") 212 self.treedata = { } 213 self.treedata["D"] = IPMITreeDummyItem("D") 214 self.setup_item("D", active=True) 215 self.tree.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1) 216 self.tree.hlist.bind("<Button-3>", self.TreeMenu) 217 218 self.tree.hlist.bind("<MouseWheel>", self.Wheel) 219 if (gui_winsys.winsys == "x11"): 220 self.tree.hlist.bind("<Button-4>", self.ButtonUp) 221 self.tree.hlist.bind("<Button-5>", self.ButtonDown) 222 pass 223 224 self.numloglines = 1 225 self.maxloglines = 1000 226 self.logwindow = Tix.ScrolledText(evpane) 227 self.logwindow.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1) 228 self.logwindow.text.insert("end", "GUI Log Window") 229 230 self.imptobjs = gui_list.SubList(imptobjpane, 231 ( ("Type", 50), 232 ("Name", 200), 233 ("Data", 200) ), 234 options=("hlist.header 1" 235 + " hlist.itemtype text" 236 + " hlist.columns 3" 237 + " hlist.selectForeground black" 238 + " hlist.selectBackground beige"), 239 width=0, height=0) 240 self.imptobjs.pack(fill=Tix.BOTH, expand=1) 241 242 self.errstr = gui_errstr.ErrStr(cmdpane) 243 self.errstr.pack(side=Tix.TOP, fill=Tix.X, expand=1) 244 245 self.cmdwindow = gui_cmdwin.CommandWindow(cmdpane, self) 246 self.cmdwindow.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1) 247 248 hpane.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1) 249 250 vpane.pack(side=Tix.BOTTOM, fill=Tix.BOTH, expand=1) 251 fileb.pack(side=Tix.LEFT) 252 viewb.pack(side=Tix.LEFT) 253 setb.pack(side=Tix.LEFT) 254 255 self.itemval = 0 256 257 self.in_destroy = False 258 259 self.bind("<Destroy>", self.OnDestroy) 260 261 self.impt_objs = { } 262 self.impt_objs["control"] = { } 263 self.impt_objs["sensor"] = { } 264 self.impt_objs["entity"] = { } 265 266 self.last_scan = None 267 self.timer_timeout_ms = 200 268 top.after(self.timer_timeout_ms, self.Timeout) 269 270 for i in init_impt_objs: 271 self.add_impt_data(i[0], i[1]) 272 pass 273 return 274 275 def Wheel(self, event): 276 self.tree.hlist.yview("scroll", -int(event.delta / 20), "units") 277 return 278 279 def ButtonUp(self, event): 280 event.delta = 120 281 self.Wheel(event); 282 return 283 284 def ButtonDown(self, event): 285 event.delta = -120 286 self.Wheel(event); 287 return 288 289 def ReportError(self, str): 290 if (self.in_destroy): 291 return 292 self.errstr.SetError(str) 293 return 294 295 def find_impt_data(self, type, name): 296 s = self.impt_objs[type] 297 if name in s: 298 return s[name] 299 return None 300 301 def add_impt_data(self, type, name, obj=None): 302 if name in self.impt_objs[type]: 303 return 304 i = ImptObj(self, type, name, obj) 305 self.impt_objs[type][name] = i 306 i.key = self.imptobjs.Append(type, (name, ""), data=i) 307 if (obj != None): 308 obj.impt_data = i; 309 self.setup_impt_data(obj.impt_data, obj) 310 pass 311 else: 312 self.imptobjs.SetColumnStyle(i.key, 0, self.inactive_style) 313 return 314 315 def setup_impt_data(self, data, obj): 316 data.obj = obj 317 self.set_impt_active_change(obj) 318 self.imptobjs.SetColumnStyle(obj.impt_data.key, 0, self.active_style) 319 self.set_impt_data_text(obj) 320 return 321 322 def cleanup_impt_data(self, obj): 323 self.imptobjs.SetColumnStyle(obj.impt_data.key, 1, 324 self.inactive_style) 325 self.imptobjs.SetColumnStyle(obj.impt_data.key, 0, self.inactive_style) 326 self.imptobjs.SetColumn(obj.impt_data.key, 2, "") 327 obj.impt_data.obj = None 328 return 329 330 def set_impt_style(self, obj, style): 331 self.imptobjs.SetColumnStyle(obj.impt_data.key, 1, style) 332 return 333 334 def set_impt_active_change(self, obj): 335 if (obj.active): 336 self.imptobjs.SetColumnStyle(obj.impt_data.key, 1, 337 self.active_style) 338 pass 339 else: 340 self.imptobjs.SetColumnStyle(obj.impt_data.key, 1, 341 self.inactive_style) 342 pass 343 return 344 345 def set_impt_data_text(self, obj): 346 if (obj.itemvalue != None): 347 self.imptobjs.SetColumn(obj.impt_data.key, 2, obj.itemvalue) 348 pass 349 else: 350 self.imptobjs.SetColumn(obj.impt_data.key, 2, "") 351 pass 352 return 353 354 def remove_impt_data(self, data): 355 obj = data.obj 356 self.imptobjs.DelItem(data.key); 357 del self.impt_objs[data.type][data.name] 358 if (obj != None): 359 obj.impt_data = None 360 pass 361 return 362 363 def Timeout(self): 364 if (self.in_destroy): 365 return 366 callcount = 0 367 checkcount = 0 368 if (self.last_scan != None): 369 next = self.last_scan 370 else: 371 # Scan important objects first 372 next = self.tree.hlist.info_next("D") 373 for i in self.impt_objs.values(): 374 for j in i.values(): 375 if (j.obj != None) and hasattr(j.obj, "DoUpdate"): 376 callcount = callcount + 1 377 j.obj.DoUpdate() 378 pass 379 checkcount = checkcount + 1 380 pass 381 pass 382 pass 383 while (callcount < 100) and (checkcount < 1000) and (next != ""): 384 if (self.tree.hlist.info_hidden(next) == "1"): 385 # Not on the screen, ignore it 386 next = self.tree.hlist.info_next(next) 387 continue 388 data = self.treedata[next] 389 if (data != None) and (hasattr(data, "DoUpdate")): 390 callcount = callcount + 1 391 data.DoUpdate() 392 pass 393 next = self.tree.hlist.info_next(next) 394 checkcount = checkcount + 1 395 pass 396 397 if (next != ""): 398 self.last_scan = next 399 self.top.after(self.timer_timeout_ms, self.Timeout) 400 else: 401 self.last_scan = None 402 self.top.after(refresh_timer_time, self.Timeout) 403 pass 404 405 return 406 407 def quit(self, event=None): 408 self.mainhandler.destroy() 409 return 410 411 def OnDestroy(self, event): 412 self.in_destroy = True 413 self.closecount = len(self.mainhandler.domains) 414 closer = IPMICloser(self, self.closecount) 415 ds = list(self.mainhandler.domains.values()) 416 for v in ds: 417 v.domain_id.to_domain(closer) 418 pass 419 closer.wait_done() 420 return 421 422 def openDomain(self, event=None): 423 dialog = gui_domainDialog.OpenDomainDialog(self.mainhandler) 424 return 425 426 def savePrefs(self, event=None): 427 self.mainhandler.savePrefs() 428 return 429 430 def ExpandItem(self, item): 431 children = self.tree.hlist.info_children(item) 432 for child in children: 433 self.tree.open(child) 434 self.ExpandItem(child) 435 pass 436 return 437 438 def ExpandAll(self, event=None): 439 self.tree.open("D") 440 self.ExpandItem("D") 441 return 442 443 def CollapseItem(self, item): 444 children = self.tree.hlist.info_children(item) 445 for child in children: 446 self.tree.close(child) 447 self.ExpandItem(child) 448 pass 449 return 450 451 def CollapseAll(self, event=None): 452 self.CollapseItem("D") 453 return 454 455 def EnableEvents(self, event=None): 456 self.logevents = self.logeventsv.get() != 0 457 print("logevents = " + str(self.logevents)) 458 return 459 460 def FullEventInfo(self, event=None): 461 print("fullevents = " + str(self.fulleventsv.get())) 462 OpenIPMI.cmdlang_set_evinfo(self.fulleventsv.get()) 463 return 464 465 def new_log(self, log): 466 if (self.in_destroy): 467 return 468 # If we are at the bottom, then scroll the window, otherwise 469 # don't do any scrolling 470 (top, bottom) = self.logwindow.text.yview() 471 doscroll = bottom == 1.0 472 self.numloglines += log.count("\n") + 1 473 self.logwindow.text.insert("end", "\n" + log) 474 overrun = self.numloglines - self.maxloglines 475 if (overrun > 0): 476 self.logwindow.text.delete("1.0", str(overrun+1)+".0") 477 self.numloglines -= overrun 478 pass 479 if (doscroll): 480 self.logwindow.text.see("end") 481 return 482 483 def setup_item(self, item, active=False, type = None): 484 data = self.treedata[item] 485 data.active = active 486 data.num_warning = 0 487 data.num_severe = 0 488 data.num_critical = 0 489 data.itemvalue = None 490 if (type != None): 491 data.impt_data = self.find_impt_data(type, data.name_str) 492 if (data.impt_data != None): 493 self.setup_impt_data(data.impt_data, data) 494 pass 495 pass 496 else: 497 data.impt_data = None 498 pass 499 self.tree.hlist.item_create(item, 1, itemtype=Tix.TEXT, text="", 500 style=self.active_style) 501 if (not active): 502 self.tree.hlist.item_configure(item, 0, style=self.inactive_style) 503 pass 504 else: 505 self.tree.hlist.item_configure(item, 0, style=self.active_style) 506 pass 507 return 508 509 def cleanup_item(self, item): 510 if (self.in_destroy): 511 return 512 data = self.treedata[item] 513 if (data == None): 514 return 515 if (data.impt_data != None): 516 self.cleanup_impt_data(data) 517 pass 518 parent = self.parent_item(item) 519 if (parent == None): 520 return 521 while (data.num_warning > 0): 522 data.num_warning = data.num_warning - 1; 523 self.decr_item_warning(parent); 524 pass 525 while (data.num_severe > 0): 526 data.num_severe = data.num_severe - 1; 527 self.decr_item_severe(parent); 528 pass 529 while (data.num_critical > 0): 530 data.num_critical = data.num_critical - 1; 531 self.decr_item_critical(parent); 532 pass 533 return 534 535 def add_domain(self, d): 536 if (self.in_destroy): 537 return 538 d.name_str = str(d) 539 item = "D." + str(self.itemval) 540 self.itemval += 1 541 d.treeroot = item 542 self.tree.hlist.add(d.treeroot, itemtype=Tix.TEXT, text=d.name_str) 543 self.tree.setmode(d.treeroot, "open") 544 self.tree.close(d.treeroot) 545 self.treedata[d.treeroot] = d 546 self.setup_item(d.treeroot, active=True) 547 548 lstr = d.treeroot + ".E" 549 self.tree.hlist.add(lstr, itemtype=Tix.TEXT, text="Entities") 550 self.tree.setmode(lstr, "none") 551 self.tree.close(lstr) 552 self.tree.hlist.hide_entry(lstr) 553 self.treedata[lstr] = IPMITreeDummyItem(lstr) 554 self.setup_item(lstr, active=True) 555 556 lstr = d.treeroot + ".M" 557 self.tree.hlist.add(lstr, itemtype=Tix.TEXT, text="MCs") 558 self.tree.setmode(lstr, "none") 559 self.tree.close(lstr) 560 self.tree.hlist.hide_entry(lstr) 561 self.treedata[lstr] = IPMITreeDummyItem(lstr) 562 self.setup_item(lstr, active=True) 563 564 lstr = d.treeroot + ".C" 565 self.tree.hlist.add(lstr, itemtype=Tix.TEXT, text="Connections") 566 self.tree.setmode(lstr, "none") 567 self.tree.close(lstr) 568 self.tree.hlist.hide_entry(lstr) 569 self.treedata[lstr] = IPMITreeDummyItem(lstr) 570 self.setup_item(lstr, active=True) 571 572 return 573 574 def item_sethide(self, parent, item): 575 mode = self.tree.getmode(parent) 576 if (mode == "open"): 577 self.tree.hlist.hide_entry(item) 578 elif (mode == "close"): 579 pass 580 else: 581 self.tree.setmode(parent, "open") 582 self.tree.hlist.hide_entry(item) 583 pass 584 return 585 586 def prepend_item(self, o, name, value, data=None): 587 if (self.in_destroy): 588 return 589 item = o.treeroot + '.' + str(self.itemval) 590 if (data == None): 591 data = IPMITreeDummyItem(item) 592 pass 593 data.name_str = name 594 self.itemval += 1 595 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=name + ":", at=0) 596 mode = self.tree.getmode(o.treeroot) 597 self.item_sethide(o.treeroot, item) 598 if (value == None): 599 self.tree.hlist.item_create(item, 1, itemtype=Tix.TEXT, text="", 600 style=self.active_style) 601 self.tree.hlist.item_configure(item, 0, style=self.inactive_style) 602 else: 603 self.tree.hlist.item_create(item, 1, itemtype=Tix.TEXT, text=value, 604 style=self.active_style) 605 self.tree.hlist.item_configure(item, 0, style=self.active_style) 606 pass 607 self.treedata[item] = data 608 return item 609 610 def append_item(self, o, name, value, data=None, parent=None): 611 if (self.in_destroy): 612 return 613 if (parent == None): 614 parent = o.treeroot 615 pass 616 item = parent + '.' + str(self.itemval) 617 if (data == None): 618 data = IPMITreeDummyItem(item) 619 pass 620 data.name_str = name 621 self.itemval += 1 622 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=name + ":") 623 mode = self.tree.getmode(parent) 624 if (mode == "open"): 625 self.tree.hlist.hide_entry(item) 626 elif (mode == "close"): 627 pass 628 else: 629 self.tree.setmode(parent, "open") 630 self.tree.hlist.hide_entry(item) 631 pass 632 if (value == None): 633 self.tree.hlist.item_create(item, 1, itemtype=Tix.TEXT, text="", 634 style=self.active_style) 635 self.tree.hlist.item_configure(item, 0, style=self.inactive_style) 636 else: 637 self.tree.hlist.item_create(item, 1, itemtype=Tix.TEXT, text=value, 638 style=self.active_style) 639 self.tree.hlist.item_configure(item, 0, style=self.active_style) 640 pass 641 self.treedata[item] = data 642 return item 643 644 def set_item_text(self, item, value): 645 if (self.in_destroy): 646 return 647 data = self.treedata[item] 648 data.itemvalue = value 649 if (hasattr(data, "impt_data") and (data.impt_data != None)): 650 self.set_impt_data_text(data) 651 pass 652 if (value == None): 653 self.tree.hlist.item_configure(item, 1, text="") 654 self.tree.hlist.item_configure(item, 0, style=self.inactive_style) 655 pass 656 else: 657 self.tree.hlist.item_configure(item, 1, text=value) 658 if (hasattr(data, "active")): 659 if (data.active): 660 self.set_item_color(item) 661 pass 662 pass 663 else: 664 self.tree.hlist.item_configure(item, 0, style=self.active_style) 665 pass 666 pass 667 return 668 669 def set_item_inactive(self, item): 670 if (self.in_destroy): 671 return 672 data = self.treedata[item] 673 data.active = False 674 if (hasattr(data, "impt_data") and (data.impt_data != None)): 675 self.set_impt_active_change(data) 676 pass 677 self.tree.hlist.item_configure(item, 0, style=self.inactive_style) 678 return 679 680 def set_item_active(self, item): 681 if (self.in_destroy): 682 return 683 data = self.treedata[item] 684 data.active = True 685 self.set_item_color(item) 686 return 687 688 def parent_item(self, item): 689 idx = item.rfind(".") 690 if (idx == -1): 691 return None 692 return item[0:idx] 693 694 def set_item_color(self, item): 695 data = self.treedata[item] 696 if (data.num_critical > 0): 697 style = self.critical_style 698 elif (data.num_severe > 0): 699 style=self.severe_style 700 elif (data.num_warning > 0): 701 style=self.warn_style 702 else: 703 style=self.active_style 704 pass 705 if (hasattr(data, "impt_data") and (data.impt_data != None)): 706 self.set_impt_style(data, style) 707 pass 708 self.tree.hlist.item_configure(item, 0, style=style) 709 return 710 711 def incr_item_warning(self, item): 712 if (self.in_destroy): 713 return 714 data = self.treedata[item] 715 if (data == None): 716 return 717 parent = self.parent_item(item) 718 if (parent != None): 719 self.incr_item_warning(parent); 720 pass 721 data.num_warning = data.num_warning + 1 722 if (not data.active): 723 return 724 if (data.num_critical > 0): 725 return 726 if (data.num_severe > 0): 727 return 728 if (data.num_warning == 1): 729 self.tree.hlist.item_configure(item, 0, style=self.warn_style) 730 pass 731 return 732 733 def decr_item_warning(self, item): 734 if (self.in_destroy): 735 return 736 data = self.treedata[item] 737 if (data == None): 738 return 739 parent = self.parent_item(item) 740 if (parent != None): 741 self.decr_item_warning(parent); 742 pass 743 data.num_warning = data.num_warning - 1 744 if (not data.active): 745 return 746 if (data.num_critical > 0): 747 return 748 if (data.num_severe > 0): 749 return 750 if (data.num_warning > 0): 751 return 752 self.tree.hlist.item_configure(item, 0, style=self.active_style) 753 return 754 755 def incr_item_severe(self, item): 756 if (self.in_destroy): 757 return 758 data = self.treedata[item] 759 if (data == None): 760 return 761 parent = self.parent_item(item) 762 if (parent != None): 763 self.incr_item_severe(parent); 764 pass 765 data.num_severe = data.num_severe + 1 766 if (not data.active): 767 return 768 if (data.num_critical > 0): 769 return 770 if (data.num_severe == 1): 771 self.tree.hlist.item_configure(item, 0, style=self.severe_style) 772 pass 773 return 774 775 def decr_item_severe(self, item): 776 if (self.in_destroy): 777 return 778 data = self.treedata[item] 779 if (data == None): 780 return 781 parent = self.parent_item(item) 782 if (parent != None): 783 self.decr_item_severe(parent); 784 pass 785 data.num_severe = data.num_severe - 1 786 if (not data.active): 787 return 788 if (data.num_critical > 0): 789 return 790 if (data.num_severe > 0): 791 return 792 if (data.num_warning > 0): 793 self.tree.hlist.item_configure(item, 0, style=self.warn_style) 794 return 795 self.tree.hlist.item_configure(item, 0, style=self.active_style) 796 return 797 798 def incr_item_critical(self, item): 799 if (self.in_destroy): 800 return 801 data = self.treedata[item] 802 if (data == None): 803 return 804 parent = self.parent_item(item) 805 if (parent != None): 806 self.incr_item_critical(parent); 807 pass 808 data.num_critical = data.num_critical + 1 809 if (not data.active): 810 return 811 if (data.num_critical == 1): 812 self.tree.hlist.item_configure(item, 0, style=self.critical_style) 813 pass 814 return 815 816 def decr_item_critical(self, item): 817 if (self.in_destroy): 818 return 819 data = self.treedata[item] 820 if (data == None): 821 return 822 parent = self.parent_item(item) 823 if (parent != None): 824 self.decr_item_critical(parent); 825 pass 826 data.num_critical = data.num_critical - 1 827 if (not data.active): 828 return 829 if (data.num_critical > 0): 830 return 831 if (data.num_severe > 0): 832 self.tree.hlist.item_configure(item, 0, style=self.severe_style) 833 return 834 if (data.num_warning > 0): 835 self.tree.hlist.item_configure(item, 0, style=self.warn_style) 836 return 837 self.tree.hlist.item_configure(item, 0, style=self.active_style) 838 return 839 840 def TreeMenu(self, event): 841 w = event.widget 842 item = w.nearest(event.y) 843 data = self.treedata[item] 844 if (data != None) and (hasattr(data, "HandleMenu")): 845 data.HandleMenu(event) 846 pass 847 return 848 849 def TreeExpanded(self, event): 850 item = event.GetItem() 851 data = self.tree.GetPyData(item) 852 if (data != None) and (hasattr(data, "HandleExpand")): 853 data.HandleExpand(event) 854 pass 855 return 856 857 def remove_domain(self, d): 858 if (self.in_destroy): 859 return 860 if (hasattr(d, "treeroot")): 861 self.cleanup_item(d.treeroot) 862 self.tree.hlist.delete_entry(d.treeroot) 863 pass 864 return 865 866 def add_connection(self, d, c): 867 if (self.in_destroy): 868 return 869 parent = d.treeroot + ".C" 870 item = parent + '.' + str(self.itemval) 871 self.itemval += 1 872 c.treeroot = item 873 c.name_str = str(c) 874 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=c.name_str) 875 self.tree.setmode(item, "none") 876 self.tree.close(item) 877 self.item_sethide(parent, item) 878 self.treedata[item] = c 879 self.setup_item(item, active=True) 880 return 881 882 def add_port(self, c, p): 883 if (self.in_destroy): 884 return 885 item = c.treeroot + '.' + str(self.itemval) 886 self.itemval += 1 887 p.treeroot = item 888 p.name_str = str(p) 889 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=p.name_str) 890 self.tree.setmode(item, "none") 891 self.tree.close(item) 892 self.item_sethide(c.treeroot, item) 893 self.treedata[item] = p 894 self.setup_item(item, active=True) 895 return 896 897 def remove_port(self, p): 898 if (self.in_destroy): 899 return 900 if (hasattr(p, "treeroot")): 901 self.cleanup_item(p.treeroot) 902 self.tree.hlist.delete_entry(p.treeroot) 903 del self.treedata[p.treeroot] 904 pass 905 return 906 907 def add_entity(self, d, e, parent=None): 908 if (self.in_destroy): 909 return 910 if (parent == None): 911 parent = d.treeroot + ".E" 912 pass 913 else: 914 parent = parent.treeroot 915 pass 916 e.name_str = str(e) 917 item = parent + '.' + str(self.itemval) 918 self.itemval += 1 919 e.treeroot = item 920 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=e.name_str) 921 self.tree.setmode(item, "open") 922 self.tree.close(item) 923 self.item_sethide(parent, item) 924 self.treedata[item] = e 925 self.setup_item(item, type="entity") 926 927 lstr = item + ".S" 928 self.tree.hlist.add(lstr, itemtype=Tix.TEXT, text="Sensors") 929 self.tree.setmode(lstr, "none") 930 self.tree.close(lstr) 931 self.tree.hlist.hide_entry(lstr) 932 self.treedata[lstr] = IPMITreeDummyItem(lstr) 933 self.setup_item(lstr, active=True) 934 935 lstr = item + ".C" 936 self.tree.hlist.add(lstr, itemtype=Tix.TEXT, text="Controls") 937 self.tree.setmode(lstr, "none") 938 self.tree.close(lstr) 939 self.tree.hlist.hide_entry(lstr) 940 self.treedata[lstr] = IPMITreeDummyItem(lstr) 941 self.setup_item(lstr, active=True) 942 return 943 944 def reparent_entity(self, d, e, parent): 945 if (self.in_destroy): 946 return 947 self.add_entity(d, e, parent) 948 return 949 950 def remove_entity(self, e): 951 if (self.in_destroy): 952 return 953 if (hasattr(e, "treeroot")): 954 self.cleanup_item(e.treeroot) 955 self.tree.hlist.delete_entry(e.treeroot) 956 del self.treedata[e.treeroot] 957 pass 958 return 959 960 def add_mc(self, d, m): 961 if (self.in_destroy): 962 return 963 parent = d.treeroot + ".M" 964 m.name_str = str(m) 965 item = parent + "." + str(self.itemval) 966 self.itemval += 1 967 m.treeroot = item 968 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=m.name_str) 969 self.tree.setmode(item, "none") 970 self.tree.close(item) 971 self.item_sethide(parent, item) 972 self.treedata[item] = m 973 self.setup_item(item) 974 return 975 976 def remove_mc(self, m): 977 if (self.in_destroy): 978 return 979 if (hasattr(m, "treeroot")): 980 self.cleanup_item(m.treeroot) 981 self.tree.hlist.delete_entry(m.treeroot) 982 del self.treedata[m.treeroot] 983 pass 984 return 985 986 def add_sensor(self, e, s): 987 if (self.in_destroy): 988 return 989 parent = e.treeroot + ".S" 990 s.name_str = str(s) 991 item = parent + "." + str(self.itemval) 992 self.itemval += 1 993 s.treeroot = item 994 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=s.name_str) 995 self.tree.setmode(item, "none") 996 self.tree.close(item) 997 self.item_sethide(parent, item) 998 self.treedata[item] = s 999 self.setup_item(item, active=True, type="sensor") 1000 return 1001 1002 def remove_sensor(self, s): 1003 if (self.in_destroy): 1004 return 1005 if (hasattr(s, "treeroot")): 1006 self.cleanup_item(s.treeroot) 1007 self.tree.hlist.delete_entry(s.treeroot) 1008 del self.treedata[s.treeroot] 1009 pass 1010 return 1011 1012 def add_control(self, e, c): 1013 if (self.in_destroy): 1014 return 1015 parent = e.treeroot + ".C" 1016 c.name_str = str(c) 1017 item = parent + "." + str(self.itemval) 1018 self.itemval += 1 1019 c.treeroot = item 1020 self.tree.hlist.add(item, itemtype=Tix.TEXT, text=c.name_str) 1021 self.tree.setmode(item, "none") 1022 self.tree.close(item) 1023 self.item_sethide(parent, item) 1024 self.treedata[item] = c 1025 self.setup_item(item, active=True, type="control") 1026 return 1027 1028 def remove_control(self, c): 1029 if (self.in_destroy): 1030 return 1031 if (hasattr(c, "treeroot")): 1032 self.cleanup_item(c.treeroot) 1033 self.tree.hlist.delete_entry(c.treeroot) 1034 del self.treedata[c.treeroot] 1035 pass 1036 return 1037 1038 # XML preferences handling 1039 def getTag(self): 1040 return "guiparms" 1041 1042 def SaveInfo(self, doc, elem): 1043 elem.setAttribute("windowwidth", str(self.vpane.winfo_width())) 1044 elem.setAttribute("windowheight", str(self.vpane.winfo_height())) 1045 spos = int(self.vpane.panecget("objectsevents", "-size")) 1046 ipos = int(self.vpane.panecget("importantobjects", "-size")) 1047 elem.setAttribute("sashposition", str(spos)) 1048 elem.setAttribute("isashposition", str(spos + ipos)) 1049 elem.setAttribute("bsashposition", 1050 str(self.hpane.panecget("objects", "-size"))) 1051 #elem.setAttribute("treenamewidth", str(self.tree.GetColumnWidth(0))) 1052 elem.setAttribute("logevents", str(self.logevents)) 1053 elem.setAttribute("fullevents", str(self.fulleventsv != 0)) 1054 for i in list(self.impt_objs.values()): 1055 for j in list(i.values()): 1056 o = doc.createElement("watch") 1057 o.setAttribute("type", j.type) 1058 o.setAttribute("name", j.name) 1059 elem.appendChild(o) 1060 pass 1061 pass 1062 return 1063 pass 1064 1065def GetAttrInt(attr, default): 1066 try: 1067 return int(attr.nodeValue) 1068 except Exception as e: 1069 _oi_logging.error("Error getting init parm " + attr.nodeName + 1070 ": " + str(e)) 1071 return default 1072 1073def GetAttrBool(attr, default): 1074 if (attr.nodeValue.lower() == "true") or (attr.nodeValue == "1"): 1075 return True 1076 elif (attr.nodeValue.lower() == "false") or (attr.nodeValue == "0"): 1077 return False 1078 else: 1079 _oi_logging.error ("Error getting init parm " + attr.nodeName) 1080 pass 1081 return default 1082 1083class _GUIRestore(_saveprefs.RestoreHandler): 1084 def __init__(self, mainhandler): 1085 _saveprefs.RestoreHandler.__init__(self, mainhandler, "guiparms") 1086 return 1087 1088 def restore(self, mainhandler, node): 1089 global init_windowheight 1090 global init_windowwidth 1091 global init_sashposition 1092 global init_bsashposition 1093 global init_isashposition 1094 global init_treenamewidth 1095 global init_fullevents 1096 global init_logevents 1097 global init_impt_objs 1098 1099 for i in range(0, node.attributes.length): 1100 attr = node.attributes.item(i) 1101 if (attr.nodeName == "windowwidth"): 1102 init_windowwidth = GetAttrInt(attr, init_windowwidth) 1103 elif (attr.nodeName == "windowheight"): 1104 init_windowheight = GetAttrInt(attr, init_windowheight) 1105 elif (attr.nodeName == "sashposition"): 1106 init_sashposition = GetAttrInt(attr, init_sashposition) 1107 elif (attr.nodeName == "bsashposition"): 1108 init_bsashposition = GetAttrInt(attr, init_bsashposition) 1109 elif (attr.nodeName == "isashposition"): 1110 init_isashposition = GetAttrInt(attr, init_isashposition) 1111 elif (attr.nodeName == "treenamewidth"): 1112 init_treenamewidth = GetAttrInt(attr, init_treenamewidth) 1113 elif (attr.nodeName == "logevents"): 1114 init_logevents = GetAttrBool(attr, init_logevents) 1115 elif (attr.nodeName == "fullevents"): 1116 init_fullevents = GetAttrBool(attr, init_fullevents) 1117 pass 1118 pass 1119 for i in node.childNodes: 1120 if (i.nodeName == "watch"): 1121 name = None 1122 type = None 1123 for j in range(0, i.attributes.length): 1124 attr = i.attributes.item(j) 1125 if (attr.nodeName == "name"): 1126 name = attr.nodeValue 1127 elif (attr.nodeName == "type"): 1128 type = attr.nodeValue 1129 pass 1130 if (name != None) and (type != None): 1131 init_impt_objs.append( (type, name) ) 1132 pass 1133 pass 1134 pass 1135 return 1136 1137 pass 1138 1139 1140