1// BEGIN LICENSE BLOCK 2// Version: CMPL 1.1 3// 4// The contents of this file are subject to the Cisco-style Mozilla Public 5// License Version 1.1 (the "License"); you may not use this file except 6// in compliance with the License. You may obtain a copy of the License 7// at www.eclipse-clp.org/license. 8// 9// Software distributed under the License is distributed on an "AS IS" 10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11// the License for the specific language governing rights and limitations 12// under the License. 13// 14// The Original Code is The ECLiPSe Constraint Logic Programming System. 15// The Initial Developer of the Original Code is Cisco Systems, Inc. 16// Portions created by the Initial Developer are 17// Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18// 19// Contributor(s): 20// 21// END LICENSE BLOCK 22 23package com.parctechnologies.eclipse.visualisation; 24 25import com.parctechnologies.eclipse.*; 26import java.util.*; 27import javax.swing.*; 28import java.awt.event.*; 29import java.awt.Component; 30 31/** 32 * A ContainerViewer is a Viewer which contains zero or more "Viewlets" per 33 * viewable element. A Viewlet is an object, representing the data stored in a ViewletStore, which contains information about the viewable element. The ContainerViewer class does not commit itself to how many 34 * viewlets per element there are, what kind they are or how to store/access the 35 * viewlets. These decisions are left to subclasses. <p> 36 * 37 * The way this is done is that the protected abstract methods 38 * getViewletsAtIndex(List index) and getAllViewlets() must be implemented by 39 * the subclass, and should return the relevant Collection of Viewlets.<p> 40 * 41 * However, ContainerViewer <em>is</em> responsible for mediating between 42 * the event ViewerManager and the viewlets it contains. These responsibilities 43 * are as follows:<p> 44 * <ul> 45 * <li>For CreateEvents and ExpandEvents, the subclass of ContainerViewer may 46 * have created new viewlets during the invocation of the prepareForEvent 47 * method. In the collectPreEventGoals method, it is the responsibility of 48 * ContainerViewer to marshall these new 49 * viewlets and collect from each a goal using its 50 * collectPreBuildGoal method. All such goals are collected together in a batch 51 * goal and returned. 52 * <li>Similarly, for UpdateEvents, during the collectPreEventGoals, 53 * ContainerViewer must marshall all the 54 * Viewlets whose viewable elements are updating and collect a goal from each 55 * using its collectPreUpdateGoal method. These goals are batched together in a 56 * BatchGoal which is then returned. 57 * <li>Following on from the above, during startEvent, the ContainerViewer is 58 * responsible for distributing the results of the collected goals to the 59 * viewlets who generated the goals, using their startBuild methods in the case 60 * of CreateEvents and ExpandEvents and their startUpdate methods in the case of 61 * UpdateEvents. 62 * <li>The ContainerViewlet's implementation of stopEvent should invoke 63 * the stopBuild methods of all newly created viewlets at the end of a 64 * CreateEvent or an ExpandEvent and it should invoke the stopUpdate methods at 65 * the end of an UpdateEvent. 66 * <li>Between the execution of startEvent and the execution of stopEvent, 67 * ContainerViewer is also responsible for providing protected access to 68 * Collections of the indices of created/expanded/updating viewable elements, 69 * and to Collections of created/expanded/updating viewlets. 70 * <li>Each ContainerViewer also has a subset of its viewlets which are 71 * currently "selected" in the sense that the next user action will apply to 72 * them. The ContainerViewer is responsible for managing this collection. At 73 * present this means having a protected selection member, initialising 74 * the selection and remembering the selection during periods when the viewer 75 * loses focus. However, I intend to move actions such as "select all" and 76 * "select updating" up into this class along with other selection-related 77 * functionality where possible. 78 * </ul> 79 * ContainerViewer is also responsible for keeping track of the Location names. 80 */ 81 82public abstract class ContainerViewer extends ViewerImpl 83{ 84 private ViewletRange createdElementIndices; 85 private ViewletRange updatingElementIndices; 86 private ViewletRange expandingElementIndices; 87 //private Collection createdViewlets; 88 //private Collection updatingViewlets; 89 //private Collection expandingViewlets; 90 private List size; 91 private boolean trackUpdates = false; 92 93 protected ViewletType viewletType; 94 95 protected ViewletDataStore viewletDataStore; 96 97 /** 98 * Action to select all updating viewlets 99 */ 100 private SelectUpdatingAction selectUpdatingAction; 101 102 /** 103 * The menu entry specifying whether to track updates or not 104 */ 105 protected JCheckBoxMenuItem trackUpdatesMenuItem; 106 107 private static final Atom vcSupportAtom = new Atom("vc_support"); 108 //protected Collection selectionCopy = new LinkedList(); 109 //protected ViewletRange selection = new ViewletRangeCollection(); 110 111 /** 112 * Array of Lists of Strings. Each element in the array relates to a 113 * dimension. Each List is a list of strings: location names for the 114 * corresponding dimension. <p> 115 * locationNames[0] is a List of location names for dimension 1 in the 116 * viewable, 117 * locationNames[1] is for dimension 2 etc. 118 */ 119 private List[] locationNames; 120 121 122 /** 123 * Returns the mnemonic to use for a given menuTitle 124 */ 125 protected int getMenuMnemonic(String menuTitle) { 126 if ("Select".equals(menuTitle)) return KeyEvent.VK_S; 127 if ("View".equals(menuTitle)) return KeyEvent.VK_V; 128 return super.getMenuMnemonic(menuTitle); 129 } 130 131 public ContainerViewer(VisClientStateModel stateModel, 132 Viewable viewable, 133 ViewletType viewletType) 134 { 135 super(stateModel, viewable); 136 this.viewletType = viewletType; 137 viewletType.setSymRef(new SymRef(viewletType, 138 this.getSymRef(), 139 viewletType.getClass().getName())); 140 trackUpdatesMenuItem = new JCheckBoxMenuItem("Track updates"); 141 trackUpdatesMenuItem. 142 setModel(new BooleanPropertyModel("trackUpdates", 143 this, getPropertyChangeSupport())); 144 addMenuItem("Options", trackUpdatesMenuItem); 145 146 addMenuAndPopupMenuItem("Select", new SelectAllAction()); 147 selectUpdatingAction = new SelectUpdatingAction(); 148 addMenuAndPopupMenuItem("Select", selectUpdatingAction); 149 addMenuAndPopupMenuItem("Select", new ClearSelectionAction()); 150 addMenuAndPopupMenuItem("View", getZoomInAction(this, 0.5f)); 151 addMenuAndPopupMenuItem("View", getZoomInAction(this, 2.0f)); 152 addMenuAndPopupMenuItem("View", null); 153 addMenuAndPopupMenuItem("View", getZoomAction(this, 4.0f)); 154 addMenuAndPopupMenuItem("View", getZoomAction(this, 2.0f)); 155 addMenuAndPopupMenuItem("View", getZoomAction(this, 1.5f)); 156 addMenuAndPopupMenuItem("View", getZoomNormalAction(this)); 157 addMenuAndPopupMenuItem("View", getZoomAction(this, 0.75f)); 158 addMenuAndPopupMenuItem("View", getZoomAction(this, 0.5f)); 159 addMenuAndPopupMenuItem("View", getZoomAction(this, 0.25f)); 160 addMenuAndPopupMenuItem("View", getZoomToFitWidthAction()); 161 addMenuAndPopupMenuItem("View", getZoomToFitHeightAction()); 162 } 163 164 public ViewletDataStore getViewletDataStore() { 165 return viewletDataStore; 166 } 167 168 protected abstract Action getZoomToFitWidthAction(); 169 170 protected abstract Action getZoomToFitHeightAction(); 171 172 protected List getSize() 173 { 174 return(size); 175 } 176 177 public boolean getTrackUpdates() 178 { 179 return(trackUpdates); 180 } 181 182 183 public void setTrackUpdates(boolean newValue) 184 { 185 (new ViewerSetBooleanPropertyCommand(this, "trackUpdates", newValue)).issue(); 186 } 187 188 public void setTrackUpdatesPrivate(boolean newValue) 189 { 190 boolean oldValue = trackUpdates; 191 trackUpdates = newValue; 192 this.getPropertyChangeSupport(). 193 firePropertyChange("trackUpdates", oldValue, newValue); 194 } 195 196 197 public BatchGoal collectPreEventGoals(VisEvent event) 198 { 199 BatchGoal result = new BatchGoal(); 200 201 if(event instanceof UpdateEvent) 202 { 203 result.add(super.collectPreEventGoals(event)); 204 setUpdatingElementIndices((UpdateEvent) event); 205 result.add(collectPreUpdateGoals(updatingElementIndices, 206 ((UpdateEvent) event))); 207 return(result); 208 } 209 210 if(event instanceof ExpandEvent) 211 { 212 result.add(super.collectPreEventGoals(event)); 213 ExpandEvent expandEvent = (ExpandEvent) event; 214 int expandingDimension = expandEvent.getExpandingDimension(); 215 Integer newLocation = 216 (Integer) expandEvent.getViewableSize().get(expandingDimension - 1); 217 // add a goal to get the name of the new location in the expanded dimension 218 result.add(getAddLocationNameGoal(expandingDimension, 219 newLocation.intValue())); 220 setExpandingElementIndices(expandEvent); 221 result.add(collectPreBuildGoals(expandingElementIndices)); 222 return(result); 223 } 224 225 if(event instanceof CreateEvent) 226 { 227 result.add(super.collectPreEventGoals(event)); 228 CreateEvent createEvent = (CreateEvent) event; 229 // add a location names goal for each dimension. 230 for(int i = 1 ; i <= createEvent.getViewableSize().size() ; i++) 231 { 232 result.add(getLocationNamesGoal(i)); 233 } 234 setCreatedElementIndices(createEvent); 235 DebuggingSupport.logMessage(this,"collectPreEventGoal fooee"); 236 result.add(collectPreBuildGoals(createdElementIndices)); 237 return(result); 238 } 239 return(super.collectPreEventGoals(event)); 240 } 241 242 public void clearSelection() 243 { 244 setSelection(new ViewletRangeCollection()); 245 } 246 247 public void setSelection(ViewletRange newSelection) 248 { 249 (new ViewerSetSelectionCommand(this, newSelection)).issue(); 250 } 251 252// public void addAllToSelection(Collection newViewlets) 253// { 254// // HashSet newSelection = new HashSet(selection); 255// // newSelection.addAll(newViewlets); 256// // setSelection(newViewlets); 257// } 258 259// public void removeAllFromSelection(Collection viewletsToRemove) 260// { 261// // HashSet newSelection = new HashSet(selection); 262// // newSelection.removeAll(viewletsToRemove); 263// // setSelection(newSelection); 264// } 265 266// // public void addToSelection(Viewlet viewlet) 267// // { 268// // // LinkedList single = new LinkedList(); 269// // // single.add(viewlet); 270// // // addAllToSelection(single); 271// // } 272 273// // public void removeFromSelection(Viewlet viewlet) 274// // { 275// // // LinkedList single = new LinkedList(); 276// // // single.add(viewlet); 277// // // removeAllFromSelection(single); 278// // } 279 280 protected void setSelectionPrivate(ViewletRange newSelection) { 281 // default to doing nothing 282 // must be overidden by subclasses 283 284 // Collection viewletsToAdd = new LinkedList(); 285 // Collection viewletsToRemove = new LinkedList(); 286 // Iterator i1 = selection.iterator(); 287 // Viewlet current; 288 // while(i1.hasNext()) 289 // { 290 // current = (Viewlet) i1.next(); 291 // if(!newSelection.contains(current)) 292 // { 293 // viewletsToRemove.add(current); 294 // } 295 // } 296 // Iterator i2 = newSelection.iterator(); 297 // while(i2.hasNext()) 298 // { 299 // current = (Viewlet) i2.next(); 300 // if(!selection.contains(current)) 301 // { 302 // viewletsToAdd.add(current); 303 // } 304 // } 305 // addAllToSelectionPrivate(viewletsToAdd); 306 // removeAllFromSelectionPrivate(viewletsToRemove); 307 } 308 309// private void addAllToSelectionPrivate(Collection all) 310// { 311// // Iterator i = all.iterator(); 312// // while(i.hasNext()) 313// // { 314// // addToSelectionPrivate((Viewlet) i.next()); 315// // } 316// } 317 318// private void removeAllFromSelectionPrivate(Collection all) 319// { 320// Iterator i = all.iterator(); 321// while(i.hasNext()) 322// { 323// removeFromSelectionPrivate((Viewlet) i.next()); 324// } 325// } 326 327// private void addToSelectionPrivate(Viewlet viewlet) 328// { 329// // selection.add(viewlet); 330// // viewlet.setSelected(true); 331// } 332 333// private void removeFromSelectionPrivate(Viewlet viewlet) 334// { 335// // selection.remove(viewlet); 336// // viewlet.setSelected(false); 337// } 338 339 public ViewletRange getSelection() 340 { 341 //return selection; 342 return null; 343 } 344 345 private Collection collectPreBuildGoals(ViewletRange indexList) 346 { 347 //List goals = new LinkedList(); 348 //goals.add(viewletType.collectPreBuildGoal(this,new ViewletRangeCollection(indexList))); 349 List goals = viewletType.collectPreBuildGoal(this, 350 viewletDataStore, 351 indexList); 352 DebuggingSupport.logMessage(this,"PreBuildGoals="+goals); 353 return goals; 354 } 355 356 357 private Collection collectPreUpdateGoals(ViewletRange indexList, UpdateEvent event) 358 { 359 //List goals = new LinkedList(); 360 //goals.add(viewletType.collectPreUpdateGoal(this,new ViewletRangeCollection(indexList), event)); 361 List goals = viewletType.collectPreUpdateGoal(this, 362 viewletDataStore, 363 indexList, 364 event); 365 DebuggingSupport.logMessage(this,"PreUpdateGoals="+goals); 366 return goals; 367// BatchGoal result = new BatchGoal(); 368// Iterator indexListIterator = indexList.iterator(); 369// List currentIndex; 370// Collection viewlets; 371 372// while(indexListIterator.hasNext()) 373// { 374// currentIndex = (List) indexListIterator.next(); 375// viewlets = getViewletDataAt(currentIndex); 376// result.add(composeElementUpdateGoal(viewlets, currentIndex, event)); 377// } 378// return(result); 379 } 380 381// private BatchGoal composeElementBuildGoal(Collection viewlets, List index) 382// { 383// BatchGoal result = new BatchGoal(); 384// Object elementReference = new CompoundTermImpl("element", index); 385// Iterator viewletsIterator = viewlets.iterator(); 386// ViewletData currentViewlet; 387// CompoundTerm viewletGoal; 388// Object viewableName = getViewable().getNameAtom(); 389 390// while(viewletsIterator.hasNext()) 391// { 392// currentViewlet = (ViewletData) viewletsIterator.next(); 393// //viewletGoal = currentViewlet.collectPreBuildGoal(); 394// //result.add(composeElementGoal(elementReference, 395// // viewletGoal)); 396// } 397// return(result); 398// } 399 400// private BatchGoal composeElementUpdateGoal(Collection viewlets, List index, UpdateEvent event) 401// { 402// BatchGoal result = new BatchGoal(); 403// Object elementReference = new CompoundTermImpl("element", index); 404// Iterator viewletsIterator = viewlets.iterator(); 405// ViewletData currentViewlet; 406// CompoundTerm viewletGoal; 407 408// while(viewletsIterator.hasNext()) 409// { 410// currentViewlet = (ViewletData) viewletsIterator.next(); 411// // viewletGoal = currentViewlet.collectPreUpdateGoal(event); 412// // result.add(composeElementGoal(elementReference, 413// // viewletGoal)); 414// } 415// return(result); 416// } 417 418// protected CompoundTerm composeElementGoal(Object elementReference, 419// CompoundTerm viewletGoal) 420// { 421// return(new CompoundTermImpl(":", vcSupportAtom, 422// new CompoundTermImpl("viewable_element_execute", 423// getViewable().getNameAtom(), elementReference, viewletGoal))); 424// } 425 426 private void setCreatedElementIndices(CreateEvent event) 427 { 428 List size = event.getViewableSize(); 429 // create an index representing the first element in the viewable 430 List start = new ArrayList(size.size()); 431 Integer one = new Integer(1); 432 for(int i = 0; i < size.size(); i++) { 433 start.add(one); 434 } 435 // createdElementIndices = allCombinations(size); 436 createdElementIndices = viewletDataStore.createRange(start,size); 437 if (DebuggingSupport.logMessages) { 438 DebuggingSupport.logMessage(this, 439 "setCreatedElementIndices event="+event+ 440 " start=" + start + " size=" +size + 441 "createdElementIndices=" + 442 createdElementIndices); 443 } 444 } 445 446 private void setExpandingElementIndices(ExpandEvent event) 447 { 448 int expandingDimension = event.getExpandingDimension(); 449 List size = event.getViewableSize(); 450 Integer newDimensionSize 451 = (Integer) size.get(expandingDimension-1);//list indices start at 0 452 453 // create an index representing the first element in the newly 454 // expanded dimension 455 List start = new ArrayList(size.size()); 456 Integer one = new Integer(1); 457 for(int i = 0; i < size.size(); i++) { 458 start.add(one); 459 } 460 start.set(expandingDimension-1, newDimensionSize); 461 expandingElementIndices = viewletDataStore.createRange(start, size); 462 } 463 464 private void setUpdatingElementIndices(UpdateEvent event) 465 { 466 updatingElementIndices = 467 viewletDataStore.createRange(event.getElementsUpdating()); 468 if (DebuggingSupport.logMessages) { 469 DebuggingSupport.logMessage(this, "setUpdatingElementIndices "+ 470 "event="+event+ 471 "event.getElementsUpdating()="+event.getElementsUpdating()+ 472 "updatingElementIndices="+updatingElementIndices); 473 } 474 } 475 476 477 protected ViewletRange getCreatedElementIndices() 478 { 479 return createdElementIndices; 480 } 481 482 protected ViewletRange getUpdatingElementIndices() 483 { 484 return updatingElementIndices; 485 } 486 487 protected ViewletRange getExpandingElementIndices() 488 { 489 return expandingElementIndices; 490 } 491 492 public void gainFocus() 493 { 494 super.gainFocus(); 495 // this.setSelection(selectionCopy); 496 getComponent().repaint(); 497 498 if (DebuggingSupport.logMessages) { 499 DebuggingSupport.logMessage(this, "focus gained"); 500 } 501 502 } 503 504 public void loseFocus() 505 { 506 super.loseFocus(); 507// try { 508// selectionCopy = (ViewletSelection)(getSelection().clone()); 509// } catch(CloneNotSupportedException e) { 510// if (DebuggingSupport.logMessages) { 511// DebuggingSupport.logMessage(this, "clone not supported"); 512// e.printStackTrace(System.err); 513// } 514// //selectionCopy = new LinkedList(getSelection()); 515// } 516 clearSelection(); 517 518 getComponent().repaint(); 519 520 if (DebuggingSupport.logMessages) { 521 DebuggingSupport.logMessage(this, "focus lost"); 522 } 523 524 } 525 526 //protected abstract ViewletTracker getViewletTracker(); 527 528 private void scrollToTrackUpdate(Collection updatingViewlets) 529 { 530// ViewletTracker viewletTracker = getViewletTracker(); 531// viewletTracker.setViewlets(getUpdatingViewlets()); 532// try { 533// SwingUtilities.invokeAndWait(viewletTracker); 534// } catch(Exception e) { throw new RuntimeException("Exception "+e+" thrown "+ 535// "while executing viewletTracker");} 536 } 537 538 public void startEvent(VisEvent event, java.util.List goalResults) 539 { 540 if(event instanceof UpdateEvent) 541 { 542 super.startEvent(event, (List) goalResults.get(0)); 543 distributeUpdateResults((List) goalResults.get(1), updatingElementIndices, 544 ((UpdateEvent) event)); 545 // When starting an update event, enable the selectUpdating action 546 // and track the update if this is switched on. 547 selectUpdatingAction.setEnabled(true); 548// if(trackUpdates) 549// { 550// scrollToTrackUpdate(getUpdatingViewlets()); 551// } 552 553 return; 554 } 555 else 556 { 557 // can't select updating viewlets unless update event is in progress 558 // this line is possibly unnecessary (why would the action be enabled?). 559 selectUpdatingAction.setEnabled(false); 560 } 561 562 563 if(event instanceof ExpandEvent) 564 { 565 size = ((ExpandEvent) event).getViewableSize(); 566 super.startEvent(event, (List) goalResults.get(0)); 567 String newLocationName = 568 locationNameFromGoalResult((CompoundTermImpl) goalResults.get(1)); 569 int dimNumber = ((ExpandEvent) event).getExpandingDimension(); 570 locationNames[dimNumber - 1].add(newLocationName); 571 572 if (DebuggingSupport.logMessages) { 573 DebuggingSupport.logMessage(this, "Added location name "+ 574 newLocationName+ 575 " to dimension "+dimNumber); 576 } 577 578 distributeBuildResults((List) goalResults.get(2), expandingElementIndices); 579 return; 580 } 581 582 583 if(event instanceof ContractEvent) 584 { 585 size = ((ContractEvent) event).getViewableSize(); 586 shrinkLocationNamesTo(size); 587 } 588 589 if(event instanceof CreateEvent) 590 { 591 size = ((CreateEvent) event).getViewableSize(); 592 super.startEvent(event, (List) goalResults.get(0)); 593 // extract the results of the "getDimension Location names" goals 594 int nDims = size.size(); 595 locationNames = new List[nDims]; 596 List locationNamesList; 597 int i; 598 for(i = 1 ; i <= nDims ; i++) 599 { 600 locationNamesList = 601 locationNamesFromGoalResult((CompoundTermImpl) goalResults.get(i)); 602 locationNames[i-1] = locationNamesList; 603 } 604 // distribute the "preBuild" goal results 605 distributeBuildResults((List) goalResults.get(i), createdElementIndices); 606 return; 607 } 608 super.startEvent(event, goalResults); 609 } 610 611 public Collection getCreatedViewlets() 612 { 613// if(createdViewlets == null) 614// { 615// createdViewlets = getViewletsAtIndexList(getCreatedElementIndices()); 616// } 617// return(createdViewlets); 618 return null; 619 } 620 621 public Collection getUpdatingViewlets() 622 { 623// if(updatingViewlets == null) 624// { 625// updatingViewlets = getViewletsAtIndexList(getUpdatingElementIndices()); 626// } 627// return(updatingViewlets); 628 return null; 629 } 630 631 public Collection getExpandingViewlets() 632 { 633// if(expandingViewlets == null) 634// { 635// expandingViewlets = getViewletsAtIndexList(getExpandingElementIndices()); 636// } 637// return(expandingViewlets); 638 return null; 639 } 640 641 private Collection getViewletDataAtIndexList(Collection indexList) 642 { 643 Iterator indexListIterator = indexList.iterator(); 644 List currentIndex; 645 Collection viewlets; 646 Collection result = new LinkedList(); 647 while(indexListIterator.hasNext()) 648 { 649 currentIndex = (List) indexListIterator.next(); 650 viewlets = getViewletDataAt(currentIndex); 651 result.addAll(viewlets); 652 } 653 return(result); 654 } 655 656 public boolean shouldHold() 657 { 658 if(super.shouldHold()) 659 { 660 return(true); 661 } 662 if(getCurrentEvent() instanceof UpdateEvent) 663 { 664 // Collection updatingViewlets = getUpdatingViewlets(); 665 Iterator updatingViewletsIterator = 666 viewletDataStore.getViewletDataIterator(new ViewletRangeCollection(updatingElementIndices)); 667 ViewletData currentViewlet; 668 while(updatingViewletsIterator.hasNext()) 669 { 670 currentViewlet = (ViewletData) updatingViewletsIterator.next(); 671 if(currentViewlet.getHoldsOnUpdates()) 672 { 673 return(true); 674 } 675 } 676 } 677 return(false); 678 } 679 680 private void distributeBuildResults(List results, ViewletRange indexList) 681 { 682 viewletType.startBuild(this, viewletDataStore, indexList, results); 683 /* 684 Iterator indexListIterator = indexList.iterator(); 685 Iterator resultsIterator = results.iterator(); 686 List elementResult; 687 Collection viewlets; 688 List currentIndex; 689 while(indexListIterator.hasNext()) 690 { 691 currentIndex = (List) indexListIterator.next(); 692 viewlets = getViewletDataAt(currentIndex); 693 elementResult = (List) resultsIterator.next(); 694 distributeBuildResult(elementResult, viewlets); 695 } 696 */ 697 } 698 699// private void distributeBuildResult(List elementResults, ViewletRange viewlets) 700// { 701// Iterator elementResultsIterator = elementResults.iterator(); 702// Iterator viewletsIterator = viewlets.iterator(); 703// ViewletData currentViewlet; 704// CompoundTermImpl currentResult; 705// Object next; 706// while(elementResultsIterator.hasNext()) 707// { 708// currentViewlet = (ViewletData) viewletsIterator.next(); 709// next = elementResultsIterator.next(); 710// // 711// if (DebuggingSupport.logMessages) { 712// DebuggingSupport.logMessage(this, "currentViewlet:"+currentViewlet); 713// DebuggingSupport.logMessage(this, "next:"+next); 714// } 715 716// //currentResult = (CompoundTermImpl) next; 717// //currentViewlet.startBuild((CompoundTerm) (currentResult.argCT(2).arg(3))); 718// } 719// } 720 721 private void distributeUpdateResults(List results, 722 ViewletRange indexList, 723 UpdateEvent event) 724 { 725 viewletType.startUpdate(this, 726 viewletDataStore, 727 indexList, 728 results, 729 event); 730 /* 731 Iterator indexListIterator = indexList.iterator(); 732 Iterator resultsIterator = results.iterator(); 733 List elementResult; 734 Collection viewlets; 735 List currentIndex; 736 while(indexListIterator.hasNext()) 737 { 738 currentIndex = (List) indexListIterator.next(); 739 viewlets = getViewletDataAt(currentIndex); 740 elementResult = (List) resultsIterator.next(); 741 distributeUpdateResult(elementResult, viewlets, event); 742 } 743 */ 744 } 745 746// private void distributeUpdateResult(List elementResults, Collection viewlets, 747// UpdateEvent event) 748// { 749// Iterator elementResultsIterator = elementResults.iterator(); 750// Iterator viewletsIterator = viewlets.iterator(); 751// ViewletData currentViewlet; 752// CompoundTermImpl currentResult; 753// while(elementResultsIterator.hasNext()) 754// { 755// currentViewlet = (ViewletData) viewletsIterator.next(); 756// currentResult = (CompoundTermImpl) elementResultsIterator.next(); 757// //currentViewlet.startUpdate(event, (CompoundTerm) currentResult.argCT(2).arg(3)); 758// } 759// } 760 761 public void stopEvent() 762 { 763 if(getCurrentEvent() instanceof CreateEvent) 764 { 765 stopBuild(createdElementIndices); 766 } 767 768 if(getCurrentEvent() instanceof ExpandEvent) 769 { 770 stopBuild(expandingElementIndices); 771 } 772 773 if(getCurrentEvent() instanceof UpdateEvent) 774 { 775 stopUpdate(updatingElementIndices); 776 selectUpdatingAction.setEnabled(false); 777 } 778 779 createdElementIndices = null; 780 updatingElementIndices = null; 781 expandingElementIndices = null; 782 //createdViewlets = null; 783 //updatingViewlets = null; 784 //expandingViewlets = null; 785 super.stopEvent(); 786 } 787 788 private void stopBuild(ViewletRange indexList) 789 { 790 Iterator indexListIterator = indexList.iterator(); 791 List currentIndex; 792 Iterator viewletIterator; 793 ViewletData currentViewlet; 794 795 while(indexListIterator.hasNext()) 796 { 797 currentIndex = (List) indexListIterator.next(); 798 viewletIterator = getViewletDataAt(currentIndex).iterator(); 799 while(viewletIterator.hasNext()) 800 { 801 currentViewlet = (ViewletData) viewletIterator.next(); 802 //currentViewlet.stopBuild(); 803 } 804 } 805 } 806 807 private void stopUpdate(ViewletRange indexList) 808 { 809 viewletType.stopUpdate(this, viewletDataStore, indexList); 810// Iterator indexListIterator = indexList.iterator(); 811// List currentIndex; 812// Iterator viewletIterator; 813// ViewletData currentViewlet; 814 815// while(indexListIterator.hasNext()) 816// { 817// currentIndex = (List) indexListIterator.next(); 818// viewletIterator = getViewletDataAt(currentIndex).iterator(); 819// while(viewletIterator.hasNext()) 820// { 821// currentViewlet = (ViewletData) viewletIterator.next(); 822// //currentViewlet.stopUpdate(); 823// } 824// } 825 } 826 827 protected abstract Collection getViewletDataAt(List index); 828 protected abstract ViewletRange getAllViewletData(); 829 830 831 /** 832 * dimNumber starts from 1. 833 */ 834 protected List getLocationNames(int dimNumber) 835 { 836 return(locationNames[dimNumber - 1]); 837 } 838 839 /** 840 * dimNumber & locNumber start from 1. 841 */ 842 protected String getLocationName(int dimNumber, int locNumber) 843 { 844 return((String) getLocationNames(dimNumber).get(locNumber - 1)); 845 } 846 847 private void shrinkLocationNamesTo(List newSize) 848 { 849 for(int i = 0; i < locationNames.length; i++) 850 { 851 int newDimSize = ((Integer) newSize.get(i)).intValue(); 852 List newLocationNames = locationNames[i].subList(0, newDimSize); 853 locationNames[i] = newLocationNames; 854 855 if (DebuggingSupport.logMessages) { 856 DebuggingSupport.logMessage(this, "location names of dimension "+(i+1)+ 857 " shrunk to "+newLocationNames); 858 } 859 860 } 861 } 862 863 864 private CompoundTerm getLocationNamesGoal(int dimNumber) 865 { 866 CompoundTerm locationNamesGoal = 867 new CompoundTermImpl(":", vcSupportAtom, 868 new CompoundTermImpl("viewable_get_location_names", 869 getViewable().getNameAtom(), 870 new Integer(dimNumber), null)); 871 return(locationNamesGoal); 872 } 873 874 private CompoundTerm getAddLocationNameGoal(int dimNumber, int newLocation) 875 { 876 CompoundTerm addLocationNameGoal = 877 new CompoundTermImpl(":", vcSupportAtom, 878 new CompoundTermImpl("viewable_get_location_name", 879 getViewable().getNameAtom(), 880 new Integer(dimNumber), 881 new Integer(newLocation), 882 null)); 883 return(addLocationNameGoal); 884 } 885 886 private List locationNamesFromGoalResult(CompoundTermImpl result) 887 { 888 return((List) result.argCT(2).arg(3)); 889 } 890 891 private String locationNameFromGoalResult(CompoundTermImpl result) 892 { 893 return((String) result.argCT(2).arg(4)); 894 } 895 896 private abstract class ViewletSelectionAction extends AbstractAction 897 { 898 protected abstract ViewletRange newSelection(); 899 900 ViewletSelectionAction(String text) 901 { 902 super(text); 903 } 904 public void actionPerformed(ActionEvent event) 905 { 906 clearSelection(); 907 //addAllToSelection(newSelection()); 908 setSelection(newSelection()); 909 getComponent().repaint(); 910 } 911 } 912 913 private class SelectAllAction extends ViewletSelectionAction 914 { 915 SelectAllAction() 916 { 917 super("Select all viewlets"); 918 } 919 protected ViewletRange newSelection() 920 { 921 return(viewletDataStore.getEntireViewletRange()); 922 } 923 } 924 925 private class SelectUpdatingAction extends ViewletSelectionAction 926 { 927 SelectUpdatingAction() 928 { 929 super("Select updating viewlet(s)"); 930 setEnabled(false); 931 } 932 protected ViewletRange newSelection() 933 { 934 return getUpdatingElementIndices(); 935 } 936 } 937 938 private class ClearSelectionAction extends ViewletSelectionAction 939 { 940 ClearSelectionAction() 941 { 942 super("Clear selection"); 943 } 944 protected ViewletRange newSelection() 945 { 946 return new ViewletRangeCollection(); 947 } 948 } 949 950 protected Action getZoomInAction(Viewer viewer, float ratio) 951 { 952 return(new ZoomInAction(viewer, ratio)); 953 } 954 955 protected Action getZoomAction(Viewer viewer, float zoomRatio) 956 { 957 return(new ZoomAction(viewer, zoomRatio)); 958 } 959 960 protected Action getZoomNormalAction(Viewer viewer) 961 { 962 return(new ZoomNormalAction(viewer)); 963 } 964 965 private class ZoomAction extends AbstractAction 966 { 967 private float zoomRatio; 968 private Viewer viewer; 969 970 ZoomAction(Viewer viewer, float zoomRatio) 971 { 972 super("Zoom to "+((int)(zoomRatio*100))+"%"); 973 this.zoomRatio = zoomRatio; 974 this.viewer = viewer; 975 } 976 public void actionPerformed(ActionEvent event) 977 { 978 (new ViewerZoomCommand(viewer, zoomRatio)).issue(); 979 } 980 } 981 982 private class ZoomInAction extends AbstractAction 983 { 984 private float zoomRatio; 985 private Viewer viewer; 986 987 ZoomInAction(Viewer viewer, float zoomRatio) 988 { 989 super("Zoom "+((zoomRatio<1)?"out":"in")+" by "+ 990 ((int)(((zoomRatio<1)?(1/zoomRatio):zoomRatio)*100))+"%"); 991 this.zoomRatio = zoomRatio; 992 this.viewer = viewer; 993 } 994 public void actionPerformed(ActionEvent event) 995 { 996 (new ViewerZoomInCommand(viewer, zoomRatio)).issue(); 997 } 998 } 999 1000 private class ZoomNormalAction extends ZoomAction 1001 { 1002 ZoomNormalAction(Viewer viewer) 1003 { 1004 super(viewer, 1.0f); 1005 this.putValue(Action.NAME, "Zoom to normal size"); 1006 } 1007 } 1008 1009 /** Returns any actions/menu items that should be available via a 1010 right-click popup menu */ 1011 public Collection getViewerPopupMenuCollection() { 1012 Collection result = new LinkedList(); 1013 result.add(getPopupMenu("Select")); 1014 result.add(getPopupMenu("View")); 1015 return result; 1016 } 1017 1018 1019 /** Access the context sensitive popup menu */ 1020 public JPopupMenu getPopupMenu() { 1021 JPopupMenu menu = super.getPopupMenu(); 1022 // Add action specific to the current selection 1023 ViewletRange range = getSelection(); 1024 if (range != null) { 1025 for(Iterator it = viewletType.getActions(viewletDataStore, range).iterator(); 1026 it.hasNext();) { 1027 menu.add((Action)(it.next())); 1028 } 1029 } 1030 // Add actions specific to this viewer 1031 menu.addSeparator(); 1032 for(Iterator it = getViewerPopupMenuCollection().iterator(); 1033 it.hasNext();) { 1034 Object item = it.next(); 1035 if (item instanceof Action) { 1036 menu.add((Action)(item)); 1037 } else if (item instanceof JMenuItem) { 1038 menu.add((JMenuItem)(item)); 1039 } else if (item instanceof Component) { 1040 menu.add((Component)(item)); 1041 } else if (item instanceof String) { 1042 menu.add((String)(item)); 1043 } else if (item instanceof JMenu) { 1044 menu.add((JMenu)item); 1045 } 1046 } 1047 return menu; 1048 } 1049} 1050