1 11 12 package org.eclipse.ui.internal.forms; 13 14 import java.io.PrintWriter ; 15 import java.io.StringWriter ; 16 import java.util.ArrayList ; 17 import java.util.Enumeration ; 18 import java.util.Hashtable ; 19 import java.util.Iterator ; 20 21 import org.eclipse.jface.dialogs.IMessageProvider; 22 import org.eclipse.jface.fieldassist.ControlDecoration; 23 import org.eclipse.jface.fieldassist.FieldDecoration; 24 import org.eclipse.jface.fieldassist.FieldDecorationRegistry; 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.custom.CLabel; 27 import org.eclipse.swt.widgets.Composite; 28 import org.eclipse.swt.widgets.Control; 29 import org.eclipse.swt.widgets.Label; 30 import org.eclipse.ui.forms.IMessage; 31 import org.eclipse.ui.forms.IMessageManager; 32 import org.eclipse.ui.forms.IMessagePrefixProvider; 33 import org.eclipse.ui.forms.widgets.Hyperlink; 34 import org.eclipse.ui.forms.widgets.ScrolledForm; 35 36 39 40 public class MessageManager implements IMessageManager { 41 private static final DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER = new DefaultPrefixProvider(); 42 private ArrayList messages = new ArrayList (); 43 private Hashtable decorators = new Hashtable (); 44 private boolean autoUpdate = true; 45 private ScrolledForm scrolledForm; 46 private IMessagePrefixProvider prefixProvider = DEFAULT_PREFIX_PROVIDER; 47 private int decorationPosition = SWT.LEFT | SWT.BOTTOM; 48 private static FieldDecoration standardError = FieldDecorationRegistry 49 .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); 50 private static FieldDecoration standardWarning = FieldDecorationRegistry 51 .getDefault().getFieldDecoration( 52 FieldDecorationRegistry.DEC_WARNING); 53 54 private static final String [] SINGLE_MESSAGE_SUMMARY_KEYS = { 55 Messages.MessageManager_sMessageSummary, 56 Messages.MessageManager_sMessageSummary, 57 Messages.MessageManager_sWarningSummary, 58 Messages.MessageManager_sErrorSummary }; 59 60 private static final String [] MULTIPLE_MESSAGE_SUMMARY_KEYS = { 61 Messages.MessageManager_pMessageSummary, 62 Messages.MessageManager_pMessageSummary, 63 Messages.MessageManager_pWarningSummary, 64 Messages.MessageManager_pErrorSummary }; 65 66 static class Message implements IMessage { 67 Control control; 68 Object data; 69 Object key; 70 String message; 71 int type; 72 String prefix; 73 74 Message(Object key, String message, int type, Object data) { 75 this.key = key; 76 this.message = message; 77 this.type = type; 78 this.data = data; 79 } 80 81 86 public Object getKey() { 87 return key; 88 } 89 90 95 public String getMessage() { 96 return message; 97 } 98 99 104 public int getMessageType() { 105 return type; 106 } 107 108 113 public Control getControl() { 114 return control; 115 } 116 117 122 public Object getData() { 123 return data; 124 } 125 126 131 public String getPrefix() { 132 return prefix; 133 } 134 } 135 136 static class DefaultPrefixProvider implements IMessagePrefixProvider { 137 138 public String getPrefix(Control c) { 139 Composite parent = c.getParent(); 140 Control[] siblings = parent.getChildren(); 141 for (int i = 0; i < siblings.length; i++) { 142 if (siblings[i] == c) { 143 for (int j = i - 1; j >= 0; j--) { 146 Control label = siblings[j]; 147 String ltext = null; 148 if (label instanceof Label) { 149 ltext = ((Label) label).getText(); 150 } else if (label instanceof Hyperlink) { 151 ltext = ((Hyperlink) label).getText(); 152 } else if (label instanceof CLabel) { 153 ltext = ((CLabel) label).getText(); 154 } 155 if (ltext != null) { 156 if (!ltext.endsWith(":")) return ltext + ": "; return ltext + " "; } 160 } 161 break; 162 } 163 } 164 return null; 165 } 166 } 167 168 class ControlDecorator { 169 private ControlDecoration decoration; 170 private ArrayList controlMessages = new ArrayList (); 171 private String prefix; 172 173 ControlDecorator(Control control) { 174 this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody()); 175 } 176 177 public boolean isDisposed() { 178 return decoration.getControl() == null; 179 } 180 181 void updatePrefix() { 182 prefix = null; 183 } 184 185 void updatePosition() { 186 Control control = decoration.getControl(); 187 decoration.dispose(); 188 this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody()); 189 update(); 190 } 191 192 String getPrefix() { 193 if (prefix == null) 194 createPrefix(); 195 return prefix; 196 } 197 198 private void createPrefix() { 199 if (prefixProvider == null) { 200 prefix = ""; return; 202 } 203 prefix = prefixProvider.getPrefix(decoration.getControl()); 204 if (prefix == null) 205 prefix = ""; } 208 209 void addAll(ArrayList target) { 210 target.addAll(controlMessages); 211 } 212 213 void addMessage(Object key, String text, Object data, int type) { 214 Message message = MessageManager.this.addMessage(getPrefix(), key, 215 text, data, type, controlMessages); 216 message.control = decoration.getControl(); 217 if (isAutoUpdate()) 218 update(); 219 } 220 221 boolean removeMessage(Object key) { 222 Message message = findMessage(key, controlMessages); 223 if (message != null) { 224 controlMessages.remove(message); 225 if (isAutoUpdate()) 226 update(); 227 } 228 return message != null; 229 } 230 231 boolean removeMessages() { 232 if (controlMessages.isEmpty()) 233 return false; 234 controlMessages.clear(); 235 if (isAutoUpdate()) 236 update(); 237 return true; 238 } 239 240 public void update() { 241 if (controlMessages.isEmpty()) { 242 decoration.setDescriptionText(null); 243 decoration.hide(); 244 } else { 245 ArrayList peers = createPeers(controlMessages); 246 int type = ((IMessage) peers.get(0)).getMessageType(); 247 String description = createDetails(createPeers(peers), true); 248 if (type == IMessageProvider.ERROR) 249 decoration.setImage(standardError.getImage()); 250 else if (type == IMessageProvider.WARNING) 251 decoration.setImage(standardWarning.getImage()); 252 decoration.setDescriptionText(description); 253 decoration.show(); 254 } 255 } 256 } 257 258 265 public MessageManager(ScrolledForm scrolledForm) { 266 this.scrolledForm = scrolledForm; 267 } 268 269 275 public void addMessage(Object key, String messageText, Object data, int type) { 276 addMessage(null, key, messageText, data, type, messages); 277 if (isAutoUpdate()) 278 updateForm(); 279 } 280 281 287 public void addMessage(Object key, String messageText, Object data, 288 int type, Control control) { 289 ControlDecorator dec = (ControlDecorator) decorators.get(control); 290 291 if (dec == null) { 292 dec = new ControlDecorator(control); 293 decorators.put(control, dec); 294 } 295 dec.addMessage(key, messageText, data, type); 296 if (isAutoUpdate()) 297 updateForm(); 298 } 299 300 305 public void removeMessage(Object key) { 306 Message message = findMessage(key, messages); 307 if (message != null) { 308 messages.remove(message); 309 if (isAutoUpdate()) 310 updateForm(); 311 } 312 } 313 314 319 public void removeMessages() { 320 if (!messages.isEmpty()) { 321 messages.clear(); 322 if (isAutoUpdate()) 323 updateForm(); 324 } 325 } 326 327 333 public void removeMessage(Object key, Control control) { 334 ControlDecorator dec = (ControlDecorator) decorators.get(control); 335 if (dec == null) 336 return; 337 if (dec.removeMessage(key)) 338 if (isAutoUpdate()) 339 updateForm(); 340 } 341 342 347 public void removeMessages(Control control) { 348 ControlDecorator dec = (ControlDecorator) decorators.get(control); 349 if (dec != null) { 350 if (dec.removeMessages()) { 351 if (isAutoUpdate()) 352 updateForm(); 353 } 354 } 355 } 356 357 362 public void removeAllMessages() { 363 boolean needsUpdate = false; 364 for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) { 365 ControlDecorator control = (ControlDecorator) enm.nextElement(); 366 if (control.removeMessages()) 367 needsUpdate = true; 368 } 369 if (!messages.isEmpty()) { 370 messages.clear(); 371 needsUpdate = true; 372 } 373 if (needsUpdate && isAutoUpdate()) 374 updateForm(); 375 } 376 377 380 381 private Message addMessage(String prefix, Object key, String messageText, 382 Object data, int type, ArrayList list) { 383 Message message = findMessage(key, list); 384 if (message == null) { 385 message = new Message(key, messageText, type, data); 386 message.prefix = prefix; 387 list.add(message); 388 } else { 389 message.message = messageText; 390 message.type = type; 391 message.data = data; 392 } 393 return message; 394 } 395 396 399 400 private Message findMessage(Object key, ArrayList list) { 401 for (int i = 0; i < list.size(); i++) { 402 Message message = (Message) list.get(i); 403 if (message.getKey().equals(key)) 404 return message; 405 } 406 return null; 407 } 408 409 414 public void update() { 415 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { 417 ControlDecorator dec = (ControlDecorator) iter.next(); 418 dec.update(); 419 } 420 updateForm(); 422 } 423 424 427 428 private void updateForm() { 429 ArrayList mergedList = new ArrayList (); 430 mergedList.addAll(messages); 431 for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) { 432 ControlDecorator dec = (ControlDecorator) enm.nextElement(); 433 dec.addAll(mergedList); 434 } 435 update(mergedList); 436 } 437 438 private void update(ArrayList mergedList) { 439 pruneControlDecorators(); 440 if (mergedList.isEmpty() || mergedList == null) { 441 scrolledForm.setMessage(null, IMessageProvider.NONE); 442 return; 443 } 444 ArrayList peers = createPeers(mergedList); 445 int maxType = ((IMessage) peers.get(0)).getMessageType(); 446 String messageText; 447 IMessage[] array = (IMessage[]) peers 448 .toArray(new IMessage[peers.size()]); 449 if (peers.size() == 1 && ((Message) peers.get(0)).prefix == null) { 450 IMessage message = (IMessage) peers.get(0); 452 messageText = message.getMessage(); 453 scrolledForm.setMessage(messageText, maxType, array); 454 } else { 455 if (peers.size() > 1) 458 messageText = Messages.bind( 459 MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType], 460 new String [] { peers.size() + "" }); else 462 messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType]; 463 scrolledForm.setMessage(messageText, maxType, array); 464 } 465 } 466 467 private static String getFullMessage(IMessage message) { 468 if (message.getPrefix() == null) 469 return message.getMessage(); 470 return message.getPrefix() + message.getMessage(); 471 } 472 473 private ArrayList createPeers(ArrayList messages) { 474 ArrayList peers = new ArrayList (); 475 int maxType = 0; 476 for (int i = 0; i < messages.size(); i++) { 477 Message message = (Message) messages.get(i); 478 if (message.type > maxType) { 479 peers.clear(); 480 maxType = message.type; 481 } 482 if (message.type == maxType) 483 peers.add(message); 484 } 485 return peers; 486 } 487 488 private String createDetails(ArrayList messages, boolean excludePrefix) { 489 StringWriter sw = new StringWriter (); 490 PrintWriter out = new PrintWriter (sw); 491 492 for (int i = 0; i < messages.size(); i++) { 493 if (i > 0) 494 out.println(); 495 IMessage m = (IMessage) messages.get(i); 496 out.print(excludePrefix ? m.getMessage() : getFullMessage(m)); 497 } 498 out.flush(); 499 return sw.toString(); 500 } 501 502 public static String createDetails(IMessage[] messages) { 503 if (messages == null || messages.length == 0) 504 return null; 505 StringWriter sw = new StringWriter (); 506 PrintWriter out = new PrintWriter (sw); 507 508 for (int i = 0; i < messages.length; i++) { 509 if (i > 0) 510 out.println(); 511 out.print(getFullMessage(messages[i])); 512 } 513 out.flush(); 514 return sw.toString(); 515 } 516 517 522 public String createSummary(IMessage[] messages) { 523 return createDetails(messages); 524 } 525 526 private void pruneControlDecorators() { 527 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { 528 ControlDecorator dec = (ControlDecorator) iter.next(); 529 if (dec.isDisposed()) 530 iter.remove(); 531 } 532 } 533 534 539 public IMessagePrefixProvider getMessagePrefixProvider() { 540 return prefixProvider; 541 } 542 543 548 public void setMessagePrefixProvider(IMessagePrefixProvider provider) { 549 this.prefixProvider = provider; 550 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { 551 ControlDecorator dec = (ControlDecorator) iter.next(); 552 dec.updatePrefix(); 553 } 554 } 555 556 561 public int getDecorationPosition() { 562 return decorationPosition; 563 } 564 565 570 public void setDecorationPosition(int position) { 571 this.decorationPosition = position; 572 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) { 573 ControlDecorator dec = (ControlDecorator) iter.next(); 574 dec.updatePosition(); 575 } 576 } 577 578 583 public boolean isAutoUpdate() { 584 return autoUpdate; 585 } 586 587 592 public void setAutoUpdate(boolean autoUpdate) { 593 boolean needsUpdate = !this.autoUpdate && autoUpdate; 594 this.autoUpdate = autoUpdate; 595 if (needsUpdate) 596 update(); 597 } 598 } | Popular Tags |