1 /*******************************************************************************
2  * Copyright (c) 2005, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.team.internal.ui.dialogs;
15 
16 import org.eclipse.jface.dialogs.IDialogConstants;
17 import org.eclipse.jface.dialogs.MessageDialog;
18 import org.eclipse.jface.window.IShellProvider;
19 import org.eclipse.swt.widgets.Shell;
20 
21 /**
22  * This class provides a Yes/No prompter that can be used for multiple questions
23  * during the same operation. It can be used for a single prompt (in which case
24  * OK and Cancel are presented) or multiple (in which case Yes, Yes to All, No
25  * and No to All are presented). It uses the previous selection as appropriate.
26  */
27 public class MultipleYesNoPrompter {
28 	private static final int ALWAYS_ASK = 0;
29 	private static final int YES_TO_ALL = 1;
30 	private static final int NO_TO_ALL = 2;
31 	private String[] buttons;
32 	private int confirmation = ALWAYS_ASK;
33 	private String title;
34 	private boolean hasMultiple;
35 	private boolean allOrNothing;
36 	private IShellProvider shellProvider;
37 
38 	/**
39 	 * Prompt for the given resources using the specific condition. The prompt dialog will
40 	 * have the title specified.
41 	 */
MultipleYesNoPrompter(IShellProvider provider, String title, boolean hasMultiple, boolean allOrNothing)42 	public MultipleYesNoPrompter(IShellProvider provider, String title,
43 			boolean hasMultiple, boolean allOrNothing) {
44 		this.title = title;
45 		this.shellProvider = provider;
46 		this.hasMultiple = hasMultiple;
47 		this.allOrNothing = allOrNothing;
48 		if (hasMultiple) {
49 			if (allOrNothing) {
50 				buttons = new String[] {
51 					IDialogConstants.YES_LABEL,
52 					IDialogConstants.YES_TO_ALL_LABEL,
53 					IDialogConstants.CANCEL_LABEL};
54 			} else {
55 				buttons = new String[] {
56 					IDialogConstants.YES_LABEL,
57 					IDialogConstants.YES_TO_ALL_LABEL,
58 					IDialogConstants.NO_LABEL,
59 					IDialogConstants.NO_TO_ALL_LABEL,
60 					IDialogConstants.CANCEL_LABEL};
61 			}
62 		} else {
63 			buttons = new String[] {
64 					IDialogConstants.YES_LABEL,
65 					IDialogConstants.NO_LABEL,
66 					IDialogConstants.CANCEL_LABEL
67 			};
68 		}
69 	}
70 
71 	/**
72 	 * Return whether the given resource should be included in the
73 	 * target set.
74 	 * @param message the message
75 	 * @return whether the resource should be included
76 	 * @throws InterruptedException if the user choose to cancel
77 	 */
shouldInclude(String message)78 	public boolean shouldInclude(String message) throws InterruptedException {
79 		if (confirmation == YES_TO_ALL) {
80 			return true;
81 		} else {
82 			switch (confirmation) {
83 			case ALWAYS_ASK:
84 				// This call has the nasty side effect of changing the
85 				// instance scoped "confirmation"
86 				if (confirmOverwrite(message)) {
87 					return true;
88 				}
89 				return false;
90 
91 			case YES_TO_ALL:
92 				return true;
93 
94 			case NO_TO_ALL:
95 				// Don't overwrite
96 				return false;
97 
98 			default:
99 				// If we get here, the user said no or not_to_all.
100 				return false;
101 			}
102 		}
103 	}
104 
105 	/**
106 	 * Opens the confirmation dialog based on the prompt condition settings.
107 	 */
confirmOverwrite(String msg)108 	private boolean confirmOverwrite(String msg) throws InterruptedException {
109 		Shell shell = shellProvider.getShell();
110 		if (shell == null) return false;
111 		final MessageDialog dialog =
112 			new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, buttons, 0);
113 
114 		// run in syncExec because callback is from an operation,
115 		// which is probably not running in the UI thread.
116 		shell.getDisplay().syncExec(
117 			() -> dialog.open());
118 		if (hasMultiple) {
119 			switch (dialog.getReturnCode()) {
120 				case 0:// Yes
121 					return true;
122 				case 1:// Yes to all
123 					confirmation = YES_TO_ALL;
124 					return true;
125 				case 2:// No (or CANCEL for all-or-nothing)
126 					if (allOrNothing) {
127 						throw new InterruptedException();
128 					}
129 					return false;
130 				case 3:// No to all
131 					confirmation = NO_TO_ALL;
132 					return false;
133 				case 4:// Cancel
134 				default:
135 					throw new InterruptedException();
136 			}
137 		} else {
138 			switch (dialog.getReturnCode()) {
139 			case 0:// Yes
140 				return true;
141 			case 1:// No
142 				return false;
143 			case 2:// Cancel
144 			default:
145 				throw new InterruptedException();
146 			}
147 		}
148 	}
149 
setTitle(String title)150 	public void setTitle(String title) {
151 		this.title = title;
152 	}
153 
154 }
155