comparison org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/MessageManager.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children dbfb303e8fb0
comparison
equal deleted inserted replaced
11:43904fec5dca 12:bc29606a740c
1 /*******************************************************************************
2 * Copyright (c) 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 ******************************************************************************/
13
14 module org.eclipse.ui.internal.forms.MessageManager;
15
16 import org.eclipse.ui.internal.forms.Messages;
17
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.custom.CLabel;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Label;
23 import org.eclipse.jface.dialogs.IMessageProvider;
24 import org.eclipse.jface.fieldassist.ControlDecoration;
25 import org.eclipse.jface.fieldassist.FieldDecoration;
26 import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
27 import org.eclipse.ui.forms.IMessage;
28 import org.eclipse.ui.forms.IMessageManager;
29 import org.eclipse.ui.forms.IMessagePrefixProvider;
30 import org.eclipse.ui.forms.widgets.Hyperlink;
31 import org.eclipse.ui.forms.widgets.ScrolledForm;
32
33 import java.lang.all;
34 import java.util.Enumeration;
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.Set;
38
39 import tango.util.Convert;
40 import tango.text.Text;
41 import tango.io.model.IFile;
42
43 /**
44 * @see IMessageManager
45 */
46
47 public class MessageManager : IMessageManager {
48
49 private static DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER_;
50 private static DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER(){
51 if( DEFAULT_PREFIX_PROVIDER_ is null ){
52 synchronized(MessageManager.classinfo){
53 if( DEFAULT_PREFIX_PROVIDER_ is null ){
54 DEFAULT_PREFIX_PROVIDER_ = new DefaultPrefixProvider();
55 }
56 }
57 }
58 return DEFAULT_PREFIX_PROVIDER_;
59 }
60 private ArrayList messages;
61 private Hashtable decorators;
62 private bool autoUpdate = true;
63 private ScrolledForm scrolledForm;
64 private IMessagePrefixProvider prefixProvider;
65 private int decorationPosition = SWT.LEFT | SWT.BOTTOM;
66
67 private static FieldDecoration standardError_;
68 private static FieldDecoration standardError(){
69 if( standardError_ is null ){
70 synchronized(MessageManager.classinfo){
71 if( standardError_ is null ){
72 standardError_ = FieldDecorationRegistry
73 .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
74 }
75 }
76 }
77 return standardError_;
78 }
79
80 private static FieldDecoration standardWarning_;
81 private static FieldDecoration standardWarning(){
82 if( standardWarning_ is null ){
83 synchronized(MessageManager.classinfo){
84 if( standardWarning_ is null ){
85 standardWarning_ = FieldDecorationRegistry
86 .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
87 }
88 }
89 }
90 return standardWarning_;
91 }
92
93 private static FieldDecoration standardInformation_;
94 private static FieldDecoration standardInformation(){
95 if( standardInformation_ is null ){
96 synchronized(MessageManager.classinfo){
97 if( standardInformation_ is null ){
98 standardInformation_ = FieldDecorationRegistry
99 .getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION);
100 }
101 }
102 }
103 return standardInformation_;
104 }
105
106 private static String[] SINGLE_MESSAGE_SUMMARY_KEYS_;
107 private static String[] SINGLE_MESSAGE_SUMMARY_KEYS(){
108 if( SINGLE_MESSAGE_SUMMARY_KEYS_ is null ){
109 synchronized(MessageManager.classinfo){
110 if( SINGLE_MESSAGE_SUMMARY_KEYS_ is null ){
111 SINGLE_MESSAGE_SUMMARY_KEYS_ = [
112 Messages.MessageManager_sMessageSummary,
113 Messages.MessageManager_sMessageSummary,
114 Messages.MessageManager_sWarningSummary,
115 Messages.MessageManager_sErrorSummary ];
116 }
117 }
118 }
119 return SINGLE_MESSAGE_SUMMARY_KEYS_;
120 }
121
122 private static String[] MULTIPLE_MESSAGE_SUMMARY_KEYS_;
123 private static String[] MULTIPLE_MESSAGE_SUMMARY_KEYS(){
124 if( MULTIPLE_MESSAGE_SUMMARY_KEYS_ is null ){
125 synchronized(MessageManager.classinfo){
126 if( MULTIPLE_MESSAGE_SUMMARY_KEYS_ is null ){
127 MULTIPLE_MESSAGE_SUMMARY_KEYS_ = [
128 Messages.MessageManager_pMessageSummary,
129 Messages.MessageManager_pMessageSummary,
130 Messages.MessageManager_pWarningSummary,
131 Messages.MessageManager_pErrorSummary ];
132 }
133 }
134 }
135 return MULTIPLE_MESSAGE_SUMMARY_KEYS_;
136 }
137
138 static class Message : IMessage {
139 Control control;
140 Object data;
141 Object key;
142 String message;
143 int type;
144 String prefix;
145
146 this(Object key, String message, int type, Object data) {
147 this.key = key;
148 this.message = message;
149 this.type = type;
150 this.data = data;
151 }
152
153 /*
154 * (non-Javadoc)
155 *
156 * @see org.eclipse.jface.dialogs.IMessage#getKey()
157 */
158 public Object getKey() {
159 return key;
160 }
161
162 /*
163 * (non-Javadoc)
164 *
165 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage()
166 */
167 public String getMessage() {
168 return message;
169 }
170
171 /*
172 * (non-Javadoc)
173 *
174 * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType()
175 */
176 public int getMessageType() {
177 return type;
178 }
179
180 /*
181 * (non-Javadoc)
182 *
183 * @see org.eclipse.ui.forms.messages.IMessage#getControl()
184 */
185 public Control getControl() {
186 return control;
187 }
188
189 /*
190 * (non-Javadoc)
191 *
192 * @see org.eclipse.ui.forms.messages.IMessage#getData()
193 */
194 public Object getData() {
195 return data;
196 }
197
198 /*
199 * (non-Javadoc)
200 *
201 * @see org.eclipse.ui.forms.messages.IMessage#getPrefix()
202 */
203 public String getPrefix() {
204 return prefix;
205 }
206 }
207
208 static class DefaultPrefixProvider : IMessagePrefixProvider {
209
210 public String getPrefix(Control c) {
211 Composite parent = c.getParent();
212 Control[] siblings = parent.getChildren();
213 for (int i = 0; i < siblings.length; i++) {
214 if (siblings[i] is c) {
215 // this is us - go backward until you hit
216 // a label-like widget
217 for (int j = i - 1; j >= 0; j--) {
218 Control label = siblings[j];
219 String ltext = null;
220 if ( auto l = cast(Label)label ) {
221 ltext = l.getText();
222 } else if ( auto hl = cast(Hyperlink)label ) {
223 ltext = hl.getText();
224 } else if ( auto cl = cast(CLabel)label ) {
225 ltext = cl.getText();
226 }
227 if (ltext !is null) {
228 if (!ltext.endsWith(":")) //$NON-NLS-1$
229 return ltext ~ ": "; //$NON-NLS-1$
230 return ltext ~ " "; //$NON-NLS-1$
231 }
232 }
233 break;
234 }
235 }
236 return null;
237 }
238 }
239
240 class ControlDecorator {
241 private ControlDecoration decoration;
242 private ArrayList controlMessages;
243 private String prefix;
244
245 this(Control control) {
246 controlMessages = new ArrayList();
247 this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody());
248 }
249
250 public bool isDisposed() {
251 return decoration.getControl() is null;
252 }
253
254 void updatePrefix() {
255 prefix = null;
256 }
257
258 void updatePosition() {
259 Control control = decoration.getControl();
260 decoration.dispose();
261 this.decoration = new ControlDecoration(control, decorationPosition, scrolledForm.getBody());
262 update();
263 }
264
265 String getPrefix() {
266 if (prefix is null)
267 createPrefix();
268 return prefix;
269 }
270
271 private void createPrefix() {
272 if (prefixProvider is null) {
273 prefix = ""; //$NON-NLS-1$
274 return;
275 }
276 prefix = prefixProvider.getPrefix(decoration.getControl());
277 if (prefix is null)
278 // make a prefix anyway
279 prefix = ""; //$NON-NLS-1$
280 }
281
282 void addAll(ArrayList target) {
283 target.addAll(controlMessages);
284 }
285
286 void addMessage(Object key, String text, Object data, int type) {
287 Message message = this.outer.addMessage(getPrefix(), key,
288 text, data, type, controlMessages);
289 message.control = decoration.getControl();
290 if (isAutoUpdate())
291 update();
292 }
293
294 bool removeMessage(Object key) {
295 Message message = findMessage(key, controlMessages);
296 if (message !is null) {
297 controlMessages.remove(message);
298 if (isAutoUpdate())
299 update();
300 }
301 return message !is null;
302 }
303
304 bool removeMessages() {
305 if (controlMessages.isEmpty())
306 return false;
307 controlMessages.clear();
308 if (isAutoUpdate())
309 update();
310 return true;
311 }
312
313 public void update() {
314 if (controlMessages.isEmpty()) {
315 decoration.setDescriptionText(null);
316 decoration.hide();
317 } else {
318 ArrayList peers = createPeers(controlMessages);
319 int type = (cast(IMessage) peers.get(0)).getMessageType();
320 String description = createDetails(createPeers(peers), true);
321 if (type is IMessageProvider.ERROR)
322 decoration.setImage(standardError.getImage());
323 else if (type is IMessageProvider.WARNING)
324 decoration.setImage(standardWarning.getImage());
325 else if (type is IMessageProvider.INFORMATION)
326 decoration.setImage(standardInformation.getImage());
327 decoration.setDescriptionText(description);
328 decoration.show();
329 }
330 }
331 }
332
333 /**
334 * Creates a new instance of the message manager that will work with the
335 * provided form.
336 *
337 * @param scrolledForm
338 * the form to control
339 */
340 public this(ScrolledForm scrolledForm) {
341 prefixProvider = DEFAULT_PREFIX_PROVIDER;
342 messages = new ArrayList();
343 decorators = new Hashtable();
344 this.scrolledForm = scrolledForm;
345 }
346
347 /*
348 * (non-Javadoc)
349 *
350 * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
351 * java.lang.String, int)
352 */
353 public void addMessage(Object key, String messageText, Object data, int type) {
354 addMessage(null, key, messageText, data, type, messages);
355 if (isAutoUpdate())
356 updateForm();
357 }
358
359 /*
360 * (non-Javadoc)
361 *
362 * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
363 * java.lang.String, int, org.eclipse.swt.widgets.Control)
364 */
365 public void addMessage(Object key, String messageText, Object data,
366 int type, Control control) {
367 ControlDecorator dec = cast(ControlDecorator) decorators.get(control);
368
369 if (dec is null) {
370 dec = new ControlDecorator(control);
371 decorators.put(control, dec);
372 }
373 dec.addMessage(key, messageText, data, type);
374 if (isAutoUpdate())
375 updateForm();
376 }
377
378 /*
379 * (non-Javadoc)
380 *
381 * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object)
382 */
383 public void removeMessage(Object key) {
384 Message message = findMessage(key, messages);
385 if (message !is null) {
386 messages.remove(message);
387 if (isAutoUpdate())
388 updateForm();
389 }
390 }
391
392 /*
393 * (non-Javadoc)
394 *
395 * @see org.eclipse.ui.forms.IMessageManager#removeMessages()
396 */
397 public void removeMessages() {
398 if (!messages.isEmpty()) {
399 messages.clear();
400 if (isAutoUpdate())
401 updateForm();
402 }
403 }
404
405 /*
406 * (non-Javadoc)
407 *
408 * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object,
409 * org.eclipse.swt.widgets.Control)
410 */
411 public void removeMessage(Object key, Control control) {
412 ControlDecorator dec = cast(ControlDecorator) decorators.get(control);
413 if (dec is null)
414 return;
415 if (dec.removeMessage(key))
416 if (isAutoUpdate())
417 updateForm();
418 }
419
420 /*
421 * (non-Javadoc)
422 *
423 * @see org.eclipse.ui.forms.IMessageManager#removeMessages(org.eclipse.swt.widgets.Control)
424 */
425 public void removeMessages(Control control) {
426 ControlDecorator dec = cast(ControlDecorator) decorators.get(control);
427 if (dec !is null) {
428 if (dec.removeMessages()) {
429 if (isAutoUpdate())
430 updateForm();
431 }
432 }
433 }
434
435 /*
436 * (non-Javadoc)
437 *
438 * @see org.eclipse.ui.forms.IMessageManager#removeAllMessages()
439 */
440 public void removeAllMessages() {
441 bool needsUpdate = false;
442 for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) {
443 ControlDecorator control = cast(ControlDecorator) enm.nextElement();
444 if (control.removeMessages())
445 needsUpdate = true;
446 }
447 if (!messages.isEmpty()) {
448 messages.clear();
449 needsUpdate = true;
450 }
451 if (needsUpdate && isAutoUpdate())
452 updateForm();
453 }
454
455 /*
456 * Adds the message if it does not already exist in the provided list.
457 */
458
459 private Message addMessage(String prefix, Object key, String messageText,
460 Object data, int type, ArrayList list) {
461 Message message = findMessage(key, list);
462 if (message is null) {
463 message = new Message(key, messageText, type, data);
464 message.prefix = prefix;
465 list.add(message);
466 } else {
467 message.message = messageText;
468 message.type = type;
469 message.data = data;
470 }
471 return message;
472 }
473
474 /*
475 * Finds the message with the provided key in the provided list.
476 */
477
478 private Message findMessage(Object key, ArrayList list) {
479 for (int i = 0; i < list.size(); i++) {
480 Message message = cast(Message) list.get(i);
481 if (message.getKey().opEquals(key))
482 return message;
483 }
484 return null;
485 }
486
487 /*
488 * (non-Javadoc)
489 *
490 * @see org.eclipse.ui.forms.IMessageManager#update()
491 */
492 public void update() {
493 // Update decorations
494 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
495 ControlDecorator dec = cast(ControlDecorator) iter.next();
496 dec.update();
497 }
498 // Update the form
499 updateForm();
500 }
501
502 /*
503 * Updates the container by rolling the messages up from the controls.
504 */
505
506 private void updateForm() {
507 ArrayList mergedList = new ArrayList();
508 mergedList.addAll(messages);
509 for (Enumeration enm = decorators.elements(); enm.hasMoreElements();) {
510 ControlDecorator dec = cast(ControlDecorator) enm.nextElement();
511 dec.addAll(mergedList);
512 }
513 update(mergedList);
514 }
515
516 private void update(ArrayList mergedList) {
517 pruneControlDecorators();
518 if (scrolledForm.getForm().getHead().getBounds().height is 0 || mergedList.isEmpty() || mergedList is null) {
519 scrolledForm.setMessage(null, IMessageProvider.NONE);
520 return;
521 }
522 ArrayList peers = createPeers(mergedList);
523 int maxType = (cast(IMessage) peers.get(0)).getMessageType();
524 String messageText;
525 IMessage[] array = arraycast!(IMessage)( peers
526 .toArray());
527 if (peers.size() is 1 && (cast(Message) peers.get(0)).prefix is null) {
528 // a single message
529 IMessage message = cast(IMessage) peers.get(0);
530 messageText = message.getMessage();
531 scrolledForm.setMessage(messageText, maxType, array);
532 } else {
533 // show a summary message for the message
534 // and list of errors for the details
535 if (peers.size() > 1)
536 messageText = Messages.bind(
537 MULTIPLE_MESSAGE_SUMMARY_KEYS[maxType],
538 [ to!(String)(peers.size()) ]); //$NON-NLS-1$
539 else
540 messageText = SINGLE_MESSAGE_SUMMARY_KEYS[maxType];
541 scrolledForm.setMessage(messageText, maxType, array);
542 }
543 }
544
545 private static String getFullMessage(IMessage message) {
546 if (message.getPrefix() is null)
547 return message.getMessage();
548 return message.getPrefix() ~ message.getMessage();
549 }
550
551 private ArrayList createPeers(ArrayList messages) {
552 ArrayList peers = new ArrayList();
553 int maxType = 0;
554 for (int i = 0; i < messages.size(); i++) {
555 Message message = cast(Message) messages.get(i);
556 if (message.type > maxType) {
557 peers.clear();
558 maxType = message.type;
559 }
560 if (message.type is maxType)
561 peers.add(message);
562 }
563 return peers;
564 }
565
566 private String createDetails(ArrayList messages, bool excludePrefix) {
567 auto txt = new tango.text.Text.Text!(char);
568
569 for (int i = 0; i < messages.size(); i++) {
570 if (i > 0)
571 txt.append( FileConst.NewlineString );
572 IMessage m = cast(IMessage) messages.get(i);
573 txt.append(excludePrefix ? m.getMessage() : getFullMessage(m));
574 }
575 return txt.toString();
576 }
577
578 public static String createDetails(IMessage[] messages) {
579 if (messages is null || messages.length is 0)
580 return null;
581 auto txt = new tango.text.Text.Text!(char);
582
583 for (int i = 0; i < messages.length; i++) {
584 if (i > 0)
585 txt.append( FileConst.NewlineString );
586 txt.append(getFullMessage(messages[i]));
587 }
588 return txt.toString();
589 }
590
591 /*
592 * (non-Javadoc)
593 *
594 * @see org.eclipse.ui.forms.IMessageManager#createSummary(org.eclipse.ui.forms.IMessage[])
595 */
596 public String createSummary(IMessage[] messages) {
597 return createDetails(messages);
598 }
599
600 private void pruneControlDecorators() {
601 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
602 ControlDecorator dec = cast(ControlDecorator) iter.next();
603 if (dec.isDisposed())
604 iter.remove();
605 }
606 }
607
608 /*
609 * (non-Javadoc)
610 *
611 * @see org.eclipse.ui.forms.IMessageManager#getMessagePrefixProvider()
612 */
613 public IMessagePrefixProvider getMessagePrefixProvider() {
614 return prefixProvider;
615 }
616
617 /*
618 * (non-Javadoc)
619 *
620 * @see org.eclipse.ui.forms.IMessageManager#setMessagePrefixProvider(org.eclipse.ui.forms.IMessagePrefixProvider)
621 */
622 public void setMessagePrefixProvider(IMessagePrefixProvider provider) {
623 this.prefixProvider = provider;
624 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
625 ControlDecorator dec = cast(ControlDecorator) iter.next();
626 dec.updatePrefix();
627 }
628 }
629
630 /*
631 * (non-Javadoc)
632 *
633 * @see org.eclipse.ui.forms.IMessageManager#getDecorationPosition()
634 */
635 public int getDecorationPosition() {
636 return decorationPosition;
637 }
638
639 /*
640 * (non-Javadoc)
641 *
642 * @see org.eclipse.ui.forms.IMessageManager#setDecorationPosition(int)
643 */
644 public void setDecorationPosition(int position) {
645 this.decorationPosition = position;
646 for (Iterator iter = decorators.values().iterator(); iter.hasNext();) {
647 ControlDecorator dec = cast(ControlDecorator) iter.next();
648 dec.updatePosition();
649 }
650 }
651
652 /*
653 * (non-Javadoc)
654 *
655 * @see org.eclipse.ui.forms.IMessageManager#isAutoUpdate()
656 */
657 public bool isAutoUpdate() {
658 return autoUpdate;
659 }
660
661 /*
662 * (non-Javadoc)
663 *
664 * @see org.eclipse.ui.forms.IMessageManager#setAutoUpdate(bool)
665 */
666 public void setAutoUpdate(bool autoUpdate) {
667 bool needsUpdate = !this.autoUpdate && autoUpdate;
668 this.autoUpdate = autoUpdate;
669 if (needsUpdate)
670 update();
671 }
672 }