[IronLute-CVS] ironlute/gtk handletag.py,1.3,1.4 outlinewidget.py,1.3,1.4
Status: Pre-Alpha
Brought to you by:
thejerf
From: Jeremy B. <th...@us...> - 2005-05-08 20:57:23
|
Update of /cvsroot/ironlute/ironlute/gtk In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16922 Modified Files: handletag.py outlinewidget.py Log Message: Towards functional outliner; got some stuff in here I wouldn't care to replicate if I lose it. Index: outlinewidget.py =================================================================== RCS file: /cvsroot/ironlute/ironlute/gtk/outlinewidget.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** outlinewidget.py 7 May 2005 20:11:52 -0000 1.3 --- outlinewidget.py 8 May 2005 20:57:14 -0000 1.4 *************** *** 2,5 **** --- 2,26 ---- * Change philosophy. (I think that I have it covered, but I might be wrong. + + Buffer Hypothesis: + + This is just a hypothesis but it seems to fit the facts. + + The buffer seems to store lines as first-class citizens in its data + models. When you request the 5th line, you really get the fifth line. + + Iterators and marks, on the other hand, seem derived, despite what + you'd think. A mark is only updated when the GUI regains control; if + you insert some text before a mark, then request the iterator for that + mark, you may not get what you expect. + + In particular, I had a problem with creating new lines, and not being + able to retrieve the nodes after those lines until after the GUI + updated itself. + + This explains why some parts of this code still play with line + numbers; you can't keep retrieving the iterator for the next node, + because it hasn't moved yet, and you end up with all the nodes being + inserted backwards. """ *************** *** 29,32 **** --- 50,55 ---- class OutlineWidget(gtk.TextView, guiSupport.IronLuteOutlineFrame): def __init__(self, rootHandle, **kw): + self.magic = False + guiSupport.IronLuteOutlineFrame.__init__(self, initialView = rootHandle) *************** *** 48,52 **** self.insert = it self.selection_bound = it - # event handlers self.connect("key-press-event", self.keypress) --- 71,74 ---- *************** *** 63,68 **** changed.""" # If the change is user initiated, it has to be near the ! # cursor. ! self.getCurrentHandleTag() def selectionEvent(self, source, event): --- 85,90 ---- changed.""" # If the change is user initiated, it has to be near the ! # cursor... I hope. ! self.getCurrentHandleTag().updateNodeFromWidget() def selectionEvent(self, source, event): *************** *** 149,154 **** except StopIteration: pass # use initial newPosIter ! lineNum = newPosIter.get_line() ! HandleTag(self, handle, newPosIter, lineNum) print "Unhandled event", name, ":", event.__dict__ --- 171,175 ---- except StopIteration: pass # use initial newPosIter ! HandleTag(self, handle, newPosIter) print "Unhandled event", name, ":", event.__dict__ *************** *** 226,230 **** i = 0 for handle, _ in self.handleWalkerForward(self.rootHandle[0]): ! HandleTag(self, handle, buffer.get_end_iter(), i) i += 1 --- 247,251 ---- i = 0 for handle, _ in self.handleWalkerForward(self.rootHandle[0]): ! HandleTag(self, handle, buffer.get_end_iter()) i += 1 *************** *** 260,263 **** --- 281,299 ---- "no children.") + # Get the node we're inserting everything in front of, + # or None if it's at the end + print "Source:", handleToChange.node.getData() + it = self.handleWalkerForward(handleToChange) + it.next() + try: + insertTagHandle, _ = it.next() + print "Inserting before:", insertTagHandle.node.getData() + insertTag = self.handleToTag[insertTagHandle] + print insertTag.text + insertLine = insertTag.widgetBegin.get_line() + print "Inserting at line", insertLine + except IndexError: + insertLine = None + self.handleStates[handleToChange] = constants.OPEN *************** *** 268,285 **** return - lineNum = handleTag.getLineNumber() - it = self.handleWalkerForward(handleToChange, True) # skip the first one, as it is handleToChange it.next() - thisLine = lineNum + 1 for handle, depth in it: if handle in self.handleToTag: # Remove the old tag if it exists, paranoia self.handleToTag[handle].destroy() ! HandleTag(self, handle, ! self.buffer.get_iter_at_line(thisLine), ! thisLine) ! thisLine += 1 if state == constants.CLOSED: --- 304,320 ---- return it = self.handleWalkerForward(handleToChange, True) # skip the first one, as it is handleToChange it.next() for handle, depth in it: if handle in self.handleToTag: # Remove the old tag if it exists, paranoia self.handleToTag[handle].destroy() ! if insertLine is None: ! startIter = self.buffer.get_end_iter() ! else: ! startIter = self.buffer.get_iter_at_line(insertLine) ! insertLine += 1 ! HandleTag(self, handle, startIter) if state == constants.CLOSED: *************** *** 292,297 **** if wasVisible: - import pdb - #pdb.set_trace() it = self.handleWalkerForward(handleToChange, True) it.next() --- 327,330 ---- *************** *** 373,374 **** --- 406,454 ---- # is high, but if nobody says they want Tk, this will go return + + def handleChildAdded(self, sourceHandle, link): + """Recieves a childAdded event from a HandleTag and handle it. + + @param sourceHandle: The handle the event was emitted + from. The new node is a child of that handle. + @param link: The new link that was added for the new node; the + new node is link.dest.""" + + # There are three possibilities, one for each possible + # node state. + # We already know the source handle is *visible*, or we wouldn't + # have a HandleTag watching a LinkHandle to recieve + # this event. + + state = self.handleStates[sourceHandle] + + if state == constants.NOCHILDREN: + # We're not going to display this new node, but we will + # update the indicator. + self.handleStates[sourceHandle] = constants.CLOSED + indicator = self.handleToTag[sourceHandle].indicator + indicator.setState(constants.CLOSED) + return + + if state == constants.CLOSED: + # We're not displaying anything, so ignore it + return + + if state == constants.OPEN: + # We have to add the new handle in. + newChildHandle = sourceHandle.getHandleForLink(link) + # Now, we have to figure out the new position, which is + # the current position of the next line, or the end of the + # buffer + walker = self.handleWalkerForward(newChildHandle) + walker.next() + try: + nextHandle, _ = walker.next() + newPosIter = self.handleToTag[nextHandle].getWidgetBeginIter() + except StopIteration: + newPosIter = self.buffer.get_end_iter() + HandleTag(self, newChildHandle, newPosIter) + return + + raise ValueError("Can't add new child because source handle " + "has unknown state: %s" % handleState) Index: handletag.py =================================================================== RCS file: /cvsroot/ironlute/ironlute/gtk/handletag.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** handletag.py 7 May 2005 20:11:52 -0000 1.3 --- handletag.py 8 May 2005 20:57:14 -0000 1.4 *************** *** 25,33 **** class HandleTag(object): ! def __init__(self, outlineWidget, handle, myIter, lineNum): self.tagNumber = tagNumbers() self.handle = handle self.buffer = outlineWidget.buffer self.outlineWidget = outlineWidget --- 25,46 ---- class HandleTag(object): ! def __init__(self, outlineWidget, handle, myIter): self.tagNumber = tagNumbers() self.handle = handle + lineNum = myIter.get_line() + self.buffer = outlineWidget.buffer + # Make us a new line + newlineIter = self.buffer.get_iter_at_line(lineNum) + newlineIter.backward_char() + self.buffer.insert(newlineIter, "\n") + myIter = self.buffer.get_iter_at_line(lineNum) + + # Mark the iter position, since we'll want to use + # it a lot + self.mark = self.buffer.create_mark(str(self) + "_mark", + myIter, True) + self.mark.set_visible(True) self.outlineWidget = outlineWidget *************** *** 41,45 **** textToInsert = handle.getNode().getData() ! self.buffer.insert(myIter, textToInsert + "\n") self.tag.set_property("size-points", 15) --- 54,62 ---- textToInsert = handle.getNode().getData() ! self.buffer.insert(self.widgetBegin, textToInsert) ! widgetEnd = self.widgetBegin ! widgetEnd.forward_to_line_end() ! widgetEnd.forward_char() ! #self.buffer.remove_all_tags(self.widgetBegin, widgetEnd) self.tag.set_property("size-points", 15) *************** *** 52,56 **** # Set up the indicator ! anchorIter = self.buffer.get_iter_at_line(lineNum) self.anchor = self.buffer.create_child_anchor(anchorIter) self.indicator = Indicator(self, handle, pixels) --- 69,73 ---- # Set up the indicator ! anchorIter = self.widgetBegin self.anchor = self.buffer.create_child_anchor(anchorIter) self.indicator = Indicator(self, handle, pixels) *************** *** 74,87 **** self.indicator.setState(self.outlineWidget.handleStates[self.handle]) ! self.buffer.apply_tag(self.tag, ! self.buffer.get_iter_at_line(lineNum), ! self.buffer.get_iter_at_line(lineNum + ! 1)) ! ! # Set a mark, which we use to retrieve line numbers and such ! lineIter = self.buffer.get_iter_at_line(lineNum) ! self.mark = self.buffer.create_mark(str(self) + "_mark", ! lineIter, True) ! self.handle.subscribe(self) --- 91,98 ---- self.indicator.setState(self.outlineWidget.handleStates[self.handle]) ! tagEnd = self.widgetBegin ! tagEnd.forward_to_line_end() ! tagEnd.forward_char() ! self.buffer.apply_tag(self.tag, self.widgetBegin, tagEnd) self.handle.subscribe(self) *************** *** 96,100 **** To activate magic, uncomment the 'magic' part of the keypress handler in outlinewidget.""" ! self.setText("Sophie is a good dog.") def getState(self): --- 107,118 ---- To activate magic, uncomment the 'magic' part of the keypress handler in outlinewidget.""" ! self.mark.set_visible(False) ! print self.outlineWidget.insert.get_line() ! print self.text ! print id(self) ! print str(self) ! #print self.outlineWidget.insert.get_tags() ! #self.outlineWidget.magic = True ! #self.handle.node.addNewChild() def getState(self): *************** *** 117,122 **** data_change. This directly handles the last, and indirectly the first two.""" print event ! print self.getText() def unselect(self): --- 135,152 ---- data_change. This directly handles the last, and indirectly the first two.""" + try: + if event.source is self: + return + except AttributeError: pass + print event ! ! if event.eventName == "data_change" and not hasattr(event, "key"): ! self.updateWidgetFromNode() ! ! # Things we have to pass up to the outline widget ! if event.eventName == "child_added": ! self.outlineWidget.handleChildAdded(event.sourceHandle, ! event.link) def unselect(self): *************** *** 135,139 **** """Sets the position of the cursor within this tag, as a function of characters after the node indicator.""" ! it = self.getWidgetBeginIter() it.forward_chars(pos + 1) self.outlineWidget.insert = it --- 165,169 ---- """Sets the position of the cursor within this tag, as a function of characters after the node indicator.""" ! it = self.widgetBegin it.forward_chars(pos + 1) self.outlineWidget.insert = it *************** *** 142,150 **** def updateNodeFromWidget(self): """Copy the text from this widget into the node.""" ! self.handle.node.setData(self.getText()) def updateWidgetFromNode(self): """Copy the text in the node out to the widget.""" ! self.setText(self.handle.node.getData()) def toggle(self): --- 172,182 ---- def updateNodeFromWidget(self): """Copy the text from this widget into the node.""" ! self.handle.node.setData(self.text, source = self) def updateWidgetFromNode(self): """Copy the text in the node out to the widget.""" ! print "updated from node" ! self.text = self.handle.node.getData() ! print self.handle.node.getData() def toggle(self): *************** *** 163,169 **** Note using this invalidates GtkTextIters.""" del self.outlineWidget.gtkTagToHandleTag[self.tag] ! begin = self.getWidgetBeginIter() # just after the indicator #begin.backward_char() # back up to get the indicator ! end = self.getWidgetBeginIter() end.forward_to_line_end() # end of line end.forward_char() # get the CRLF too --- 195,201 ---- Note using this invalidates GtkTextIters.""" del self.outlineWidget.gtkTagToHandleTag[self.tag] ! begin = self.widgetBegin # just after the indicator #begin.backward_char() # back up to get the indicator ! end = self.widgetBegin end.forward_to_line_end() # end of line end.forward_char() # get the CRLF too *************** *** 177,180 **** --- 209,214 ---- return self.buffer.get_iter_at_mark(self.mark) + widgetBegin = property(getWidgetBeginIter) + def getTextStartIter(self): """Gets an iterator set at the start of the text. *************** *** 183,193 **** start of the node; I want to make it possible to have multiple little widgets there if necessary.""" ! it = self.getWidgetBeginIter() it.forward_char() return it ! def getLineNumber(self): ! """Returns the current line number of the handle.""" ! return self.getWidgetBeginIter().get_line() def bounds(self): --- 217,225 ---- start of the node; I want to make it possible to have multiple little widgets there if necessary.""" ! it = self.widgetBegin it.forward_char() return it ! textBegin = property(getTextStartIter) def bounds(self): *************** *** 197,201 **** @returns TextIter, TextIter (tuple)""" ! bounds = self.getWidgetBeginIter(), self.getWidgetBeginIter() # FIXME: I end up doing this a lot, either factor or isolate bounds[1].forward_to_line_end() --- 229,233 ---- @returns TextIter, TextIter (tuple)""" ! bounds = self.widgetBegin, self.widgetBegin # FIXME: I end up doing this a lot, either factor or isolate bounds[1].forward_to_line_end() *************** *** 210,214 **** @returns GtkTextIter, GtkTextIter (tuple)""" ! bounds = self.getTextStartIter(), self.getWidgetBeginIter() bounds[1].forward_to_line_end() return bounds --- 242,246 ---- @returns GtkTextIter, GtkTextIter (tuple)""" ! bounds = self.textBegin, self.widgetBegin bounds[1].forward_to_line_end() return bounds *************** *** 226,230 **** """Sets this node as pure text.""" self.clear() ! self.buffer.insert(self.getTextStartIter(), text) def setFocus(self): --- 258,264 ---- """Sets this node as pure text.""" self.clear() ! self.buffer.insert(self.textBegin, text) ! ! text = property(getText, setText, clear) def setFocus(self): *************** *** 237,244 **** def selectAll(self): ! itBegin = self.getWidgetBeginIter() ! itBegin.forward_char() self.outlineWidget.selection_bound = itBegin ! itEnd = self.getWidgetBeginIter() itEnd.forward_to_line_end() self.outlineWidget.insert = itEnd --- 271,277 ---- def selectAll(self): ! itBegin = self.textBegin self.outlineWidget.selection_bound = itBegin ! itEnd = self.widgetBegin itEnd.forward_to_line_end() self.outlineWidget.insert = itEnd |