comparison browser_side/base_widget.py @ 225:9b93a21dc5e2

browser_side: display widget title in the debug info (LiberviaWidget method "getDebugName") - better PEP8 compliance
author souliane <souliane@mailoo.org>
date Thu, 26 Sep 2013 11:39:54 +0200
parents 3092f6b1710c
children 266e9678eec0
comparison
equal deleted inserted replaced
224:f3a5a094c8d6 225:9b93a21dc5e2
38 import dialog 38 import dialog
39 from tools import LiberviaDragWidget 39 from tools import LiberviaDragWidget
40 from pyjamas import Window 40 from pyjamas import Window
41 from __pyjamas__ import doc 41 from __pyjamas__ import doc
42 42
43
43 class DropCell(DropWidget): 44 class DropCell(DropWidget):
44 """Cell in the middle grid which replace itself with the dropped widget on DnD""" 45 """Cell in the middle grid which replace itself with the dropped widget on DnD"""
45 drop_keys = {} 46 drop_keys = {}
46 47
47 def __init__(self, host): 48 def __init__(self, host):
48 DropWidget.__init__(self) 49 DropWidget.__init__(self)
49 self.host = host 50 self.host = host
50 self.setStyleName('dropCell') 51 self.setStyleName('dropCell')
51 52
52 @classmethod 53 @classmethod
53 def addDropKey(cls, key, callback): 54 def addDropKey(cls, key, callback):
54 DropCell.drop_keys[key] = callback 55 DropCell.drop_keys[key] = callback
55 56
56 def onDragEnter(self, event): 57 def onDragEnter(self, event):
57 if self == LiberviaDragWidget.current: 58 if self == LiberviaDragWidget.current:
58 return 59 return
59 self.addStyleName('dragover') 60 self.addStyleName('dragover')
60 DOM.eventPreventDefault(event) 61 DOM.eventPreventDefault(event)
61 62
62 def onDragLeave(self, event): 63 def onDragLeave(self, event):
63 if event.clientX <= self.getAbsoluteLeft() or event.clientY <= self.getAbsoluteTop() or\ 64 if event.clientX <= self.getAbsoluteLeft() or event.clientY <= self.getAbsoluteTop() or\
64 event.clientX >= self.getAbsoluteLeft() + self.getOffsetWidth()-1 or event.clientY >= self.getAbsoluteTop() + self.getOffsetHeight()-1: 65 event.clientX >= self.getAbsoluteLeft() + self.getOffsetWidth() - 1 or event.clientY >= self.getAbsoluteTop() + self.getOffsetHeight() - 1:
65 #We check that we are inside widget's box, and we don't remove the style in this case because 66 # We check that we are inside widget's box, and we don't remove the style in this case because
66 #if the mouse is over a widget inside the DropWidget, if will leave the DropWidget, and we 67 # if the mouse is over a widget inside the DropWidget, if will leave the DropWidget, and we
67 #don't want that 68 # don't want that
68 self.removeStyleName('dragover') 69 self.removeStyleName('dragover')
69 70
70 def onDragOver(self, event): 71 def onDragOver(self, event):
71 DOM.eventPreventDefault(event) 72 DOM.eventPreventDefault(event)
72 73
78 79
79 80
80 def onDrop(self, event): 81 def onDrop(self, event):
81 DOM.eventPreventDefault(event) 82 DOM.eventPreventDefault(event)
82 dt = event.dataTransfer 83 dt = event.dataTransfer
83 #'text', 'text/plain', and 'Text' are equivalent. 84 # 'text', 'text/plain', and 'Text' are equivalent.
84 try: 85 try:
85 item, item_type = dt.getData("text/plain").split('\n') #Workaround for webkit, only text/plain seems to be managed 86 item, item_type = dt.getData("text/plain").split('\n') # Workaround for webkit, only text/plain seems to be managed
86 if item_type and item_type[-1] == '\0': #Workaround for what looks like a pyjamas bug: the \0 should not be there, and 87 if item_type and item_type[-1] == '\0': # Workaround for what looks like a pyjamas bug: the \0 should not be there, and
87 item_type = item_type[:-1] # .strip('\0') and .replace('\0','') don't work. TODO: check this and fill a bug report 88 item_type = item_type[:-1] # .strip('\0') and .replace('\0','') don't work. TODO: check this and fill a bug report
88 #item_type = dt.getData("type") 89 # item_type = dt.getData("type")
89 print "message: %s" % item 90 print "message: %s" % item
90 print "type: %s" % item_type 91 print "type: %s" % item_type
91 except: 92 except:
92 print "no message found" 93 print "no message found"
93 item='&nbsp;' 94 item = '&nbsp;'
94 item_type = None 95 item_type = None
95 if item_type == "WIDGET": 96 if item_type == "WIDGET":
96 if not LiberviaDragWidget.current: 97 if not LiberviaDragWidget.current:
97 print "ERROR: No widget registered in LiberviaDragWidget !" 98 print "ERROR: No widget registered in LiberviaDragWidget !"
98 return 99 return
99 _new_panel = LiberviaDragWidget.current 100 _new_panel = LiberviaDragWidget.current
100 if self == _new_panel: # We can't drop on ourself 101 if self == _new_panel: # We can't drop on ourself
101 return 102 return
102 # we need to remove the widget from the panel as it will be inserted elsewhere 103 # we need to remove the widget from the panel as it will be inserted elsewhere
103 widgets_panel = _new_panel.getWidgetsPanel() 104 widgets_panel = _new_panel.getWidgetsPanel()
104 wid_row = widgets_panel.getWidgetCoords(_new_panel)[0] 105 wid_row = widgets_panel.getWidgetCoords(_new_panel)[0]
105 row_wids = widgets_panel.getLiberviaRowWidgets(wid_row) 106 row_wids = widgets_panel.getLiberviaRowWidgets(wid_row)
108 # as the target widget (self), we don't do anything 109 # as the target widget (self), we don't do anything
109 self.removeStyleName('dragover') 110 self.removeStyleName('dragover')
110 return 111 return
111 widgets_panel.removeWidget(_new_panel) 112 widgets_panel.removeWidget(_new_panel)
112 elif item_type in self.drop_keys: 113 elif item_type in self.drop_keys:
113 _new_panel = self.drop_keys[item_type](self.host,item) 114 _new_panel = self.drop_keys[item_type](self.host, item)
114 else: 115 else:
115 print "WARNING: unmanaged item type" 116 print "WARNING: unmanaged item type"
116 return 117 return
117 if isinstance(self, LiberviaWidget): 118 if isinstance(self, LiberviaWidget):
118 self.host.unregisterWidget(self) 119 self.host.unregisterWidget(self)
179 self.addStyleName('widget') 180 self.addStyleName('widget')
180 if self.__selectable: 181 if self.__selectable:
181 self.addClickListener(self) 182 self.addClickListener(self)
182 self.host.registerWidget(self) 183 self.host.registerWidget(self)
183 184
184 def getWidgetsPanel(self): 185 def getDebugName(self):
185 current = self 186 return "%s (%s)" % (self, self.__title.getText())
186 while current is not None and current.__class__ != WidgetsPanel: 187
188 def getWidgetsPanel(self, verbose=True):
189 # current = self was not reassuring for the code analyzer
190 current = self.getParent()
191 while current is not None and not isinstance(current, WidgetsPanel):
187 current = current.getParent() 192 current = current.getParent()
188 if current is None: 193 if current is None and verbose:
189 print "Error: can't find WidgetsPanel" 194 print "Error: can't find WidgetsPanel"
190 return current 195 return current
191 196
192 def onClick(self, sender): 197 def onClick(self, sender):
193 self.host.setSelected(self) 198 self.host.setSelected(self)
194 199
195 def onClose(self, sender): 200 def onClose(self, sender):
196 """ Called when the close button is pushed """ 201 """ Called when the close button is pushed """
204 209
205 def onSetting(self, sender): 210 def onSetting(self, sender):
206 widpanel = self.getWidgetsPanel() 211 widpanel = self.getWidgetsPanel()
207 row, col = widpanel.getIndex(self) 212 row, col = widpanel.getIndex(self)
208 body = VerticalPanel() 213 body = VerticalPanel()
209 214
210 #colspan & rowspan 215 # colspan & rowspan
211 colspan = widpanel.getColSpan(row, col) 216 colspan = widpanel.getColSpan(row, col)
212 rowspan = widpanel.getRowSpan(row, col) 217 rowspan = widpanel.getRowSpan(row, col)
218
213 def onColSpanChange(value): 219 def onColSpanChange(value):
214 widpanel.setColSpan(row, col, value) 220 widpanel.setColSpan(row, col, value)
221
215 def onRowSpanChange(value): 222 def onRowSpanChange(value):
216 widpanel.setRowSpan(row, col, value) 223 widpanel.setRowSpan(row, col, value)
217 colspan_setter = dialog.IntSetter("Columns span", colspan) 224 colspan_setter = dialog.IntSetter("Columns span", colspan)
218 colspan_setter.addValueChangeListener(onColSpanChange) 225 colspan_setter.addValueChangeListener(onColSpanChange)
219 colspan_setter.setWidth('100%') 226 colspan_setter.setWidth('100%')
220 rowspan_setter = dialog.IntSetter("Rows span", rowspan) 227 rowspan_setter = dialog.IntSetter("Rows span", rowspan)
221 rowspan_setter.addValueChangeListener(onRowSpanChange) 228 rowspan_setter.addValueChangeListener(onRowSpanChange)
222 rowspan_setter.setWidth('100%') 229 rowspan_setter.setWidth('100%')
223 body.add(colspan_setter) 230 body.add(colspan_setter)
224 body.add(rowspan_setter) 231 body.add(rowspan_setter)
225 232
226 #size 233 # size
227 width_str = self.getWidth() 234 width_str = self.getWidth()
228 if width_str.endswith('px'): 235 if width_str.endswith('px'):
229 width=int(width_str[:-2]) 236 width = int(width_str[:-2])
230 else: 237 else:
231 width = 0 238 width = 0
232 height_str = self.getHeight() 239 height_str = self.getHeight()
233 if height_str.endswith('px'): 240 if height_str.endswith('px'):
234 height=int(height_str[:-2]) 241 height = int(height_str[:-2])
235 else: 242 else:
236 height = 0 243 height = 0
244
237 def onWidthChange(value): 245 def onWidthChange(value):
238 if not value: 246 if not value:
239 self.setWidth('100%') 247 self.setWidth('100%')
240 else: 248 else:
241 self.setWidth('%dpx' % value) 249 self.setWidth('%dpx' % value)
250
242 def onHeightChange(value): 251 def onHeightChange(value):
243 if not value: 252 if not value:
244 self.setHeight('100%') 253 self.setHeight('100%')
245 else: 254 else:
246 self.setHeight('%dpx' % value) 255 self.setHeight('%dpx' % value)
251 height_setter.addValueChangeListener(onHeightChange) 260 height_setter.addValueChangeListener(onHeightChange)
252 height_setter.setHeight('100%') 261 height_setter.setHeight('100%')
253 body.add(width_setter) 262 body.add(width_setter)
254 body.add(height_setter) 263 body.add(height_setter)
255 264
256 #reset 265 # reset
257 def onReset(sender): 266 def onReset(sender):
258 colspan_setter.setValue(1) 267 colspan_setter.setValue(1)
259 rowspan_setter.setValue(1) 268 rowspan_setter.setValue(1)
260 width_setter.setValue(0) 269 width_setter.setValue(0)
261 height_setter.setValue(0) 270 height_setter.setValue(0)
314 body_wid = widget 323 body_wid = widget
315 self.add(body_wid) 324 self.add(body_wid)
316 self.setCellHeight(body_wid, '100%') 325 self.setCellHeight(body_wid, '100%')
317 326
318 def doDetachChildren(self): 327 def doDetachChildren(self):
319 #We need to force the use of a panel subclass method here, 328 # We need to force the use of a panel subclass method here,
320 #for the same reason as doAttachChildren 329 # for the same reason as doAttachChildren
321 VerticalPanel.doDetachChildren(self) 330 VerticalPanel.doDetachChildren(self)
322 331
323 def doAttachChildren(self): 332 def doAttachChildren(self):
324 #We need to force the use of a panel subclass method here, else 333 # We need to force the use of a panel subclass method here, else
325 #the event will not propagate to children 334 # the event will not propagate to children
326 VerticalPanel.doAttachChildren(self) 335 VerticalPanel.doAttachChildren(self)
336
327 337
328 class ScrollPanelWrapper(SimplePanel): 338 class ScrollPanelWrapper(SimplePanel):
329 """Scroll Panel like component, wich use the full available space 339 """Scroll Panel like component, wich use the full available space
330 to work around percent size issue, it use some of the ideas found 340 to work around percent size issue, it use some of the ideas found
331 here: http://code.google.com/p/google-web-toolkit/issues/detail?id=316 341 here: http://code.google.com/p/google-web-toolkit/issues/detail?id=316
351 self.spanel.setScrollPosition(position) 361 self.spanel.setScrollPosition(position)
352 362
353 def scrollToBottom(self): 363 def scrollToBottom(self):
354 self.setScrollPosition(self.spanel.getElement().scrollHeight) 364 self.setScrollPosition(self.spanel.getElement().scrollHeight)
355 365
366
356 class EmptyWidget(DropCell, SimplePanel): 367 class EmptyWidget(DropCell, SimplePanel):
357 """Empty dropable panel""" 368 """Empty dropable panel"""
358 369
359 def __init__(self, host): 370 def __init__(self, host):
360 SimplePanel.__init__(self) 371 SimplePanel.__init__(self)
361 DropCell.__init__(self, host) 372 DropCell.__init__(self, host)
362 #self.setWidget(HTML('')) 373 #self.setWidget(HTML(''))
363 self.setSize('100%','100%') 374 self.setSize('100%', '100%')
375
364 376
365 class BorderWidget(EmptyWidget): 377 class BorderWidget(EmptyWidget):
366 def __init__(self, host): 378 def __init__(self, host):
367 EmptyWidget.__init__(self, host) 379 EmptyWidget.__init__(self, host)
368 self.addStyleName('borderPanel') 380 self.addStyleName('borderPanel')
369 381
382
370 class LeftBorderWidget(BorderWidget): 383 class LeftBorderWidget(BorderWidget):
371 def __init__(self, host): 384 def __init__(self, host):
372 BorderWidget.__init__(self, host) 385 BorderWidget.__init__(self, host)
373 self.addStyleName('leftBorderWidget') 386 self.addStyleName('leftBorderWidget')
374 387
388
375 class RightBorderWidget(BorderWidget): 389 class RightBorderWidget(BorderWidget):
376 def __init__(self, host): 390 def __init__(self, host):
377 BorderWidget.__init__(self, host) 391 BorderWidget.__init__(self, host)
378 self.addStyleName('rightBorderWidget') 392 self.addStyleName('rightBorderWidget')
379 393
394
380 class BottomBorderWidget(BorderWidget): 395 class BottomBorderWidget(BorderWidget):
381 def __init__(self, host): 396 def __init__(self, host):
382 BorderWidget.__init__(self, host) 397 BorderWidget.__init__(self, host)
383 self.addStyleName('bottomBorderWidget') 398 self.addStyleName('bottomBorderWidget')
384 399
400
385 class WidgetsPanel(ScrollPanelWrapper): 401 class WidgetsPanel(ScrollPanelWrapper):
386 402
387 def __init__(self, host, locked = False): 403 def __init__(self, host, locked=False):
388 ScrollPanelWrapper.__init__(self) 404 ScrollPanelWrapper.__init__(self)
389 self.setSize('100%', '100%') 405 self.setSize('100%', '100%')
390 self.host = host 406 self.host = host
391 self.locked = locked #if True: tab will not be removed when there are no more widgets inside 407 self.locked = locked # if True: tab will not be removed when there are no more widgets inside
392 self.selected = None 408 self.selected = None
393 self.flextable = FlexTable() 409 self.flextable = FlexTable()
394 self.flextable.setSize('100%','100%') 410 self.flextable.setSize('100%', '100%')
395 self.setWidget(self.flextable) 411 self.setWidget(self.flextable)
396 self.setStyleName('widgetsPanel') 412 self.setStyleName('widgetsPanel')
397 _bottom = BottomBorderWidget(self.host) 413 _bottom = BottomBorderWidget(self.host)
398 self.flextable.setWidget(0, 0, _bottom) #There will be always an Empty widget on the last row, 414 self.flextable.setWidget(0, 0, _bottom) # There will be always an Empty widget on the last row,
399 #dropping a widget there will add a new row 415 # dropping a widget there will add a new row
400 td_elt = _bottom.getElement().parentNode 416 td_elt = _bottom.getElement().parentNode
401 DOM.setStyleAttribute(td_elt, "height", "1px") #needed so the cell adapt to the size of the border (specially in webkit) 417 DOM.setStyleAttribute(td_elt, "height", "1px") # needed so the cell adapt to the size of the border (specially in webkit)
402 self._max_cols = 1 #give the maximum number of columns i a raw 418 self._max_cols = 1 # give the maximum number of columns i a raw
403 419
404 def isLocked(self): 420 def isLocked(self):
405 return self.locked 421 return self.locked
406 422
407 def changeWidget(self, row, col, wid): 423 def changeWidget(self, row, col, wid):
408 """Change the widget in the given location, add row or columns when necessary""" 424 """Change the widget in the given location, add row or columns when necessary"""
409 print "changing widget:", wid, row, col 425 print "changing widget:", wid.getDebugName(), row, col
410 last_row = max(0, self.flextable.getRowCount()-1) 426 last_row = max(0, self.flextable.getRowCount() - 1)
411 try: 427 try:
412 prev_wid = self.flextable.getWidget(row, col) 428 prev_wid = self.flextable.getWidget(row, col)
413 except: 429 except:
414 print "ERROR: Trying to change an unexisting widget !" 430 print "ERROR: Trying to change an unexisting widget !"
415 return 431 return
416
417 432
418 cellFormatter = self.flextable.getFlexCellFormatter() 433 cellFormatter = self.flextable.getFlexCellFormatter()
419 434
420 if isinstance(prev_wid, BorderWidget): 435 if isinstance(prev_wid, BorderWidget):
421 #We are on a border, we must create a row and/or columns 436 # We are on a border, we must create a row and/or columns
422 print "BORDER WIDGET" 437 print "BORDER WIDGET"
423 prev_wid.removeStyleName('dragover') 438 prev_wid.removeStyleName('dragover')
424 439
425 if isinstance(prev_wid, BottomBorderWidget): 440 if isinstance(prev_wid, BottomBorderWidget):
426 #We are on the bottom border, we create a new row 441 # We are on the bottom border, we create a new row
427 self.flextable.insertRow(last_row) 442 self.flextable.insertRow(last_row)
428 self.flextable.setWidget(last_row, 0, LeftBorderWidget(self.host)) 443 self.flextable.setWidget(last_row, 0, LeftBorderWidget(self.host))
429 self.flextable.setWidget(last_row, 1, wid) 444 self.flextable.setWidget(last_row, 1, wid)
430 self.flextable.setWidget(last_row, 2, RightBorderWidget(self.host)) 445 self.flextable.setWidget(last_row, 2, RightBorderWidget(self.host))
431 cellFormatter.setHorizontalAlignment(last_row, 2, HasAlignment.ALIGN_RIGHT) 446 cellFormatter.setHorizontalAlignment(last_row, 2, HasAlignment.ALIGN_RIGHT)
432 row = last_row 447 row = last_row
433 448
434 elif isinstance(prev_wid, LeftBorderWidget): 449 elif isinstance(prev_wid, LeftBorderWidget):
435 if col!=0: 450 if col != 0:
436 print "ERROR: LeftBorderWidget must be on the first column !" 451 print "ERROR: LeftBorderWidget must be on the first column !"
437 return 452 return
438 self.flextable.insertCell(row, col+1) 453 self.flextable.insertCell(row, col + 1)
439 self.flextable.setWidget(row, 1, wid) 454 self.flextable.setWidget(row, 1, wid)
440 455
441 elif isinstance(prev_wid, RightBorderWidget): 456 elif isinstance(prev_wid, RightBorderWidget):
442 if col!=self.flextable.getCellCount(row)-1: 457 if col != self.flextable.getCellCount(row) - 1:
443 print "ERROR: RightBorderWidget must be on the last column !" 458 print "ERROR: RightBorderWidget must be on the last column !"
444 return 459 return
445 self.flextable.insertCell(row, col) 460 self.flextable.insertCell(row, col)
446 self.flextable.setWidget(row, col, wid) 461 self.flextable.setWidget(row, col, wid)
447 462
448 else: 463 else:
449 prev_wid.removeFromParent() 464 prev_wid.removeFromParent()
450 self.flextable.setWidget(row, col, wid) 465 self.flextable.setWidget(row, col, wid)
451 466
452 _max_cols = max(self._max_cols, self.flextable.getCellCount(row)) 467 _max_cols = max(self._max_cols, self.flextable.getCellCount(row))
453 if _max_cols != self._max_cols: 468 if _max_cols != self._max_cols:
454 self._max_cols = _max_cols 469 self._max_cols = _max_cols
455 self._sizesAdjust() 470 self._sizesAdjust()
456 471
457 def _sizesAdjust(self): 472 def _sizesAdjust(self):
458 cellFormatter = self.flextable.getFlexCellFormatter() 473 cellFormatter = self.flextable.getFlexCellFormatter()
459 width = 100.0/max(1, self._max_cols-2) #we don't count the borders 474 width = 100.0 / max(1, self._max_cols - 2) # we don't count the borders
460 475
461 for row_idx in xrange(self.flextable.getRowCount()): 476 for row_idx in xrange(self.flextable.getRowCount()):
462 for col_idx in xrange(self.flextable.getCellCount(row_idx)): 477 for col_idx in xrange(self.flextable.getCellCount(row_idx)):
463 _widget = self.flextable.getWidget(row_idx, col_idx) 478 _widget = self.flextable.getWidget(row_idx, col_idx)
464 if not isinstance(_widget, BorderWidget): 479 if not isinstance(_widget, BorderWidget):
465 td_elt = _widget.getElement().parentNode 480 td_elt = _widget.getElement().parentNode
466 DOM.setStyleAttribute(td_elt, "width", "%.2f%%" % width) 481 DOM.setStyleAttribute(td_elt, "width", "%.2f%%" % width)
467 482
468 last_row = max(0, self.flextable.getRowCount()-1) 483 last_row = max(0, self.flextable.getRowCount() - 1)
469 cellFormatter.setColSpan(last_row, 0, self._max_cols) 484 cellFormatter.setColSpan(last_row, 0, self._max_cols)
470 485
471 def addWidget(self, wid): 486 def addWidget(self, wid):
472 """Add a widget to a new cell on the next to last row""" 487 """Add a widget to a new cell on the next to last row"""
473 last_row = max(0, self.flextable.getRowCount()-1) 488 last_row = max(0, self.flextable.getRowCount() - 1)
474 print "putting widget %s at %d, %d" % (wid, last_row, 0) 489 print "putting widget %s at %d, %d" % (wid.getDebugName(), last_row, 0)
475 self.changeWidget(last_row, 0, wid) 490 self.changeWidget(last_row, 0, wid)
476 491
477 def removeWidget(self, wid): 492 def removeWidget(self, wid):
478 """Remove a widget and the cell where it is""" 493 """Remove a widget and the cell where it is"""
479 _row, _col = self.flextable.getIndex(wid) 494 _row, _col = self.flextable.getIndex(wid)
480 self.flextable.remove(wid) 495 self.flextable.remove(wid)
481 self.flextable.removeCell(_row, _col) 496 self.flextable.removeCell(_row, _col)
482 if not self.getLiberviaRowWidgets(_row): #we have no more widgets, we remove the row 497 if not self.getLiberviaRowWidgets(_row): # we have no more widgets, we remove the row
483 self.flextable.removeRow(_row) 498 self.flextable.removeRow(_row)
484 _max_cols = 1 499 _max_cols = 1
485 for row_idx in xrange(self.flextable.getRowCount()): 500 for row_idx in xrange(self.flextable.getRowCount()):
486 _max_cols = max(_max_cols, self.flextable.getCellCount(row_idx)) 501 _max_cols = max(_max_cols, self.flextable.getCellCount(row_idx))
487 if _max_cols != self._max_cols: 502 if _max_cols != self._max_cols:
488 self._max_cols = _max_cols 503 self._max_cols = _max_cols
489 self._sizesAdjust() 504 self._sizesAdjust()
490 current = self 505 current = self
491 506
492 blank_page = self.getLiberviaWidgetsCount() == 0 # do we still have widgets on the page ? 507 blank_page = self.getLiberviaWidgetsCount() == 0 # do we still have widgets on the page ?
493 508
494 if blank_page and not self.isLocked(): 509 if blank_page and not self.isLocked():
495 #we now notice the MainTabPanel that the WidgetsPanel is empty and need to be removed 510 # we now notice the MainTabPanel that the WidgetsPanel is empty and need to be removed
496 while current is not None: 511 while current is not None:
497 if isinstance(current, MainTabPanel): 512 if isinstance(current, MainTabPanel):
498 current.onWidgetPanelRemove(self) 513 current.onWidgetPanelRemove(self)
499 return 514 return
500 current = current.getParent() 515 current = current.getParent()
523 return self.flextable.getIndex(wid) 538 return self.flextable.getIndex(wid)
524 539
525 def getColSpan(self, row, col): 540 def getColSpan(self, row, col):
526 cellFormatter = self.flextable.getFlexCellFormatter() 541 cellFormatter = self.flextable.getFlexCellFormatter()
527 return cellFormatter.getColSpan(row, col) 542 return cellFormatter.getColSpan(row, col)
528 543
529 def setColSpan(self, row, col, value): 544 def setColSpan(self, row, col, value):
530 cellFormatter = self.flextable.getFlexCellFormatter() 545 cellFormatter = self.flextable.getFlexCellFormatter()
531 return cellFormatter.setColSpan(row, col, value) 546 return cellFormatter.setColSpan(row, col, value)
532 547
533 def getRowSpan(self, row, col): 548 def getRowSpan(self, row, col):
534 cellFormatter = self.flextable.getFlexCellFormatter() 549 cellFormatter = self.flextable.getFlexCellFormatter()
535 return cellFormatter.getRowSpan(row, col) 550 return cellFormatter.getRowSpan(row, col)
536 551
537 def setRowSpan(self, row, col, value): 552 def setRowSpan(self, row, col, value):
538 cellFormatter = self.flextable.getFlexCellFormatter() 553 cellFormatter = self.flextable.getFlexCellFormatter()
539 return cellFormatter.setRowSpan(row, col, value) 554 return cellFormatter.setRowSpan(row, col, value)
540 555
541 class DropTab(Label, DropWidget): 556 class DropTab(Label, DropWidget):
548 self.setWordWrap(False) 563 self.setWordWrap(False)
549 DOM.setStyleAttribute(self.getElement(), "min-width", "30px") 564 DOM.setStyleAttribute(self.getElement(), "min-width", "30px")
550 565
551 def _getIndex(self): 566 def _getIndex(self):
552 """ get current index of the DropTab """ 567 """ get current index of the DropTab """
553 # XXX: awful hack, but seems the only way to get index 568 # XXX: awful hack, but seems the only way to get index
554 return self.tab_panel.tabBar.panel.getWidgetIndex(self.getParent().getParent()) - 1 569 return self.tab_panel.tabBar.panel.getWidgetIndex(self.getParent().getParent()) - 1
555 570
556 571
557 def onDragEnter(self, event): 572 def onDragEnter(self, event):
558 #if self == LiberviaDragWidget.current: 573 #if self == LiberviaDragWidget.current:
559 # return 574 # return
560 self.addStyleName('dragover') 575 self.addStyleName('dragover')
570 DOM.eventPreventDefault(event) 585 DOM.eventPreventDefault(event)
571 self.removeStyleName('dragover') 586 self.removeStyleName('dragover')
572 if self._getIndex() == self.tab_panel.tabBar.getSelectedTab(): 587 if self._getIndex() == self.tab_panel.tabBar.getSelectedTab():
573 # the widget come from the DragTab, so nothing to do, we let it there 588 # the widget come from the DragTab, so nothing to do, we let it there
574 return 589 return
575 590
576 # FIXME: quite the same stuff as in DropCell, need some factorisation 591 # FIXME: quite the same stuff as in DropCell, need some factorisation
577 dt = event.dataTransfer 592 dt = event.dataTransfer
578 #'text', 'text/plain', and 'Text' are equivalent. 593 # 'text', 'text/plain', and 'Text' are equivalent.
579 try: 594 try:
580 item, item_type = dt.getData("text/plain").split('\n') #Workaround for webkit, only text/plain seems to be managed 595 item, item_type = dt.getData("text/plain").split('\n') # Workaround for webkit, only text/plain seems to be managed
581 if item_type and item_type[-1] == '\0': #Workaround for what looks like a pyjamas bug: the \0 should not be there, and 596 if item_type and item_type[-1] == '\0': # Workaround for what looks like a pyjamas bug: the \0 should not be there, and
582 item_type = item_type[:-1] # .strip('\0') and .replace('\0','') don't work. TODO: check this and fill a bug report 597 item_type = item_type[:-1] # .strip('\0') and .replace('\0','') don't work. TODO: check this and fill a bug report
583 #item_type = dt.getData("type") 598 # item_type = dt.getData("type")
584 print "message: %s" % item 599 print "message: %s" % item
585 print "type: %s" % item_type 600 print "type: %s" % item_type
586 except: 601 except:
587 print "no message found" 602 print "no message found"
588 item='&nbsp;' 603 item = '&nbsp;'
589 item_type = None 604 item_type = None
590 if item_type == "WIDGET": 605 if item_type == "WIDGET":
591 if not LiberviaDragWidget.current: 606 if not LiberviaDragWidget.current:
592 print "ERROR: No widget registered in LiberviaDragWidget !" 607 print "ERROR: No widget registered in LiberviaDragWidget !"
593 return 608 return
594 _new_panel = LiberviaDragWidget.current 609 _new_panel = LiberviaDragWidget.current
595 _new_panel.getWidgetsPanel().removeWidget(_new_panel) 610 _new_panel.getWidgetsPanel().removeWidget(_new_panel)
596 elif item_type in DropCell.drop_keys: 611 elif item_type in DropCell.drop_keys:
597 _new_panel = DropCell.drop_keys[item_type](self.tab_panel.host,item) 612 _new_panel = DropCell.drop_keys[item_type](self.tab_panel.host, item)
598 else: 613 else:
599 print "WARNING: unmanaged item type" 614 print "WARNING: unmanaged item type"
600 return 615 return
601 616
602 widgets_panel = self.tab_panel.getWidget(self._getIndex()) 617 widgets_panel = self.tab_panel.getWidget(self._getIndex())
604 619
605 class MainTabPanel(TabPanel): 620 class MainTabPanel(TabPanel):
606 621
607 def __init__(self, host): 622 def __init__(self, host):
608 TabPanel.__init__(self) 623 TabPanel.__init__(self)
609 self.host=host 624 self.host = host
610 self.tabBar.setVisible(False) 625 self.tabBar.setVisible(False)
611 self.setStyleName('liberviaTabPanel') 626 self.setStyleName('liberviaTabPanel')
612 self.addStyleName('mainTabPanel') 627 self.addStyleName('mainTabPanel')
613 Window.addWindowResizeListener(self) 628 Window.addWindowResizeListener(self)
614 629
630 self.setHeight("%s%s" % (ideal_height, "px")); 645 self.setHeight("%s%s" % (ideal_height, "px"));
631 646
632 def add(self, widget, text=''): 647 def add(self, widget, text=''):
633 tab = DropTab(self, text) 648 tab = DropTab(self, text)
634 TabPanel.add(self, widget, tab, False) 649 TabPanel.add(self, widget, tab, False)
635 if self.getWidgetCount()>1: 650 if self.getWidgetCount() > 1:
636 self.tabBar.setVisible(True) 651 self.tabBar.setVisible(True)
637 self.host.resize() 652 self.host.resize()
638 653
639 def onWidgetPanelRemove(self, panel): 654 def onWidgetPanelRemove(self, panel):
640 """ Called when a child WidgetsPanel is empty and need to be removed """ 655 """ Called when a child WidgetsPanel is empty and need to be removed """
644 self.tabBar.setVisible(False) 659 self.tabBar.setVisible(False)
645 self.host.resize() 660 self.host.resize()
646 self.selectTab(0) 661 self.selectTab(0)
647 else: 662 else:
648 self.selectTab(widgets_count - 1) 663 self.selectTab(widgets_count - 1)
649 664