You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

KFileChooser.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Copyright (c) 2006-2010 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.dcc.kde;
  23. import com.dmdirc.addons.dcc.DCCPlugin;
  24. import com.dmdirc.config.IdentityManager;
  25. import java.awt.Component;
  26. import java.awt.HeadlessException;
  27. import java.io.File;
  28. import java.util.ArrayList;
  29. import java.util.List;
  30. import javax.swing.JFileChooser;
  31. import javax.swing.filechooser.FileSystemView;
  32. /**
  33. * JFileChooser that uses KDialog to show the actual chooser.
  34. * This is quite hacky, and not guarenteed to behave identically to JFileChooser,
  35. * altho it tries to be as close as possible.
  36. * Almost a drop in replacement for JFileChooser, replace:
  37. * new JFileChooser();
  38. * with:
  39. * KFileChooser.getFileChooser();
  40. *
  41. * There are obviously some differences:
  42. * - File filters must be set using setKDEFileFilter() not using FileFilter objects.
  43. * - FileSystemView's are ignored
  44. * - showOpenDialog and showSaveDialog shell kdialog, so only options available
  45. * in kdialog work.
  46. * - getFileChooser() will return a JFileChooser object unless the DCC plugin's
  47. * config option "general.useKFileChooser" is set to "true" (defaults to false)
  48. * and kdialog is in either /usr/bin or /bin
  49. * - Selection mode FILES_AND_DIRECTORIES can not be used
  50. */
  51. public class KFileChooser extends JFileChooser {
  52. /**
  53. * A version number for this class.
  54. * It should be changed whenever the class structure is changed (or anything
  55. * else that would prevent serialized objects being unserialized with the new
  56. * class).
  57. */
  58. private static final long serialVersionUID = 200806141;
  59. /** File Filter */
  60. private String fileFilter = null;
  61. /** The plugin that this file chooser is for. */
  62. private final DCCPlugin plugin;
  63. /**
  64. * Should a KFileChooser be used rather than a JFileChooser?
  65. *
  66. * @param plugin The DCC Plugin that is requesting a chooser
  67. * @return return true if getFileChooser() will return a KFileChooser not a
  68. * JFileChooser
  69. */
  70. public static boolean useKFileChooser(final DCCPlugin plugin) {
  71. return KDialogProcess.hasKDialog() && IdentityManager.getGlobalConfig().getOptionBool(plugin.getDomain(), "general.useKFileChooser");
  72. }
  73. /**
  74. * Constructs a FileChooser pointing to the user's default directory.
  75. *
  76. * @param plugin The DCC Plugin that is requesting a chooser
  77. * @return The relevant FileChooser
  78. */
  79. public static JFileChooser getFileChooser(final DCCPlugin plugin) {
  80. return useKFileChooser(plugin) ? new KFileChooser(plugin) : new JFileChooser();
  81. }
  82. /**
  83. * Constructs a FileChooser using the given File as the path.
  84. *
  85. * @param plugin The DCC Plugin that is requesting a chooser
  86. * @param currentDirectory Directory to use as the base directory
  87. * @return The relevant FileChooser
  88. */
  89. public static JFileChooser getFileChooser(final DCCPlugin plugin, final File currentDirectory) {
  90. return useKFileChooser(plugin) ? new KFileChooser(plugin, currentDirectory) : new JFileChooser(currentDirectory);
  91. }
  92. /**
  93. * Constructs a FileChooser using the given current directory and FileSystemView.
  94. *
  95. * @param plugin The DCC Plugin that is requesting a chooser
  96. * @param currentDirectory Directory to use as the base directory
  97. * @param fsv The FileSystemView to use
  98. * @return The relevant FileChooser
  99. */
  100. public static JFileChooser getFileChooser(final DCCPlugin plugin, final File currentDirectory, final FileSystemView fsv) {
  101. return useKFileChooser(plugin) ? new KFileChooser(plugin, currentDirectory, fsv) : new JFileChooser(currentDirectory, fsv);
  102. }
  103. /**
  104. * Constructs a FileChooser using the given FileSystemView.
  105. *
  106. * @param plugin The DCC Plugin that is requesting a chooser
  107. * @param fsv The FileSystemView to use
  108. * @return The relevant FileChooser
  109. */
  110. public static JFileChooser getFileChooser(final DCCPlugin plugin, final FileSystemView fsv) {
  111. return useKFileChooser(plugin) ? new KFileChooser(plugin, fsv) : new JFileChooser(fsv);
  112. }
  113. /**
  114. * Constructs a FileChooser using the given path.
  115. *
  116. * @param plugin The DCC Plugin that is requesting a chooser
  117. * @param currentDirectoryPath Directory to use as the base directory
  118. * @return The relevant FileChooser
  119. */
  120. public static JFileChooser getFileChooser(final DCCPlugin plugin, final String currentDirectoryPath) {
  121. return useKFileChooser(plugin) ? new KFileChooser(plugin, currentDirectoryPath) : new JFileChooser(currentDirectoryPath);
  122. }
  123. /**
  124. * Constructs a FileChooser using the given current directory path and FileSystemView.
  125. *
  126. * @param plugin The DCC Plugin that is requesting a chooser
  127. * @param currentDirectoryPath Directory to use as the base directory
  128. * @param fsv The FileSystemView to use
  129. * @return The relevant FileChooser
  130. */
  131. public static JFileChooser getFileChooser(final DCCPlugin plugin, final String currentDirectoryPath, final FileSystemView fsv) {
  132. return useKFileChooser(plugin) ? new KFileChooser(plugin, currentDirectoryPath, fsv) : new JFileChooser(currentDirectoryPath, fsv);
  133. }
  134. /**
  135. * Constructs a FileChooser pointing to the user's default directory.
  136. *
  137. * @param plugin The plugin that owns this KFileChooser
  138. */
  139. private KFileChooser(final DCCPlugin plugin) {
  140. super();
  141. this.plugin = plugin;
  142. }
  143. /**
  144. * Constructs a FileChooser using the given File as the path.
  145. *
  146. * @param plugin The plugin that owns this KFileChooser
  147. * @param currentDirectory Directory to use as the base directory
  148. */
  149. private KFileChooser(final DCCPlugin plugin, final File currentDirectory) {
  150. super(currentDirectory);
  151. this.plugin = plugin;
  152. }
  153. /**
  154. * Constructs a FileChooser using the given current directory and FileSystemView.
  155. *
  156. * @param plugin The plugin that owns this KFileChooser
  157. * @param currentDirectory Directory to use as the base directory
  158. * @param fsv The FileSystemView to use
  159. */
  160. private KFileChooser(final DCCPlugin plugin, final File currentDirectory, final FileSystemView fsv) {
  161. super(currentDirectory, fsv);
  162. this.plugin = plugin;
  163. }
  164. /**
  165. * Constructs a FileChooser using the given FileSystemView.
  166. *
  167. * @param plugin The plugin that owns this KFileChooser
  168. * @param fsv The FileSystemView to use
  169. */
  170. private KFileChooser(final DCCPlugin plugin, final FileSystemView fsv) {
  171. super(fsv);
  172. this.plugin = plugin;
  173. }
  174. /**
  175. * Constructs a FileChooser using the given path.
  176. *
  177. * @param plugin The plugin that owns this KFileChooser
  178. * @param currentDirectoryPath Directory to use as the base directory
  179. */
  180. private KFileChooser(final DCCPlugin plugin, final String currentDirectoryPath) {
  181. super(currentDirectoryPath);
  182. this.plugin = plugin;
  183. }
  184. /**
  185. * Constructs a FileChooser using the given current directory path and FileSystemView.
  186. *
  187. * @param plugin The plugin that owns this KFileChooser
  188. * @param currentDirectoryPath Directory to use as the base directory
  189. * @param fsv The FileSystemView to use
  190. */
  191. private KFileChooser(final DCCPlugin plugin, final String currentDirectoryPath, final FileSystemView fsv) {
  192. super(currentDirectoryPath, fsv);
  193. this.plugin = plugin;
  194. }
  195. /**
  196. * Set the file filter.
  197. *
  198. * @param fileFilter File filter (eg "*.php *.jpg" or null for no filter)
  199. */
  200. public void setKDEFileFilter(final String fileFilter) {
  201. this.fileFilter = fileFilter;
  202. }
  203. /**
  204. * Get the file filter.
  205. *
  206. * @return File filter (eg "*.php *.jpg" or null for no filter)
  207. */
  208. public String getKDEFileFilter() {
  209. return fileFilter;
  210. }
  211. /** {@inheritDoc} */
  212. @Override
  213. public int showOpenDialog(final Component parent) throws HeadlessException {
  214. if (!useKFileChooser(plugin)) {
  215. return super.showOpenDialog(parent);
  216. }
  217. final ArrayList<String> params = new ArrayList<String>();
  218. if (isMultiSelectionEnabled()) {
  219. params.add("--multiple");
  220. params.add("--separate-output");
  221. }
  222. if (getDialogTitle() != null && !getDialogTitle().isEmpty()) {
  223. params.add("--caption");
  224. params.add(getDialogTitle());
  225. }
  226. if (getFileSelectionMode() == DIRECTORIES_ONLY) {
  227. params.add("--getexistingdirectory");
  228. } else {
  229. params.add("--getopenfilename");
  230. }
  231. if (getSelectedFile() != null && getFileSelectionMode() != DIRECTORIES_ONLY && !getSelectedFile().getPath().isEmpty()) {
  232. if (getSelectedFile().getPath().charAt(0) != '/') {
  233. params.add(getCurrentDirectory().getPath() + File.separator + getSelectedFile().getPath());
  234. } else {
  235. params.add(getSelectedFile().getPath());
  236. }
  237. } else if (getCurrentDirectory() != null) {
  238. params.add(getCurrentDirectory().getPath());
  239. }
  240. if (getFileSelectionMode() != DIRECTORIES_ONLY && fileFilter != null && !fileFilter.isEmpty()) {
  241. params.add(fileFilter);
  242. }
  243. KDialogProcess kdp;
  244. try {
  245. kdp = new KDialogProcess(params.toArray(new String[0]));
  246. kdp.waitFor();
  247. } catch (Exception e) {
  248. return JFileChooser.ERROR_OPTION;
  249. }
  250. if (kdp.getProcess().exitValue() == 0) {
  251. if (isMultiSelectionEnabled()) {
  252. final List<String> list = kdp.getStdOutStream().getList();
  253. final File[] fileList = new File[list.size()];
  254. for (int i = 0; i < list.size(); ++i) {
  255. fileList[i] = new File(list.get(i));
  256. }
  257. setSelectedFiles(fileList);
  258. } else {
  259. setSelectedFile(new File(kdp.getStdOutStream().getList().get(0)));
  260. }
  261. return JFileChooser.APPROVE_OPTION;
  262. } else {
  263. return JFileChooser.ERROR_OPTION;
  264. }
  265. }
  266. /** {@inheritDoc} */
  267. @Override
  268. public int showSaveDialog(final Component parent) throws HeadlessException {
  269. if (!useKFileChooser(plugin)) {
  270. return super.showSaveDialog(parent);
  271. }
  272. final ArrayList<String> params = new ArrayList<String>();
  273. if (getDialogTitle() != null && !getDialogTitle().isEmpty()) {
  274. params.add("--caption");
  275. params.add(getDialogTitle());
  276. }
  277. params.add("--getsavefilename");
  278. if (getSelectedFile() != null && !getSelectedFile().getPath().isEmpty()) {
  279. if (getSelectedFile().getPath().charAt(0) != '/') {
  280. params.add(getCurrentDirectory().getPath() + File.separator + getSelectedFile().getPath());
  281. } else {
  282. params.add(getSelectedFile().getPath());
  283. }
  284. } else if (getCurrentDirectory() != null) {
  285. params.add(getCurrentDirectory().getPath());
  286. }
  287. KDialogProcess kdp;
  288. try {
  289. kdp = new KDialogProcess(params.toArray(new String[0]));
  290. kdp.waitFor();
  291. } catch (Exception e) {
  292. return JFileChooser.ERROR_OPTION;
  293. }
  294. if (kdp.getProcess().exitValue() == 0) {
  295. setSelectedFile(new File(kdp.getStdOutStream().getList().get(0)));
  296. return JFileChooser.APPROVE_OPTION;
  297. } else {
  298. return JFileChooser.ERROR_OPTION;
  299. }
  300. }
  301. }