home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Tools / IDE / Wlists.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  11.6 KB  |  470 lines

  1. import Wbase
  2. import Wkeys
  3. import Scrap
  4. import string
  5. import Evt
  6. import Events
  7. import Qd
  8. import Win
  9. import Lists
  10.  
  11.  
  12. class List(Wbase.SelectableWidget):
  13.     
  14.     """Standard list widget."""
  15.     
  16.     LDEF_ID = 0
  17.     
  18.     def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1, typingcasesens=0):
  19.         if items is None:
  20.             items = []
  21.         self.items = items
  22.         Wbase.SelectableWidget.__init__(self, possize)
  23.         self._selected = 0
  24.         self._enabled = 1
  25.         self._list = None
  26.         self._cols = cols
  27.         self._callback = callback
  28.         self._flags = flags
  29.         self.typingcasesens = typingcasesens
  30.         self.lasttyping = ""
  31.         self.lasttime = Evt.TickCount()
  32.         self.timelimit = 30
  33.         self.setitems(items)
  34.         self.drawingmode = 0
  35.     
  36.     def open(self):
  37.         self.setdrawingmode(0)
  38.         self.createlist()
  39.         self.setdrawingmode(1)
  40.     
  41.     def createlist(self):
  42.         import List
  43.         self._calcbounds()
  44.         self.SetPort()
  45.         rect = self._bounds
  46.         rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
  47.         self._list = List.LNew(rect, (0, 0, self._cols, 0), (0, 0), self.LDEF_ID, self._parentwindow.wid,
  48.                     0, 1, 0, 1)
  49.         if self.drawingmode:
  50.             self._list.LSetDrawingMode(0)
  51.         self._list.selFlags = self._flags
  52.         self.setitems(self.items)
  53.         if hasattr(self, "_sel"):
  54.             self.setselection(self._sel)
  55.             del self._sel
  56.     
  57.     def adjust(self, oldbounds):
  58.         self.SetPort()
  59.         if self._selected:
  60.             Win.InvalRect(Qd.InsetRect(oldbounds, -3, -3))
  61.             Win.InvalRect(Qd.InsetRect(self._bounds, -3, -3))
  62.         else:
  63.             Win.InvalRect(oldbounds)
  64.             Win.InvalRect(self._bounds)
  65.         if oldbounds[:2] == self._bounds[:2]:
  66.             # set visRgn to empty, to prevent nasty drawing side effect of LSize()
  67.             Qd.RectRgn(self._parentwindow.wid.GetWindowPort().visRgn, (0, 0, 0, 0))
  68.             # list still has the same upper/left coordinates, use LSize
  69.             l, t, r, b = self._bounds
  70.             width = r - l - 17
  71.             height = b - t - 2
  72.             self._list.LSize(width, height)
  73.             # now *why* doesn't the list manager recalc the cellrect???
  74.             l, t, r, b = self._list.LRect((0,0))
  75.             cellheight = b - t
  76.             self._list.LCellSize((width, cellheight))
  77.             # reset visRgn
  78.             self._parentwindow.wid.CalcVis()
  79.         else:
  80.             # oh well, since the list manager doesn't have a LMove call,
  81.             # we have to make the list all over again...
  82.             sel = self.getselection()
  83.             topcell = self.gettopcell()
  84.             self._list = None
  85.             self.setdrawingmode(0)
  86.             self.createlist()
  87.             self.setselection(sel)
  88.             self.settopcell(topcell)
  89.             self.setdrawingmode(1)
  90.     
  91.     def close(self):
  92.         self._list = None
  93.         self._callback = None
  94.         self.items = []
  95.         Wbase.SelectableWidget.close(self)
  96.     
  97.     def set(self, items):
  98.         self.setitems(items)
  99.     
  100.     def setitems(self, items):
  101.         self.items = items
  102.         the_list = self._list
  103.         if not self._parent or not self._list:
  104.             return
  105.         self.setdrawingmode(0)
  106.         topcell = self.gettopcell()
  107.         the_list.LDelRow(0, 1)
  108.         the_list.LAddRow(len(self.items), 0)
  109.         self_itemrepr = self.itemrepr
  110.         set_cell = the_list.LSetCell
  111.         for i in range(len(items)):
  112.             set_cell(self_itemrepr(items[i]), (0, i))
  113.         self.settopcell(topcell)
  114.         self.setdrawingmode(1)
  115.     
  116.     def click(self, point, modifiers):
  117.         if not self._enabled:
  118.             return
  119.         isdoubleclick = self._list.LClick(point, modifiers)
  120.         if self._callback:
  121.             Wbase.CallbackCall(self._callback, 0, isdoubleclick)
  122.         return 1
  123.     
  124.     def key(self, char, event):
  125.         (what, message, when, where, modifiers) = event
  126.         sel = self.getselection()
  127.         newselection = []
  128.         if char == Wkeys.uparrowkey:
  129.             if len(sel) >= 1 and min(sel) > 0:
  130.                 newselection = [min(sel) - 1]
  131.             else:
  132.                 newselection = [0]
  133.         elif char == Wkeys.downarrowkey:
  134.             if len(sel) >= 1 and max(sel) < (len(self.items) - 1):
  135.                     newselection = [max(sel) + 1]
  136.             else:
  137.                 newselection = [len(self.items) - 1]
  138.         else:
  139.             modifiers = 0
  140.             if (self.lasttime + self.timelimit) < Evt.TickCount():
  141.                 self.lasttyping = ""
  142.             if self.typingcasesens:
  143.                 self.lasttyping = self.lasttyping + char
  144.             else:
  145.                 self.lasttyping = self.lasttyping + string.lower(char)
  146.             self.lasttime = Evt.TickCount()
  147.             i = self.findmatch(self.lasttyping)
  148.             newselection = [i]
  149.         if modifiers & Events.shiftKey and not self._list.selFlags & Lists.lOnlyOne:
  150.             newselection = newselection + sel
  151.         self.setselection(newselection)
  152.         self._list.LAutoScroll()
  153.         self.click((-1, -1), 0)
  154.     
  155.     def findmatch(self, tag):
  156.         lower = string.lower
  157.         items = self.items
  158.         typingcasesens = self.typingcasesens
  159.         taglen = len(tag)
  160.         match = '\377' * 100
  161.         match_i = -1
  162.         for i in range(len(items)):
  163.             item = str(items[i])
  164.             if not typingcasesens:
  165.                 item = lower(item)
  166.             if tag <= item < match:
  167.                 match = item
  168.                 match_i = i
  169.         if match_i >= 0:
  170.             return match_i
  171.         else:
  172.             return len(items) - 1
  173.     
  174.     def domenu_copy(self, *args):
  175.         sel = self.getselection()
  176.         selitems = []
  177.         for i in sel:
  178.             selitems.append(str(self.items[i]))
  179.         text = string.join(selitems, '\r')
  180.         if text:
  181.             Scrap.ZeroScrap()
  182.             Scrap.PutScrap('TEXT', text)
  183.     
  184.     def can_copy(self, *args):
  185.         return len(self.getselection()) <> 0
  186.     
  187.     def domenu_selectall(self, *args):
  188.         self.selectall()
  189.     
  190.     def can_selectall(self, *args):
  191.         return not self._list.selFlags & Lists.lOnlyOne
  192.     
  193.     def selectall(self):
  194.         if not self._list.selFlags & Lists.lOnlyOne:
  195.             self.setselection(range(len(self.items)))
  196.             self._list.LAutoScroll()
  197.             self.click((-1, -1), 0)
  198.     
  199.     def getselection(self):
  200.         if not self._parent or not self._list:
  201.             if hasattr(self, "_sel"):
  202.                 return self._sel
  203.             return []
  204.         items = []
  205.         point = (0,0)
  206.         while 1:
  207.             ok, point = self._list.LGetSelect(1, point)
  208.             if not ok:
  209.                 break
  210.             items.append(point[1])
  211.             point = point[0], point[1]+1
  212.         return items
  213.     
  214.     def setselection(self, selection):
  215.         if not self._parent or not self._list:
  216.             self._sel = selection
  217.             return
  218.         set_sel = self._list.LSetSelect
  219.         for i in range(len(self.items)):
  220.             if i in selection:
  221.                 set_sel(1, (0, i))
  222.             else:
  223.                 set_sel(0, (0, i))
  224.         self._list.LAutoScroll()
  225.     
  226.     def getselectedobjects(self):
  227.         sel = self.getselection()
  228.         objects = []
  229.         for i in sel:
  230.             objects.append(self.items[i])
  231.         return objects
  232.     
  233.     def setselectedobjects(self, objects):
  234.         sel = []
  235.         for o in objects:
  236.             try:
  237.                 sel.append(self.items.index(o))
  238.             except:
  239.                 pass
  240.         self.setselection(sel)
  241.     
  242.     def gettopcell(self):
  243.         l, t, r, b = self._bounds
  244.         t = t + 1
  245.         cl, ct, cr, cb = self._list.LRect((0, 0))
  246.         cellheight = cb - ct
  247.         return (t - ct) / cellheight
  248.     
  249.     def settopcell(self, topcell):
  250.         top = self.gettopcell()
  251.         diff = topcell - top
  252.         self._list.LScroll(0, diff)
  253.     
  254.     def draw(self, visRgn = None):
  255.         if self._visible:
  256.             if not visRgn:
  257.                 visRgn = self._parentwindow.wid.GetWindowPort().visRgn
  258.             self._list.LUpdate(visRgn)
  259.             Qd.FrameRect(self._bounds)
  260.             if self._selected and self._activated:
  261.                 self.drawselframe(1)
  262.     
  263.     def select(self, onoff, isclick = 0):
  264.         if Wbase.SelectableWidget.select(self, onoff):
  265.             return
  266.         self.SetPort()
  267.         self.drawselframe(onoff)
  268.     
  269.     def activate(self, onoff):
  270.         self._activated = onoff
  271.         if self._visible:
  272.             self._list.LActivate(onoff)
  273.             if self._selected:
  274.                 self.drawselframe(onoff)
  275.     
  276.     def get(self):
  277.         return self.items
  278.     
  279.     def itemrepr(self, item):
  280.         return str(item)[:255]
  281.     
  282.     def __getitem__(self, index):
  283.         return self.items[index]
  284.     
  285.     def __setitem__(self, index, item):
  286.         if self._parent and self._list:
  287.             self._list.LSetCell(self.itemrepr(item), (0, index))
  288.         self.items[index] = item
  289.     
  290.     def __delitem__(self, index):
  291.         if self._parent and self._list:
  292.             self._list.LDelRow(1, index)
  293.         del self.items[index]
  294.     
  295.     def __getslice__(self, a, b):
  296.         return self.items[a:b]
  297.     
  298.     def __delslice__(self, a, b):
  299.         if b-a:
  300.             if self._parent and self._list:
  301.                 self._list.LDelRow(b-a, a)
  302.             del self.items[a:b]
  303.     
  304.     def __setslice__(self, a, b, items):
  305.         if self._parent and self._list:
  306.             l = len(items)
  307.             the_list = self._list
  308.             self.setdrawingmode(0)
  309.             if b-a:
  310.                 if b > len(self.items):
  311.                     # fix for new 1.5 "feature" where b is sys.maxint instead of len(self)...
  312.                     # LDelRow doesn't like maxint.
  313.                     b = len(self.items)
  314.                 the_list.LDelRow(b-a, a)
  315.             the_list.LAddRow(l, a)
  316.             self_itemrepr = self.itemrepr
  317.             set_cell = the_list.LSetCell
  318.             for i in range(len(items)):
  319.                 set_cell(self_itemrepr(items[i]), (0, i + a))
  320.             self.items[a:b] = items
  321.             self.setdrawingmode(1)
  322.         else:
  323.             self.items[a:b] = items
  324.     
  325.     def __len__(self):
  326.         return len(self.items)
  327.     
  328.     def append(self, item):
  329.         if self._parent and self._list:
  330.             index = len(self.items)
  331.             self._list.LAddRow(1, index)
  332.             self._list.LSetCell(self.itemrepr(item), (0, index))
  333.         self.items.append(item)
  334.     
  335.     def remove(self, item):
  336.         index = self.items.index(item)
  337.         self.__delitem__(index)
  338.     
  339.     def index(self, item):
  340.         return self.items.index(item)
  341.     
  342.     def insert(self, index, item):
  343.         if index < 0:
  344.             index = 0
  345.         if self._parent and self._list:
  346.             self._list.LAddRow(1, index)
  347.             self._list.LSetCell(self.itemrepr(item), (0, index))
  348.         self.items.insert(index, item)
  349.     
  350.     def setdrawingmode(self, onoff):
  351.         if onoff:
  352.             self.drawingmode = self.drawingmode - 1
  353.             if self.drawingmode == 0 and self._list is not None:
  354.                 self._list.LSetDrawingMode(1)
  355.                 if self._visible:
  356.                     bounds = l, t, r, b = Qd.InsetRect(self._bounds, 1, 1)
  357.                     cl, ct, cr, cb = self._list.LRect((0, len(self.items)-1))
  358.                     if cb < b:
  359.                         self.SetPort()
  360.                         Qd.EraseRect((l, cb, cr, b))
  361.                     self._list.LUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
  362.                     Win.ValidRect(bounds)
  363.         else:
  364.             if self.drawingmode == 0 and self._list is not None:
  365.                 self._list.LSetDrawingMode(0)
  366.             self.drawingmode = self.drawingmode + 1
  367.  
  368.  
  369. class TwoLineList(List):
  370.     
  371.     LDEF_ID = 468
  372.     
  373.     def createlist(self):
  374.         import List
  375.         self._calcbounds()
  376.         self.SetPort()
  377.         rect = self._bounds
  378.         rect = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-1
  379.         self._list = List.LNew(rect, (0, 0, 1, 0), (0, 28), self.LDEF_ID, self._parentwindow.wid,
  380.                     0, 1, 0, 1)
  381.         self.set(self.items)
  382.     
  383.  
  384. class ResultsWindow:
  385.     
  386.     """Simple results window. The user cannot make this window go away completely:
  387.     closing it will just hide it. It will remain in the windows list. The owner of this window
  388.     should call the done() method to indicate it's done with it.
  389.     """
  390.     
  391.     def __init__(self, possize=None, title="Results", callback=None):
  392.         import W
  393.         if possize is None:
  394.             possize = (500, 200)
  395.         self.w = W.Window(possize, title, minsize=(200, 100))
  396.         self.w.results = W.TwoLineList((-1, -1, 1, -14), callback=None)
  397.         self.w.bind("<close>", self.hide)
  398.         self.w.open()
  399.         self._done = 0
  400.     
  401.     def done(self):
  402.         self._done = 1
  403.         if not self.w.isvisible():
  404.             self.w.close()
  405.     
  406.     def hide(self):
  407.         if not self._done:
  408.             self.w.show(0)
  409.             return -1
  410.     
  411.     def append(self, msg):
  412.         if not self.w.isvisible():
  413.             self.w.show(1)
  414.             self.w.select()
  415.         msg = string.replace(msg, '\n', '\r')
  416.         self.w.results.append(msg)
  417.         self.w.results.setselection([len(self.w.results)-1])
  418.     
  419.     def __getattr__(self, attr):
  420.         return getattr(self.w.results, attr)
  421.  
  422.  
  423. class MultiList(List):
  424.     
  425.     """XXX Experimantal!!!"""
  426.     
  427.     def setitems(self, items):
  428.         self.items = items
  429.         if not self._parent or not self._list:
  430.             return
  431.         self._list.LDelRow(0, 1)
  432.         self.setdrawingmode(0)
  433.         self._list.LAddRow(len(self.items), 0)
  434.         self_itemrepr = self.itemrepr
  435.         set_cell = self._list.LSetCell
  436.         for i in range(len(items)):
  437.             row = items[i]
  438.             for j in range(len(row)):
  439.                 item = row[j]
  440.                 set_cell(self_itemrepr(item), (j, i))
  441.         self.setdrawingmode(1)
  442.     
  443.     def getselection(self):
  444.         if not self._parent or not self._list:
  445.             if hasattr(self, "_sel"):
  446.                 return self._sel
  447.             return []
  448.         items = []
  449.         point = (0,0)
  450.         while 1:
  451.             ok, point = self._list.LGetSelect(1, point)
  452.             if not ok:
  453.                 break
  454.             items.append(point[1])
  455.             point = point[0], point[1]+1
  456.         return items
  457.     
  458.     def setselection(self, selection):
  459.         if not self._parent or not self._list:
  460.             self._sel = selection
  461.             return
  462.         set_sel = self._list.LSetSelect
  463.         for i in range(len(self.items)):
  464.             if i in selection:
  465.                 set_sel(1, (0, i))
  466.             else:
  467.                 set_sel(0, (0, i))
  468.         #self._list.LAutoScroll()
  469.  
  470.