The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

153 lines
5.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. static bool exeIsAvailable (const char* const executable)
  19. {
  20. ChildProcess child;
  21. const bool ok = child.start ("which " + String (executable))
  22. && child.readAllProcessOutput().trim().isNotEmpty();
  23. child.waitForProcessToFinish (60 * 1000);
  24. return ok;
  25. }
  26. bool FileChooser::isPlatformDialogAvailable()
  27. {
  28. static bool canUseNativeBox = exeIsAvailable ("zenity") || exeIsAvailable ("kdialog");
  29. return canUseNativeBox;
  30. }
  31. void FileChooser::showPlatformDialog (Array<File>& results,
  32. const String& title,
  33. const File& file,
  34. const String& /* filters */,
  35. bool isDirectory,
  36. bool /* selectsFiles */,
  37. bool isSave,
  38. bool /* warnAboutOverwritingExistingFiles */,
  39. bool selectMultipleFiles,
  40. FilePreviewComponent* /* previewComponent */)
  41. {
  42. String separator;
  43. StringArray args;
  44. const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
  45. const bool isKdeFullSession = SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String::empty)
  46. .equalsIgnoreCase ("true");
  47. if (exeIsAvailable ("kdialog") && (isKdeFullSession || ! exeIsAvailable ("zenity")))
  48. {
  49. // use kdialog for KDE sessions or if zenity is missing
  50. args.add ("kdialog");
  51. if (title.isNotEmpty())
  52. args.add ("--title=" + title);
  53. if (selectMultipleFiles)
  54. {
  55. separator = "\n";
  56. args.add ("--multiple");
  57. args.add ("--separate-output");
  58. args.add ("--getopenfilename");
  59. }
  60. else
  61. {
  62. if (isSave) args.add ("--getsavefilename");
  63. else if (isDirectory) args.add ("--getexistingdirectory");
  64. else args.add ("--getopenfilename");
  65. }
  66. String startPath;
  67. if (file.exists() || file.getParentDirectory().exists())
  68. {
  69. startPath = file.getFullPathName();
  70. }
  71. else
  72. {
  73. startPath = File::getSpecialLocation (File::userHomeDirectory).getFullPathName();
  74. if (isSave)
  75. startPath += "/" + file.getFileName();
  76. }
  77. args.add (startPath);
  78. }
  79. else
  80. {
  81. // zenity
  82. args.add ("zenity");
  83. args.add ("--file-selection");
  84. if (title.isNotEmpty())
  85. args.add ("--title=" + title);
  86. if (selectMultipleFiles)
  87. {
  88. separator = ":";
  89. args.add ("--multiple");
  90. args.add ("--separator=" + separator);
  91. }
  92. else
  93. {
  94. if (isDirectory) args.add ("--directory");
  95. if (isSave) args.add ("--save");
  96. }
  97. if (file.isDirectory())
  98. file.setAsCurrentWorkingDirectory();
  99. else if (file.getParentDirectory().exists())
  100. file.getParentDirectory().setAsCurrentWorkingDirectory();
  101. else
  102. File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory();
  103. if (! file.getFileName().isEmpty())
  104. args.add ("--filename=" + file.getFileName());
  105. }
  106. ChildProcess child;
  107. if (child.start (args))
  108. {
  109. const String result (child.readAllProcessOutput().trim());
  110. if (result.isNotEmpty())
  111. {
  112. StringArray tokens;
  113. if (selectMultipleFiles)
  114. tokens.addTokens (result, separator, "\"");
  115. else
  116. tokens.add (result);
  117. for (int i = 0; i < tokens.size(); i++)
  118. results.add (File (tokens[i]));
  119. }
  120. child.waitForProcessToFinish (60 * 1000);
  121. }
  122. previousWorkingDirectory.setAsCurrentWorkingDirectory();
  123. }