1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 namespace juce 27 { 28 29 //============================================================================== 30 /** 31 Listens for events happening to a FilenameComponent. 32 33 Use FilenameComponent::addListener() and FilenameComponent::removeListener() to 34 register one of these objects for event callbacks when the filename is changed. 35 36 @see FilenameComponent 37 38 @tags{GUI} 39 */ 40 class JUCE_API FilenameComponentListener 41 { 42 public: 43 /** Destructor. */ 44 virtual ~FilenameComponentListener() = default; 45 46 /** This method is called after the FilenameComponent's file has been changed. */ 47 virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0; 48 }; 49 50 51 //============================================================================== 52 /** 53 Shows a filename as an editable text box, with a 'browse' button and a 54 drop-down list for recently selected files. 55 56 A handy component for dialogue boxes where you want the user to be able to 57 select a file or directory. 58 59 Attach an FilenameComponentListener using the addListener() method, and it will 60 get called each time the user changes the filename, either by browsing for a file 61 and clicking 'ok', or by typing a new filename into the box and pressing return. 62 63 @see FileChooser, ComboBox 64 65 @tags{GUI} 66 */ 67 class JUCE_API FilenameComponent : public Component, 68 public SettableTooltipClient, 69 public FileDragAndDropTarget, 70 private AsyncUpdater 71 { 72 public: 73 //============================================================================== 74 /** Creates a FilenameComponent. 75 76 @param name the name for this component. 77 @param currentFile the file to initially show in the box 78 @param canEditFilename if true, the user can manually edit the filename; if false, 79 they can only change it by browsing for a new file 80 @param isDirectory if true, the file will be treated as a directory, and 81 an appropriate directory browser used 82 @param isForSaving if true, the file browser will allow non-existent files to 83 be picked, as the file is assumed to be used for saving rather 84 than loading 85 @param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo". 86 If an empty string is passed in, then the pattern is assumed to be "*" 87 @param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added 88 to any filenames that are entered or chosen 89 @param textWhenNothingSelected the message to display in the box before any filename is entered. (This 90 will only appear if the initial file isn't valid) 91 */ 92 FilenameComponent (const String& name, 93 const File& currentFile, 94 bool canEditFilename, 95 bool isDirectory, 96 bool isForSaving, 97 const String& fileBrowserWildcard, 98 const String& enforcedSuffix, 99 const String& textWhenNothingSelected); 100 101 /** Destructor. */ 102 ~FilenameComponent() override; 103 104 //============================================================================== 105 /** Returns the currently displayed filename. */ 106 File getCurrentFile() const; 107 108 /** Returns the raw text that the user has entered. */ 109 String getCurrentFileText() const; 110 111 /** Changes the current filename. 112 113 @param newFile the new filename to use 114 @param addToRecentlyUsedList if true, the filename will also be added to the 115 drop-down list of recent files. 116 @param notification whether to send a notification of the change to listeners. 117 A notification will only be sent if the filename has changed. 118 */ 119 void setCurrentFile (File newFile, 120 bool addToRecentlyUsedList, 121 NotificationType notification = sendNotificationAsync); 122 123 /** Changes whether the use can type into the filename box. 124 */ 125 void setFilenameIsEditable (bool shouldBeEditable); 126 127 /** Sets a file or directory to be the default starting point for the browser to show. 128 129 This is only used if the current file hasn't been set. 130 */ 131 void setDefaultBrowseTarget (const File& newDefaultDirectory); 132 133 /** This can be overridden to return a custom location that you want the dialog box 134 to show when the browse button is pushed. 135 The default implementation of this method will return either the current file 136 (if one has been chosen) or the location that was set by setDefaultBrowseTarget(). 137 */ 138 virtual File getLocationToBrowse(); 139 140 /** Returns all the entries on the recent files list. 141 142 This can be used in conjunction with setRecentlyUsedFilenames() for saving the 143 state of this list. 144 145 @see setRecentlyUsedFilenames 146 */ 147 StringArray getRecentlyUsedFilenames() const; 148 149 /** Sets all the entries on the recent files list. 150 151 This can be used in conjunction with getRecentlyUsedFilenames() for saving the 152 state of this list. 153 154 @see getRecentlyUsedFilenames, addRecentlyUsedFile 155 */ 156 void setRecentlyUsedFilenames (const StringArray& filenames); 157 158 /** Adds an entry to the recently-used files dropdown list. 159 160 If the file is already in the list, it will be moved to the top. A limit 161 is also placed on the number of items that are kept in the list. 162 163 @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles 164 */ 165 void addRecentlyUsedFile (const File& file); 166 167 /** Changes the limit for the number of files that will be stored in the recent-file list. 168 */ 169 void setMaxNumberOfRecentFiles (int newMaximum); 170 171 /** Changes the text shown on the 'browse' button. 172 173 By default this button just says "..." but you can change it. The button itself 174 can be changed using the look-and-feel classes, so it might not actually have any 175 text on it. 176 */ 177 void setBrowseButtonText (const String& browseButtonText); 178 179 //============================================================================== 180 /** Adds a listener that will be called when the selected file is changed. */ 181 void addListener (FilenameComponentListener* listener); 182 183 /** Removes a previously-registered listener. */ 184 void removeListener (FilenameComponentListener* listener); 185 186 /** Gives the component a tooltip. */ 187 void setTooltip (const String& newTooltip) override; 188 189 //============================================================================== 190 /** This abstract base class is implemented by LookAndFeel classes. */ 191 struct JUCE_API LookAndFeelMethods 192 { 193 virtual ~LookAndFeelMethods() = default; 194 195 virtual Button* createFilenameComponentBrowseButton (const String& text) = 0; 196 virtual void layoutFilenameComponent (FilenameComponent&, ComboBox* filenameBox, Button* browseButton) = 0; 197 }; 198 199 //============================================================================== 200 /** @internal */ 201 void paintOverChildren (Graphics&) override; 202 /** @internal */ 203 void resized() override; 204 /** @internal */ 205 void lookAndFeelChanged() override; 206 /** @internal */ 207 bool isInterestedInFileDrag (const StringArray&) override; 208 /** @internal */ 209 void filesDropped (const StringArray&, int, int) override; 210 /** @internal */ 211 void fileDragEnter (const StringArray&, int, int) override; 212 /** @internal */ 213 void fileDragExit (const StringArray&) override; 214 /** @internal */ 215 KeyboardFocusTraverser* createFocusTraverser() override; 216 217 private: 218 //============================================================================== 219 ComboBox filenameBox; 220 String lastFilename; 221 std::unique_ptr<Button> browseButton; 222 int maxRecentFiles = 30; 223 bool isDir, isSaving, isFileDragOver = false; 224 String wildcard, enforcedSuffix, browseButtonText; 225 ListenerList <FilenameComponentListener> listeners; 226 File defaultBrowseFile; 227 228 void showChooser(); 229 void handleAsyncUpdate() override; 230 231 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilenameComponent) 232 }; 233 234 } // namespace juce 235