View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui;
21  
22  import java.awt.Component;
23  import java.awt.GridBagLayout;
24  import java.io.File;
25  import java.io.IOException;
26  
27  import javax.swing.JCheckBox;
28  import javax.swing.JLabel;
29  import javax.swing.JList;
30  import javax.swing.JOptionPane;
31  import javax.swing.JScrollPane;
32  import javax.swing.JTextField;
33  import javax.swing.border.EmptyBorder;
34  
35  import org.xnap.XNap;
36  import org.xnap.gui.component.DefaultDialog;
37  import org.xnap.gui.list.FileListCellRenderer;
38  import org.xnap.gui.util.GUIHelper;
39  import org.xnap.gui.util.GridBagHelper;
40  import org.xnap.io.Library;
41  import org.xnap.util.FileHelper;
42  import org.xnap.util.Preferences;
43  import org.xnap.util.PreferencesProvider;
44  import org.xnap.util.StringHelper;
45  
46  
47  /***
48   * Provides a set of static methods to display common dialogs.
49   */
50  public class Dialogs
51  {
52      //--- Constant(s) ---
53  
54      //--- Data Field(s) ---
55  
56      private static Preferences prefs = Preferences.getInstance();
57  
58      //--- Constructor(s) ---
59  
60      public static boolean copy(File[] files, File target)
61      {
62  		boolean success = true;
63  
64  		files = Dialogs.showCopyDialog(null, files, target);
65  		if (files != null) {
66  			for (int i = 0; i < files.length; i++) {
67  				try {
68  					FileHelper.copy(files[i], new File
69  						(target, files[i].getName()));
70  				}
71  				catch (IOException e) {
72  					success = false;
73  					JOptionPane.showMessageDialog
74  						(null, 
75  						 "Could not copy file: " + e.getLocalizedMessage(),
76  						 XNap.tr("Error"), JOptionPane.ERROR_MESSAGE);
77  				}
78  			}
79  		}
80  		else {
81  			success = false;
82  		}
83  	
84  		return success;
85      }
86  
87      public static void error(Component parent, String message)
88      {
89  		JOptionPane.showMessageDialog
90  			(parent, message, XNap.tr("Error"), JOptionPane.ERROR_MESSAGE);
91      }
92  
93      public static boolean getShowDialog(PreferencesProvider prefs, 
94  										String dialogName) 
95  	{
96  		return prefs.getBoolean("show" + dialogName + "Dialog");
97  	}
98      
99      public static boolean getShowDialog(String dialogName) 
100 	{
101 		return getShowDialog(prefs, dialogName);
102 	}
103 
104     public static void setShowDialog(PreferencesProvider prefs, 
105 									 String dialogName, boolean newValue) 
106 	{
107 		prefs.set("show" + dialogName + "Dialog", newValue);
108     }
109 
110     public static void setShowDialog(String dialogName, boolean newValue) 
111 	{
112 		setShowDialog(prefs, dialogName, newValue);
113     }
114 
115     public static void info(Component c, String message, String title)
116     {
117 		JOptionPane.showMessageDialog
118 			(c, message, title, JOptionPane.INFORMATION_MESSAGE);
119     }
120 
121     public static boolean move(File[] files, File target)
122     {
123 		boolean success = true;
124 
125 		files = Dialogs.showMoveDialog(null, files, target);
126 		if (files != null) {
127 			for (int i = 0; i < files.length; i++) {
128 				try {
129 					FileHelper.moveUnique(files[i], target.getAbsolutePath());
130 				}
131 				catch (IOException e) {
132 					success = false;
133 					JOptionPane.showMessageDialog
134 						(null, 
135 						 "Could not move file: " + e.getLocalizedMessage(),
136 						 XNap.tr("Error"), JOptionPane.ERROR_MESSAGE);
137 				}
138 			}
139 		}
140 		else {
141 			success = false;
142 		}
143 	
144 		return success;
145     }
146 
147 	 /***
148 	  * Returns true, if user presses okay button.
149 	  */
150 	 public static boolean showCloseDialog(Component c) 
151 	 {
152 		 JCheckBox jcb 
153 			 = new JCheckBox(XNap.tr("Always quit without prompting me."));
154 
155 		 Object[] message = new Object[] {
156 			 XNap.tr("This will abort any downloads and uploads."),
157 			 XNap.tr("Do you really want to quit XNap?"), 
158 			 jcb
159 		 };
160 
161 		 int response = JOptionPane.showConfirmDialog
162 			 (c, message, XNap.tr("Quit XNap"), JOptionPane.OK_CANCEL_OPTION );
163 
164 		 setShowDialog("Close", !jcb.isSelected());
165 		 prefs.write();
166 
167 		 return (response == JOptionPane.OK_OPTION);
168 	 }	
169 
170 	 /***
171 	  * Shows a confirmation dialog and saves if it should be shown again next
172 	  * time.
173 	  *
174 	  * @param c parent component used for centering the dialog
175 	  * @param dialogName the preferences key that is used to save the
176 	  *                   do not show again option
177 	  * @param title the title of the message border
178 	  * @param question the message to show
179 	  * @param optionType 
180 	  * @param prefs PreferencesProvider used for saving "do not show again
181 	  *
182 	  * @param returns JOptionPane.YES_OPTION if user checked the "Do
183 	  * not ask me again" check box before
184 	  */
185 	 public static int showConfirmDialog(Component c, String dialogName, 
186 										 String title, String question,
187 										 int optionType,
188 										 PreferencesProvider prefs)
189 	 {
190 		 if (!getShowDialog(prefs, dialogName)) {
191 			 return JOptionPane.YES_OPTION;
192 		 }
193 
194 		 JCheckBox jcb = new JCheckBox(XNap.tr("Do not ask me again."));
195 
196 		 JLabel jl = new JLabel(GUIHelper.tt(question, 400));
197 		 jl.setBorder(GUIHelper.createDefaultBorder(title));
198 
199 // 		 MultiLineLabel ml = new MultiLineLabel(question);
200 // 		 ml.setBorder(GUIHelper.createDefaultBorder(title));
201 // 		 ml.setColumns(40);
202 
203 		 Object[] message = new Object[] {
204 			 jl, jcb
205 		 };
206 
207 		 int response = JOptionPane.showConfirmDialog
208 			 (c, message, title, optionType);
209 
210 		 setShowDialog(prefs, dialogName, !jcb.isSelected());
211 
212 		 return response;
213     }
214 
215     public static File[] showCopyDialog(Component c, File files[], File dir)
216     {
217 		return showFilesActionDialog
218 			(c, files, 
219 			 XNap.tr("Do you really want to copy these files to \"{0}\"?", dir),
220 			 XNap.tr("Copy Files"), "Copy");
221     }
222 
223     public static File[] showDeleteFilesDialog(Component c, File files[])
224     {
225 		return showFilesActionDialog
226 			(c, files, XNap.tr("Do you really want to delete these files?"),
227 			 XNap.tr("Delete Files"), "DeleteFiles");
228     }
229 
230 	//      public static Transfer[] showDeleteDownloadsDialog(Component c, 
231 	//  						       Transfer[] transfers)
232 	//      {
233 	//  	if (!prefs.getShowDeleteDownloadsDialog()) {
234 	//  	    return  transfers;
235 	//  	}
236 
237 	//  	JList jList = new JList(transfers);
238 	//  	jList.setCellRenderer(new TransferListCellRenderer());
239 	//  	jList.setVisibleRowCount(4);
240 	//  	JScrollPane jsp = new JScrollPane();
241 	//  	jsp.setViewportView(jList);
242 
243 //  	// select all transfers
244 //  	jList.setSelectionInterval(0, transfers.length - 1);
245 
246 //  	JCheckBox jcb = new JCheckBox(XNap.tr("Do not ask me again."));
247 
248 //  	Object[] message = new Object[] {
249 //  	    jsp, jcb, XNap.tr("Do you really want to delete these files?")
250 //  	};
251 	
252 //  	int response = JOptionPane.showConfirmDialog
253 //  	    (c, message, 
254 //  	     MessageFormat.format(XNap.tr("{0} Files"), 
255 //  				  new Object[] { XNap.tr("Delete") }),
256 //  	     JOptionPane.YES_NO_OPTION);
257 	
258 //  	prefs.setShowDeleteDownloadsDialog(!jcb.isSelected());
259 	
260 //  	if (response == JOptionPane.YES_OPTION) {
261 //  	    Object[] rows = jList.getSelectedValues();
262 //  	    ITransferContainer[] selected = 
263 //  		new ITransferContainer[rows.length];
264 //  	    System.arraycopy(rows, 0, selected, 0, selected.length);
265 //  	    return selected;
266 //  	}
267 //  	else {
268 //  	    return null;
269 //  	}
270 //      }
271 
272     protected static File[] showFilesActionDialog
273 		(Component c, File files[], String question, String title, 
274 		 String dialogPref)
275     {
276 		if (!getShowDialog(dialogPref)) {
277 			return files;
278 		}
279 
280 		JList jList = new JList(files);
281 		jList.setCellRenderer(new FileListCellRenderer());
282 		jList.setVisibleRowCount(4);
283 		JScrollPane jsp = new JScrollPane();
284 		jsp.setViewportView(jList);
285 
286 		// select all files
287 		jList.setSelectionInterval(0, files.length - 1);
288 
289 		JCheckBox jcb = new JCheckBox(XNap.tr("Do not ask me again."));
290 
291 		Object[] message = new Object[] {
292 			jsp, jcb, question
293 		};
294 	
295 		int response = JOptionPane.showConfirmDialog
296             (c, message, title, JOptionPane.YES_NO_OPTION);
297 	
298 		setShowDialog(dialogPref, !jcb.isSelected());
299 	
300 		if (response == JOptionPane.YES_OPTION) {
301 			Object rows[] = jList.getSelectedValues();
302 			File selected[] = new File[rows.length];
303 			System.arraycopy(rows, 0, selected, 0, selected.length);
304 			return selected;
305 		}
306 		else {
307 			return null;
308 		}
309     }
310 
311     public static File[] showMoveDialog(Component c, File files[], File dir)
312     {
313 		return showFilesActionDialog
314 			(c, files, 
315 			 XNap.tr("Do you really want to move these files to \"{0}\"?", dir),
316 			 XNap.tr("Move Files"), "Move");
317     }
318 
319     public static void showNotification(Component c, String dialogName, 
320 										String title, String message) 
321     {
322 		if (getShowDialog(dialogName)) {
323 			NotificationDialog d 
324 				= new NotificationDialog(dialogName, title, message);
325 			d.show(c);
326 		}
327     }
328 
329 	public static void showNotification(Component c, String dialogName,
330 										String title, String message,
331 										PreferencesProvider prefs)
332 	{
333 		if (getShowDialog(prefs, dialogName)) {
334 			NotificationDialog d 
335 				= new NotificationDialog(dialogName, title, message, prefs);
336 			d.show(c);
337 		}
338 	}
339 
340     public static String showRenameDialog(Component c, String filename) 
341     {
342 
343 		JTextField jtf = new JTextField(filename);
344 
345         Object[] message = new Object[] {
346 			XNap.tr("Filename"),
347 			jtf
348         };
349 
350         int response = JOptionPane.showConfirmDialog
351             (c, message, XNap.tr("Rename File"), JOptionPane.OK_CANCEL_OPTION);
352 
353 		return (response == JOptionPane.OK_OPTION) ? jtf.getText() : null;
354     }	
355 
356     public static void showRestartNotification(Component c)
357     {
358 		JOptionPane.showMessageDialog
359 			(c, XNap.tr("You need to restart XNap to activate your changes."),
360 			 XNap.tr("Preferences"), JOptionPane.INFORMATION_MESSAGE);
361     }
362 
363 	/***
364 	 * Shows a message dialog if the library contains similiar files to file.
365 	 *
366 	 * @return true, if user want to continue with the download anyway
367 	 * or no files were found; false, if the user responded with no */
368 	public static boolean showSearchLibraryDialog
369 		(Component c, String filename)
370 	{
371 		String searchText = StringHelper.stripExtra(filename);
372 		File[] files = Library.getInstance().search(searchText);
373 		if (files != null && files.length > 0) {
374 			return showFilesActionDialog
375 				(c, files, 
376 				 XNap.tr("There seem to be similiar files in your library. Do you really want to download?"),
377 				 XNap.tr("Download of {0}", filename),
378 				 "SearchLibraryOnDownload") != null;
379 		}
380 		return true;
381 	}
382 
383     // --- Inner Class(es) ---
384 
385     /***
386      * This class provides a notification dialog with a do not show again
387      * option. There is no need to provide line breakes in the messsage.
388      * It is displayed in a multi line label. 
389      */
390     public static class NotificationDialog extends DefaultDialog
391     {
392 
393 		//--- Data field(s) ---
394 
395 		private PreferencesProvider prefs;
396 		private JCheckBox jcbDoNotShowAgain;
397 		private String dialogName;
398 
399 		//--- Constructor(s) ---
400 
401 		/***
402 		 * Constructs a notification dialog with an "Okay" button and 
403 		 * "Notification" as the dialog title.
404 		 *
405 		 * @param dialogName the preferences key that is used to save the
406 		 *                   do not show again option
407 		 * @param title the title of the message border
408 		 * @param msg the message to show
409 		 * @param prefs PreferencesProvider used for saving "do not show again
410 		 * option"
411 		 */
412 		public NotificationDialog(String dialogName, String title,
413 								  String msg, PreferencesProvider prefs)
414 		{
415 			super(BUTTON_OKAY);
416 
417 			this.dialogName = dialogName;
418 			this.prefs = prefs;
419 
420 			// text panel
421 
422 			JLabel jl = new JLabel(GUIHelper.tt(msg, 400));
423 			jl.setBorder(GUIHelper.createDefaultBorder(title));
424 
425 // 			MultiLineLabel mllText = new MultiLineLabel(msg);
426 // 			mllText.setBorder(GUIHelper.createDefaultBorder(title));
427 // 			mllText.setColumns(40);
428 
429 			// checkbox
430 			jcbDoNotShowAgain 
431 				= new JCheckBox(XNap.tr("Do not show again"), 
432 								!getShowDialog(prefs, dialogName));
433 
434 			// content
435 			setTitle(XNap.tr("Notification"));
436 	    
437 			getMainPanel().setBorder(new EmptyBorder(5, 5, 5, 5));
438 			getMainPanel().setLayout(new GridBagLayout());
439 			GridBagHelper.add(getMainPanel(), jl);
440 			GridBagHelper.add(getMainPanel(), jcbDoNotShowAgain);
441 			pack();
442 		}
443 	
444 		/***
445 		 * Used from within XNap's main code.
446 		 *
447 		 * Plugins have to provide their own {@link PreferencesProvider}.
448 		 */
449 		public NotificationDialog(String dialogName, String title, String msg)
450 		{
451 			this(dialogName, title, msg, Preferences.getInstance());
452 		}
453 
454 		// --- Methods ---
455 
456 		public boolean apply()
457 		{
458 			setShowDialog(prefs, dialogName, !jcbDoNotShowAgain.isSelected());
459 			return true;
460 		}
461     }
462 
463 //  	public static class ConfirmationDialog extends NotificationDialog
464 //  	{
465 		
466 //  	}
467 }
468