1 23 24 package org.objectweb.fractal.gui.undo.model; 25 26 import org.objectweb.fractal.api.control.BindingController; 27 28 import org.objectweb.fractal.gui.graph.model.GraphModel; 29 import org.objectweb.fractal.gui.graph.model.GraphModelListener; 30 import org.objectweb.fractal.gui.graph.model.Rect; 31 import org.objectweb.fractal.gui.model.ClientInterface; 32 import org.objectweb.fractal.gui.model.Component; 33 import org.objectweb.fractal.gui.model.ConfigurationListener; 34 import org.objectweb.fractal.gui.model.Interface; 35 import org.objectweb.fractal.gui.model.ServerInterface; 36 import org.objectweb.fractal.gui.model.Configuration; 37 38 import java.util.ArrayList ; 39 import java.util.List ; 40 import java.util.Map ; 41 import java.util.HashMap ; 42 import java.util.Iterator ; 43 import java.awt.Color ; 44 45 48 49 public class BasicUndoManager implements 50 UndoManager, 51 ConfigurationListener, 52 GraphModelListener, 53 BindingController 54 { 55 56 61 62 public final static String CONFIGURATION_BINDING = "configuration"; 63 64 69 70 public final static String GRAPH_BINDING = "graph"; 71 72 76 77 public final static String UNDO_LISTENERS_BINDING = "undo-listeners"; 78 79 82 83 private final static int MAX_UNDO = 50; 84 85 88 89 private Configuration configuration; 90 91 94 95 private GraphModel graph; 96 97 100 101 private Map undoListeners; 102 103 106 107 private List undoList; 108 109 112 113 private List redoList; 114 115 118 119 private boolean isUndoing; 120 121 124 125 private boolean isRedoing; 126 127 130 131 public BasicUndoManager () { 132 undoList = new ArrayList (); 133 redoList = new ArrayList (); 134 undoListeners = new HashMap (); 135 } 136 137 141 public String [] listFc () { 142 int size = undoListeners.size(); 143 String [] names = new String [size + 2]; 144 undoListeners.keySet().toArray(names); 145 names[size] = CONFIGURATION_BINDING; 146 names[size + 1] = GRAPH_BINDING; 147 return names; 148 } 149 150 public Object lookupFc (final String clientItfName) { 151 if (CONFIGURATION_BINDING.equals(clientItfName)) { 152 return configuration; 153 } else if (GRAPH_BINDING.equals(clientItfName)) { 154 return graph; 155 } else if (clientItfName.startsWith(UNDO_LISTENERS_BINDING)) { 156 return undoListeners.get(clientItfName); 157 } 158 return null; 159 } 160 161 162 public void bindFc ( 163 final String clientItfName, 164 final Object serverItf) 165 { 166 if (CONFIGURATION_BINDING.equals(clientItfName)) { 167 configuration = (Configuration)serverItf; 168 } else if (GRAPH_BINDING.equals(clientItfName)) { 169 graph = (GraphModel)serverItf; 170 } else if (clientItfName.startsWith(UNDO_LISTENERS_BINDING)) { 171 undoListeners.put(clientItfName, serverItf); 172 } 173 } 174 175 public void unbindFc (final String clientItfName) { 176 if (CONFIGURATION_BINDING.equals(clientItfName)) { 177 configuration = null; 178 } else if (GRAPH_BINDING.equals(clientItfName)) { 179 graph = null; 180 } else if (clientItfName.startsWith(UNDO_LISTENERS_BINDING)) { 181 undoListeners.remove(clientItfName); 182 } 183 } 184 185 189 public void changeCountChanged (Component component, long changeCount) { 190 } 192 193 public void rootComponentChanged (final Component oldValue) { 194 clear(); 195 } 196 197 public void nameChanged (final Component component, final String oldValue) { 198 if (configuration.getRootComponent().contains(component)) { 199 addAction(new Action(component, 1) { 200 void run () { 201 ((Component)target).setName(oldValue); 202 } 203 }); 204 } 205 } 206 207 public void typeChanged (final Component component, final String oldValue) { 208 if (configuration.getRootComponent().contains(component)) { 209 addAction(new Action(component, 1) { 210 void run () { 211 ((Component)target).setType(oldValue); 212 } 213 }); 214 } 215 } 216 217 public void implementationChanged ( 218 final Component component, 219 final String oldValue) 220 { 221 if (configuration.getRootComponent().contains(component)) { 222 addAction(new Action(component, 1) { 223 void run () { 224 ((Component)target).setImplementation(oldValue); 225 } 226 }); 227 } 228 } 229 230 public void interfaceNameChanged (final Interface i, final String oldValue) { 231 if (configuration.getRootComponent().contains(i.getOwner())) { 232 addAction(new Action(i, 1) { 233 void run () { 234 ((Interface)target).setName(oldValue); 235 } 236 }); 237 } 238 } 239 240 public void interfaceSignatureChanged ( 241 final Interface i, 242 final String oldValue) 243 { 244 if (configuration.getRootComponent().contains(i.getOwner())) { 245 addAction(new Action(i, 1) { 246 void run () { 247 ((Interface)target).setSignature(oldValue); 248 } 249 }); 250 } 251 } 252 253 public void interfaceContingencyChanged ( 254 final Interface i, 255 final boolean oldValue) 256 { 257 if (configuration.getRootComponent().contains(i.getOwner())) { 258 addAction(new Action(i, 1) { 259 void run () { 260 ((Interface)target).setIsOptional(oldValue); 261 } 262 }); 263 } 264 } 265 266 public void interfaceCardinalityChanged ( 267 final Interface i, 268 final boolean oldValue) 269 { 270 if (configuration.getRootComponent().contains(i.getOwner())) { 271 addAction(new Action(i, 1) { 272 void run () { 273 ((Interface)target).setIsCollection(oldValue); 274 } 275 }); 276 } 277 } 278 279 public void clientInterfaceAdded ( 280 final Component component, 281 final ClientInterface i, 282 final int index) 283 { 284 if (configuration.getRootComponent().contains(component)) { 285 addAction(new Action(null, 1) { 286 void run () { 287 component.removeClientInterface(i); 288 } 289 }); 290 } 291 } 292 293 public void clientInterfaceRemoved ( 294 final Component component, 295 final ClientInterface i, 296 final int index) 297 { 298 if (configuration.getRootComponent().contains(component)) { 299 addAction(new Action(null, 1) { 300 void run () { 301 component.addClientInterface(i); 302 } 303 }); 304 } 305 } 306 307 public void serverInterfaceAdded ( 308 final Component component, 309 final ServerInterface i, 310 final int index) 311 { 312 if (configuration.getRootComponent().contains(component)) { 313 addAction(new Action(null, 1) { 314 void run () { 315 component.removeServerInterface(i); 316 } 317 }); 318 } 319 } 320 321 public void serverInterfaceRemoved ( 322 final Component component, 323 final ServerInterface i, 324 final int index) 325 { 326 if (configuration.getRootComponent().contains(component)) { 327 addAction(new Action(null, 1) { 328 void run () { 329 component.addServerInterface(i); 330 } 331 }); 332 } 333 } 334 335 public void interfaceBound ( 336 final ClientInterface citf, 337 final ServerInterface sitf) 338 { 339 if (configuration.getRootComponent().contains(citf.getOwner())) { 340 addAction(new Action(null, 1) { 341 void run () { 342 citf.getOwner().unbind(citf); 343 } 344 }); 345 } 346 } 347 348 public void interfaceRebound ( 349 final ClientInterface citf, 350 final ServerInterface oldSitf) 351 { 352 if (configuration.getRootComponent().contains(citf.getOwner())) { 353 addAction(new Action(null, 1) { 354 void run () { 355 citf.getOwner().rebind(citf, oldSitf); 356 } 357 }); 358 } 359 } 360 361 public void interfaceUnbound ( 362 final ClientInterface citf, 363 final ServerInterface sitf) 364 { 365 if (configuration.getRootComponent().contains(citf.getOwner())) { 366 addAction(new Action(null, 1) { 367 void run () { 368 citf.getOwner().bind(citf, null, sitf); 369 } 370 }); 371 } 372 } 373 374 public void attributeControllerChanged ( 375 final Component component, 376 final String oldValue) 377 { 378 if (configuration.getRootComponent().contains(component)) { 379 addAction(new Action(component, 1) { 380 void run () { 381 ((Component)target).setAttributeController(oldValue); 382 } 383 }); 384 } 385 } 386 387 public void attributeChanged ( 388 final Component component, 389 final String attributeName, 390 final String oldValue) 391 { 392 if (configuration.getRootComponent().contains(component)) { 393 addAction(new Action(component, 1) { 394 void run () { 395 ((Component)target).setAttribute(attributeName, oldValue); 396 } 397 }); 398 } 399 } 400 401 public void templateControllerDescriptorChanged ( 402 final Component component, 403 final String oldValue) 404 { 405 if (configuration.getRootComponent().contains(component)) { 406 addAction(new Action(component, 1) { 407 void run () { 408 ((Component)target).setTemplateControllerDescriptor(oldValue); 409 } 410 }); 411 } 412 } 413 414 public void componentControllerDescriptorChanged ( 415 final Component component, 416 final String oldValue) 417 { 418 if (configuration.getRootComponent().contains(component)) { 419 addAction(new Action(component, 1) { 420 void run () { 421 ((Component)target).setComponentControllerDescriptor(oldValue); 422 } 423 }); 424 } 425 } 426 427 public void subComponentAdded ( 428 final Component parent, 429 final Component child, 430 final int index) 431 { 432 if (configuration.getRootComponent().contains(parent)) { 433 addAction(new Action(null, 1) { 434 void run () { 435 parent.removeSubComponent(child); 436 } 437 }); 438 } 439 } 440 441 public void subComponentRemoved ( 442 final Component parent, 443 final Component child, 444 final int index) 445 { 446 if (configuration.getRootComponent().contains(parent)) { 447 addAction(new Action(null, 1) { 448 void run () { 449 parent.addSubComponent(child); 450 } 451 }); 452 } 453 } 454 455 459 public void componentColorChanged ( 460 final Component component, 461 final Color oldColor) 462 { 463 if (configuration.getRootComponent().contains(component)) { 464 addAction(new Action(component, 0) { 465 void run () { 466 graph.setComponentColor((Component)target, oldColor); 467 } 468 }); 469 } 470 } 471 472 public void componentPositionChanged ( 473 final Component component, 474 final Rect oldValue) 475 { 476 if (configuration.getRootComponent().contains(component)) { 477 addAction(new Action(component, 0) { 478 void run () { 479 graph.setComponentPosition((Component)target, oldValue); 480 } 481 }); 482 } 483 } 484 485 489 public boolean canUndo () { 490 return undoList.size() > 0; 491 } 492 493 public void undo () { 494 isUndoing = true; 495 try { 496 Action a = (Action)undoList.remove(undoList.size() - 1); 497 configuration.setChangeCount( 498 configuration.getChangeCount() - 2*a.deltaChangeCount); 499 a.run(); 500 } finally { 501 isUndoing = false; 502 } 503 if (undoList.size() == 0) { 504 notifyListeners(); 505 } 506 } 507 508 public boolean canRedo () { 509 return redoList.size() > 0; 510 } 511 512 public void redo () { 513 isRedoing = true; 514 try { 515 ((Action)redoList.remove(redoList.size() - 1)).run(); 516 } finally { 517 isRedoing = false; 518 } 519 if (redoList.size() == 0) { 520 notifyListeners(); 521 } 522 } 523 524 public void clear () { 525 undoList.clear(); 526 redoList.clear(); 527 notifyListeners(); 528 } 529 530 534 537 538 abstract class Action { 539 540 544 545 Object target; 546 547 550 551 int deltaChangeCount; 552 553 560 561 Action (final Object target, int deltaChangeCount) { 562 this.target = target; 563 this.deltaChangeCount = deltaChangeCount; 564 } 565 566 569 570 abstract void run (); 571 } 572 573 578 579 private void addAction (final Action a) { 580 if (!isUndoing && !isRedoing && redoList.size() > 0) { 581 redoList.clear(); 582 notifyListeners(); 583 } 584 List l = isUndoing ? redoList : undoList; 585 if (l.size() == 0) { 586 l.add(a); 587 notifyListeners(); 588 } else { 589 Action last = (Action)l.get(l.size() - 1); 590 if (last.getClass() == a.getClass() && 591 last.target == a.target && 592 a.target != null) 593 { 594 return; 596 } 597 if (l.size() >= MAX_UNDO) { 598 l.remove(0); 599 } 600 l.add(a); 601 } 602 } 603 604 607 608 private void notifyListeners () { 609 Iterator i = undoListeners.values().iterator(); 610 while (i.hasNext()) { 611 ((UndoListener)i.next()).undoStateChanged(); 612 } 613 } 614 } 615 | Popular Tags |