base_adapter.py
Go to the documentation of this file.
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         # These are caching lists so I can remember what I had last time I drew.
00019         # That way, if something becomes outdated, I have a thing to compare against.
00020         # These lists are updated at the end of _update_view()
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 #         attrs.label_rotation = -90
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         # If we are moving to the right, lowerIdx is the target index.
00068         # Clear the dragged block's index, then shift all effected block
00069         # indices left.
00070         # NOTE: See issue #12
00071         if lowerIdx is not None and lowerIdx > srcIdx:
00072             while isinstance(currIdx,int) and currIdx < (upperIdx or lowerIdx+1): # In case upperIdx is None, use lower+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         # If we are moving to the left, upperIdx is the target index.
00081         # Clear the dragged blocks index, then shift all effected blocks right
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         # Otherwise we are just dragging to the side a bit and nothing is 
00092         # really moving anywhere. Return immediately to avoid trying to give
00093         # the block a new index and unnecessary extra linking actions.
00094         else:
00095             return False
00096         # Finally give the moved object its desired destination. Then make 
00097         # the TopologyWidget relink all the objects again.
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         # If we are moving up, lowerAlt is the target altitude. 
00111         # Clear the dragged bands's altitude, then shift all effected bands
00112         # down. See issue #12
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             # Assertion check
00121             assert lastAlt == lowerAlt, "%r %r"%(lastAlt,lowerAlt)
00122 
00123         # If we are moving down, upperAlt is the target altitude.
00124         # Clear the dragged bands altitude, then shift all effected bands up.
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             # Assertion check
00133             assert lastAlt == upperAlt, "%r %r"%(lastAlt,upperAlt)
00134 
00135         else:
00136             return False
00137 
00138         # Finally, give the moved object its desired destination. Then make
00139         # the TopologyWidget relink all the objects again
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         # If we are moving to the right, lowerIdx is the target index.
00154         # Clear the dragged snaps's order, then shift all effected snap
00155         # indices left.
00156         # NOTE: see #12
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             # Assertion check. TODO: Remove
00165             assert lastIdx == lowerIdx, "%r %r"%(lastIdx,lowerIdx)
00166 
00167         # If we are moving to the left, upperIdx is the target index.
00168         # Clear the dragged snaps order, then shift all effected snaps
00169         # indices right
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             # Assertion check. TODO remove
00178             assert lastIdx == upperIdx, "%r %r"%(lastIdx,upperIdx)
00179 
00180         # Otherwise we are just dragging to the side a bit and nothing is
00181         # really moving anywhere. Return immediately to avoid trying to
00182         # give the snap a new order and unnecessary extra linking actions.
00183         else:
00184             return False
00185 
00186         # Finally give the moved object its desired destination. Then
00187         # make the TopologyWidget relink all the objects again.
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 #             print "Band is already on top!"
00201             return
00202         # Order sibling altitudes by rank from lowest to highest
00203         sibling_alts.sort(lambda x,y: x[1] - y[1])
00204 #         print "Bringing band with altitude %d to front of %s" % (src_band.altitude, sibling_alts)
00205         # Get the highest rank value (what we want this band to have)
00206         target_rank = max([x[1] for x in sibling_alts])
00207 #         print "target rank value is %d" % target_rank
00208         # Strip rank information so we just have altitudes ordered by rank
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         # Determine what items are in the model
00225         blocks = self._topology.blocks
00226         bands = self._topology.bands
00227         snaps = self._topology.snaps
00228         
00229         # Delete outdated BlockItems still in the view but no longer in the topology
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         # Add new BlockItems for blocks in model that are not in view
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         # Update the BlockItem cache list
00242 #         self._cached_block_item_indexes = blocks.keys()
00243 
00244 
00245 
00246         # Delete outdated BandItems still in the view but not in the topology
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         # Delete BandItems that exist, but are not being used, and add BandItems
00253         # that are being used, but are not yet in the view
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         # Update the BandItem cache list
00265 #         self._cached_band_item_altitudes = bands.keys()
00266 
00267         # Delete outdated SnapItems still in the view but no longer in the topology
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         # Delete SnapItems that exist, but are not being used, and add SnapItems
00274         # that are being used, but are not yet in the view
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         # Update the SnapItem cache list
00286 #         self._cached_snap_item_snapkeys = snaps.keys()
00287 
00288         log.debug("*** Computing neighbors ***")
00289         sys.stdout.flush()
00290         log.debug("Blocks and snaps")
00291         sys.stdout.flush()
00292         # Compute left and right blocks
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             # Compute left and right snaps, and what bands are being touched
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                 # TODO: This assertion check should be commented out eventually
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         # Compute top and bottom bands, rank, leftmost, and rightmost snaps
00319         for altitude in bands:
00320             # Skip bands that don't have an item 
00321             if not bands[altitude].isUsed():
00322                 # The assertion below must be true for qt objects, however this 
00323                 # code should remain view implementation agnostic and the so
00324                 # the asserition is commented out.
00325 #                 item_alts = [a for a in self._view.layout_manager._band_items]
00326 #                 assert(altitude not in item_alts)
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         # Update block visual attribtutes
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         # Update band visual attributes
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         # Update snap visual attribtutes
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 


rqt_graphprofiler
Author(s): Dan Brooks
autogenerated on Thu Jun 6 2019 20:29:31