00001 from view import View
00002 from view import BlockItemAttributes
00003 from view import BandItemAttributes
00004 from view import SnapItemAttributes
00005 from adapter import Adapter
00006 from topology import *
00007 import sys
00008 import logging
00009
00010 log = logging.getLogger('diarc.base_adapter')
00011
00012 class BaseAdapter(Adapter):
00013 """ Basic implementation of the adapter interface.
00014 This should not have any QT or non-standard topology specific code. """
00015 def __init__(self, model, view):
00016 super(BaseAdapter, self).__init__(model, view)
00017
00018
00019
00020
00021 self._cached_block_item_indexes = list()
00022 self._cached_band_item_altitudes = list()
00023 self._cached_snap_item_snapkeys = list()
00024
00025 def get_block_item_attributes(self, block_index):
00026 """ Default method for providing some stock settings for blocks """
00027 attrs = BlockItemAttributes()
00028 attrs.bgcolor = "white"
00029 attrs.border_color = "red"
00030 attrs.border_width = 0
00031 attrs.label = str(block_index)
00032
00033 attrs.label_color = "red"
00034 attrs.spacerwidth = 20
00035 return attrs
00036
00037 def get_band_item_attributes(self, band_altitude):
00038 """ Default method for providing some stock settings for bands """
00039 attrs = BandItemAttributes()
00040 attrs.bgcolor = "white"
00041 attrs.border_color = "red"
00042 attrs.label = str(band_altitude)
00043 attrs.label_color = "red"
00044 attrs.width = 15
00045 return attrs
00046
00047 def get_snap_item_attributes(self, snapkey):
00048 """ Default method for providing some stock settings for snaps """
00049 attrs = SnapItemAttributes()
00050 attrs.bgcolor = "white"
00051 attrs.border_color = "blue" if "e" in snapkey else "green"
00052 attrs.border_width = 0
00053 attrs.label = snapkey
00054 attrs.label_color = "red"
00055 attrs.width = 20
00056 return attrs
00057
00058
00059 def reorder_blocks(self,srcIdx,lowerIdx,upperIdx):
00060 """ reorders the index values of blocks and triggers the view to redraw.
00061 This also requires updating the corresponding block_items.
00062 """
00063 blocks = self._topology.blocks
00064
00065 lastIdx = None
00066 currIdx = srcIdx
00067
00068
00069
00070
00071 if lowerIdx is not None and lowerIdx > srcIdx:
00072 while isinstance(currIdx,int) and currIdx < (upperIdx or lowerIdx+1):
00073 nextIdx = blocks[currIdx].rightBlock.index if blocks[currIdx].rightBlock else None
00074 blocks[currIdx].index = lastIdx
00075 log.debug("%s -> %s"%(str(currIdx),str(lastIdx)))
00076 lastIdx = currIdx
00077 currIdx = nextIdx
00078 assert lastIdx == lowerIdx, "%r %r"%(lastIdx,upperIdx)
00079
00080
00081
00082 elif upperIdx is not None and upperIdx < srcIdx:
00083 while isinstance(currIdx,int) and currIdx > lowerIdx:
00084 nextIdx = blocks[currIdx].leftBlock.index if blocks[currIdx].leftBlock else None
00085 blocks[currIdx].index = lastIdx
00086 log.debug("%s -> %s"%(str(currIdx),str(lastIdx)))
00087 lastIdx = currIdx
00088 currIdx = nextIdx
00089 assert lastIdx == upperIdx, "%r %r"%(lastIdx,upperIdx)
00090
00091
00092
00093
00094 else:
00095 return False
00096
00097
00098 blocks[srcIdx].index = lastIdx
00099 self._update_view()
00100 return True
00101
00102
00103 def reorder_bands(self, srcAlt, lowerAlt, upperAlt):
00104 """ Reorders the altitude values of bands """
00105 bands = self._topology.bands
00106
00107 lastAlt = None
00108 currAlt = srcAlt
00109
00110
00111
00112
00113 if isinstance(lowerAlt,int) and lowerAlt > srcAlt:
00114 while isinstance(currAlt,int) and currAlt < (upperAlt or lowerAlt+1):
00115 tband = bands[currAlt].topBand
00116 nextAlt = tband.altitude if isinstance(tband,Band) else None
00117 bands[currAlt].altitude = lastAlt
00118 lastAlt = currAlt
00119 currAlt = nextAlt
00120
00121 assert lastAlt == lowerAlt, "%r %r"%(lastAlt,lowerAlt)
00122
00123
00124
00125 elif isinstance(upperAlt,int) and upperAlt <= srcAlt:
00126 while isinstance(currAlt,int) and currAlt > (lowerAlt or upperAlt-1):
00127 lband = bands[currAlt].bottomBand
00128 nextAlt = lband.altitude if isinstance(lband,Band) else None
00129 bands[currAlt].altitude = lastAlt
00130 lastAlt = currAlt
00131 currAlt = nextAlt
00132
00133 assert lastAlt == upperAlt, "%r %r"%(lastAlt,upperAlt)
00134
00135 else:
00136 return False
00137
00138
00139
00140 bands[srcAlt].altitude = lastAlt
00141 self._update_view()
00142 return True
00143
00144 def reorder_snaps(self, blockIdx, container, srcIdx, lowerIdx, upperIdx):
00145 assert(container in ["emitter","collector"])
00146 block = self._topology.blocks[blockIdx]
00147 snaps = block.emitter if container == "emitter" else block.collector
00148 log.debug("%s"%snaps.keys())
00149 log.debug("move snap %s between %s and %s"%(srcIdx,lowerIdx,upperIdx))
00150
00151 lastIdx = None
00152 currIdx = srcIdx
00153
00154
00155
00156
00157 if lowerIdx is not None and lowerIdx > srcIdx:
00158 while isinstance(currIdx,int) and currIdx < (upperIdx or lowerIdx+1):
00159 nextIdx = snaps[currIdx].rightSnap.order if snaps[currIdx].rightSnap else None
00160 snaps[currIdx].order = lastIdx
00161 log.debug("%s -> %s"%(str(currIdx),str(lastIdx)))
00162 lastIdx = currIdx
00163 currIdx = nextIdx
00164
00165 assert lastIdx == lowerIdx, "%r %r"%(lastIdx,lowerIdx)
00166
00167
00168
00169
00170 elif upperIdx is not None and upperIdx < srcIdx:
00171 while isinstance(currIdx,int) and currIdx > lowerIdx:
00172 nextIdx = snaps[currIdx].leftSnap.order if snaps[currIdx].leftSnap else None
00173 snaps[currIdx].order = lastIdx
00174 log.debug("%s -> %s"%(str(currIdx),str(lastIdx)))
00175 lastIdx = currIdx
00176 currIdx = nextIdx
00177
00178 assert lastIdx == upperIdx, "%r %r"%(lastIdx,upperIdx)
00179
00180
00181
00182
00183 else:
00184 return False
00185
00186
00187
00188 snaps[srcIdx].order = lastIdx
00189 self._update_view()
00190 return True
00191
00192 def bring_band_to_front(self, altitude):
00193 bands = self._topology.bands
00194
00195 src_band = bands[altitude]
00196 sibling_alts = [(alt, band.rank) for alt, band in bands.items()
00197 if (src_band.isPositive and band.altitude > 0 and band.rank >= src_band.rank) or
00198 (not src_band.isPositive and band.altitude < 0 and band.rank >= src_band.rank)]
00199 if len(sibling_alts) <= 1:
00200
00201 return
00202
00203 sibling_alts.sort(lambda x,y: x[1] - y[1])
00204
00205
00206 target_rank = max([x[1] for x in sibling_alts])
00207
00208
00209 sibling_alts = [x[0] for x in sibling_alts]
00210 last_rank = src_band.rank
00211 src_band.rank = None
00212 for idx in range(1,len(sibling_alts)):
00213 band = bands[sibling_alts[idx]]
00214 next_rank = band.rank
00215 band.rank = last_rank
00216 last_rank = next_rank
00217 src_band.rank = target_rank
00218
00219 self._update_view()
00220
00221 def _update_view(self):
00222 """ updates the view - compute each items neigbors and then calls linking. """
00223
00224
00225 blocks = self._topology.blocks
00226 bands = self._topology.bands
00227 snaps = self._topology.snaps
00228
00229
00230 old_block_item_indexes = list(set(self._cached_block_item_indexes) - set(blocks.keys()))
00231 for index in old_block_item_indexes:
00232 self._view.remove_block_item(index)
00233 self._cached_block_item_indexes.remove(index)
00234
00235
00236 for index in blocks:
00237 if not self._view.has_block_item(index):
00238 self._view.add_block_item(index)
00239 self._cached_block_item_indexes.append(index)
00240
00241
00242
00243
00244
00245
00246
00247 old_band_item_altitudes = list(set(self._cached_band_item_altitudes) - set(bands.keys()))
00248 for altitude in old_band_item_altitudes:
00249 self._view.remove_band_item(altitude)
00250 self._cached_band_item_altitudes.remove(altitude)
00251
00252
00253
00254 for altitude in bands:
00255 band = bands[altitude]
00256 isUsed = band.isUsed()
00257 if isUsed and not self._view.has_band_item(altitude):
00258 self._view.add_band_item(altitude,band.rank)
00259 self._cached_band_item_altitudes.append(altitude)
00260 elif not isUsed and self._view.has_band_item(altitude):
00261 self._view.remove_band_item(altitude)
00262 self._cached_band_item_altitudes.remove(altitude)
00263
00264
00265
00266
00267
00268 old_snap_item_snapkeys = list(set(self._cached_snap_item_snapkeys) - set(snaps.keys()))
00269 for snapkey in old_snap_item_snapkeys:
00270 self._view.remove_snap_item(snapkey)
00271 self._cached_snap_item_snapkeys.remove(snapkey)
00272
00273
00274
00275 for snapkey in snaps:
00276 snap = snaps[snapkey]
00277 isUsed = snap.isUsed()
00278 if isUsed and not self._view.has_snap_item(snapkey):
00279 self._view.add_snap_item(snapkey)
00280 self._cached_snap_item_snapkeys.append(snapkey)
00281 elif not isUsed and self._view.has_snap_item(snapkey):
00282 self._view.remove_snap_item(snapkey)
00283 self._cached_snap_item_snapkeys.remove(snapkey)
00284
00285
00286
00287
00288 log.debug("*** Computing neighbors ***")
00289 sys.stdout.flush()
00290 log.debug("Blocks and snaps")
00291 sys.stdout.flush()
00292
00293 for index in blocks:
00294 block = blocks[index]
00295 left_index = block.leftBlock.index if block.leftBlock is not None else None
00296 right_index = block.rightBlock.index if block.rightBlock is not None else None
00297 self._view.set_block_item_settings(index, left_index, right_index)
00298
00299 emitter = blocks[index].emitter
00300 collector = blocks[index].collector
00301 for snap in emitter.values() + collector.values():
00302 order = snap.order
00303 containername = "emitter" if snap.isSource() else "collector"
00304
00305 if not snap.isUsed():
00306 items = [item for item in self._view.layout_manager._snap_items if item.snap_order == order]
00307 items = [item for item in items if item.container.strType() == containername]
00308 items_orders = [item.snap_order for item in items if item.block_index == snap.block.index]
00309 assert(order not in items_orders)
00310 continue
00311 left_order = snap.leftSnap.order if snap.leftSnap is not None else None
00312 right_order = snap.rightSnap.order if snap.rightSnap is not None else None
00313 pos_alt = snap.posBandLink.altitude if snap.posBandLink else None
00314 neg_alt = snap.negBandLink.altitude if snap.negBandLink else None
00315 self._view.set_snap_item_settings(snap.snapkey(), left_order, right_order, pos_alt, neg_alt)
00316 log.debug("bands")
00317 sys.stdout.flush()
00318
00319 for altitude in bands:
00320
00321 if not bands[altitude].isUsed():
00322
00323
00324
00325
00326
00327 continue
00328 band = bands[altitude]
00329 top_alt = band.topBand.altitude if band.topBand else None
00330 bot_alt = band.bottomBand.altitude if band.bottomBand else None
00331 emitters = band.emitters
00332 collectors = band.collectors
00333 emitters.sort(lambda x,y: x.block.index - y.block.index)
00334 collectors.sort(lambda x,y: x.block.index - y.block.index)
00335 left_snap = None
00336 right_snap = None
00337 if band.isPositive:
00338 left_snap = emitters[0]
00339 right_snap = collectors[-1]
00340 else:
00341 left_snap = collectors[0]
00342 right_snap = emitters[-1]
00343 left_snapkey = left_snap.snapkey() if left_snap is not None else None
00344 right_snapkey = right_snap.snapkey() if right_snap is not None else None
00345 self._view.set_band_item_settings(altitude, band.rank, top_alt, bot_alt, left_snapkey, right_snapkey )
00346
00347 log.debug("*** Finished Computing neighbors ***")
00348 log.debug("*** Assigning Attributes ***")
00349
00350
00351 for index in self._cached_block_item_indexes:
00352 attributes = self.get_block_item_attributes(index)
00353 self._view.set_block_item_attributes(index,attributes)
00354
00355
00356 for altitude in self._cached_band_item_altitudes:
00357 attributes = self.get_band_item_attributes(altitude)
00358 self._view.set_band_item_attributes(altitude, attributes)
00359
00360
00361 for snapkey in self._cached_snap_item_snapkeys:
00362 attributes = self.get_snap_item_attributes(snapkey)
00363 self._view.set_snap_item_attributes(snapkey, attributes)
00364 log.debug("*** Finished Assigning Attributes ***")
00365
00366 self._view.update_view()
00367
00368