JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_FileChooserDialogBox.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - 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 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-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
26namespace juce
27{
28
30{
31public:
32 ContentComponent (const String& name, const String& desc, FileBrowserComponent& chooser)
33 : Component (name),
34 chooserComponent (chooser),
35 okButton (chooser.getActionVerb()),
36 cancelButton (TRANS ("Cancel")),
37 newFolderButton (TRANS ("New Folder")),
38 instructions (desc)
39 {
40 addAndMakeVisible (chooserComponent);
41
42 addAndMakeVisible (okButton);
44
45 addAndMakeVisible (cancelButton);
47
48 addChildComponent (newFolderButton);
49
50 setInterceptsMouseClicks (false, true);
51 }
52
53 void paint (Graphics& g) override
54 {
55 text.draw (g, getLocalBounds().reduced (6)
56 .removeFromTop ((int) text.getHeight()).toFloat());
57 }
58
59 void resized() override
60 {
61 const int buttonHeight = 26;
62
63 auto area = getLocalBounds();
64
65 text.createLayout (getLookAndFeel().createFileChooserHeaderText (getName(), instructions),
66 (float) getWidth() - 12.0f);
67
68 area.removeFromTop (roundToInt (text.getHeight()) + 10);
69
70 chooserComponent.setBounds (area.removeFromTop (area.getHeight() - buttonHeight - 20));
71 auto buttonArea = area.reduced (16, 10);
72
73 okButton.changeWidthToFitText (buttonHeight);
74 okButton.setBounds (buttonArea.removeFromRight (okButton.getWidth() + 16));
75
76 buttonArea.removeFromRight (16);
77
78 cancelButton.changeWidthToFitText (buttonHeight);
79 cancelButton.setBounds (buttonArea.removeFromRight (cancelButton.getWidth()));
80
81 newFolderButton.changeWidthToFitText (buttonHeight);
82 newFolderButton.setBounds (buttonArea.removeFromLeft (newFolderButton.getWidth()));
83 }
84
85 FileBrowserComponent& chooserComponent;
86 TextButton okButton, cancelButton, newFolderButton;
87 String instructions;
88 TextLayout text;
89};
90
91//==============================================================================
93 const String& instructions,
94 FileBrowserComponent& chooserComponent,
95 bool shouldWarn,
96 Colour backgroundColour,
98 : ResizableWindow (name, backgroundColour, parentComp == nullptr),
99 warnAboutOverwritingExistingFiles (shouldWarn)
100{
101 content = new ContentComponent (name, instructions, chooserComponent);
102 setContentOwned (content, false);
103
104 setResizable (true, true);
105 setResizeLimits (300, 300, 1200, 1000);
106
107 content->okButton.onClick = [this] { okButtonPressed(); };
108 content->cancelButton.onClick = [this] { closeButtonPressed(); };
109 content->newFolderButton.onClick = [this] { createNewFolder(); };
110
111 content->chooserComponent.addListener (this);
112
113 FileChooserDialogBox::selectionChanged();
114
115 if (parentComp != nullptr)
116 parentComp->addAndMakeVisible (this);
117 else
119}
120
122{
123 content->chooserComponent.removeListener (this);
124}
125
126//==============================================================================
127#if JUCE_MODAL_LOOPS_PERMITTED
128bool FileChooserDialogBox::show (int w, int h)
129{
130 return showAt (-1, -1, w, h);
131}
132
133bool FileChooserDialogBox::showAt (int x, int y, int w, int h)
134{
135 if (w <= 0) w = getDefaultWidth();
136 if (h <= 0) h = 500;
137
138 if (x < 0 || y < 0)
139 centreWithSize (w, h);
140 else
141 setBounds (x, y, w, h);
142
143 const bool ok = (runModalLoop() != 0);
144 setVisible (false);
145 return ok;
146}
147#endif
148
150{
151 centreAroundComponent (componentToCentreAround, getDefaultWidth(), 500);
152}
153
154int FileChooserDialogBox::getDefaultWidth() const
155{
156 if (auto* previewComp = content->chooserComponent.getPreviewComponent())
157 return 400 + previewComp->getWidth();
158
159 return 600;
160}
161
162//==============================================================================
163void FileChooserDialogBox::closeButtonPressed()
164{
165 setVisible (false);
166}
167
168void FileChooserDialogBox::selectionChanged()
169{
170 content->okButton.setEnabled (content->chooserComponent.currentFileIsValid());
171
172 content->newFolderButton.setVisible (content->chooserComponent.isSaveMode()
173 && content->chooserComponent.getRoot().isDirectory());
174}
175
176void FileChooserDialogBox::fileDoubleClicked (const File&)
177{
178 selectionChanged();
179 content->okButton.triggerClick();
180}
181
182void FileChooserDialogBox::fileClicked (const File&, const MouseEvent&) {}
183void FileChooserDialogBox::browserRootChanged (const File&) {}
184
185void FileChooserDialogBox::okButtonPressed()
186{
187 if (warnAboutOverwritingExistingFiles
188 && content->chooserComponent.isSaveMode()
189 && content->chooserComponent.getSelectedFile (0).exists())
190 {
192 TRANS ("File already exists"),
193 TRANS ("There's already a file called: FLNM")
194 .replace ("FLNM", content->chooserComponent.getSelectedFile (0).getFullPathName())
195 + "\n\n"
196 + TRANS ("Are you sure you want to overwrite it?"),
197 TRANS ("Overwrite"),
198 TRANS ("Cancel"),
199 this);
200 messageBox = AlertWindow::showScopedAsync (options, [this] (int result)
201 {
202 if (result != 0)
203 exitModalState (1);
204 });
205 }
206 else
207 {
208 exitModalState (1);
209 }
210}
211
212void FileChooserDialogBox::createNewFolderCallback (int result, FileChooserDialogBox* box,
213 Component::SafePointer<AlertWindow> alert)
214{
215 if (result != 0 && alert != nullptr && box != nullptr)
216 {
217 alert->setVisible (false);
218 box->createNewFolderConfirmed (alert->getTextEditorContents ("Folder Name"));
219 }
220}
221
222void FileChooserDialogBox::createNewFolder()
223{
224 auto parent = content->chooserComponent.getRoot();
225
226 if (parent.isDirectory())
227 {
228 auto* aw = new AlertWindow (TRANS ("New Folder"),
229 TRANS ("Please enter the name for the folder"),
231
232 aw->addTextEditor ("Folder Name", String(), String(), false);
233 aw->addButton (TRANS ("Create Folder"), 1, KeyPress (KeyPress::returnKey));
234 aw->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey));
235
236 aw->enterModalState (true,
237 ModalCallbackFunction::forComponent (createNewFolderCallback, this,
238 Component::SafePointer<AlertWindow> (aw)),
239 true);
240 }
241}
242
243void FileChooserDialogBox::createNewFolderConfirmed (const String& nameFromDialog)
244{
246
247 if (! name.isEmpty())
248 {
249 auto parent = content->chooserComponent.getRoot();
250
251 if (! parent.getChildFile (name).createDirectory())
252 {
254 TRANS ("New Folder"),
255 TRANS ("Couldn't create the folder!"));
256 messageBox = AlertWindow::showScopedAsync (options, nullptr);
257 }
258
259 content->chooserComponent.refresh();
260 }
261}
262
263} // namespace juce
static ScopedMessageBox showScopedAsync(const MessageBoxOptions &options, std::function< void(int)> callback)
Shows an alert window using the specified options.
std::function< void()> onClick
You can assign a lambda to this callback object to have it called when the button is clicked.
void addShortcut(const KeyPress &)
Assigns a shortcut key to trigger the button.
virtual void triggerClick()
Causes the button to act as if it's been clicked.
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
The base class for all JUCE user-interface objects.
void setInterceptsMouseClicks(bool allowClicksOnThisComponent, bool allowClicksOnChildComponents) noexcept
Changes the default return value for the hitTest() method.
void exitModalState(int returnValue=0)
Ends a component's modal state.
void addAndMakeVisible(Component *child, int zOrder=-1)
Adds a child component to this one, and also makes the child visible if it isn't already.
void setAlwaysOnTop(bool shouldStayOnTop)
Sets whether the component should always be kept at the front of its siblings.
void setEnabled(bool shouldBeEnabled)
Enables or disables this component.
Component() noexcept
Creates a component.
void setBounds(int x, int y, int width, int height)
Changes the component's position and size.
int getWidth() const noexcept
Returns the component's width in pixels.
LookAndFeel & getLookAndFeel() const noexcept
Finds the appropriate look-and-feel to use for this component.
Rectangle< int > getLocalBounds() const noexcept
Returns the component's bounds, relative to its own origin.
void centreWithSize(int width, int height)
Changes the component's size and centres it within its parent.
void addChildComponent(Component *child, int zOrder=-1)
Adds a child component to this one.
virtual void setVisible(bool shouldBeVisible)
Makes the component visible or invisible.
String getName() const noexcept
Returns the name of this component.
A component for browsing and selecting a file or directory to open or save.
void refresh()
Refreshes the directory that's currently being listed.
File getSelectedFile(int index) const noexcept
Returns one of the files that the user has chosen.
virtual String getActionVerb() const
Returns a verb to describe what should happen when the file is accepted.
void removeListener(FileBrowserListener *listener)
Removes a listener.
bool isSaveMode() const noexcept
Returns true if the saveMode flag was set when this component was created.
const File & getRoot() const
Returns the directory whose contents are currently being shown in the listbox.
bool currentFileIsValid() const
Returns true if the currently selected file(s) are usable.
void addListener(FileBrowserListener *listener)
Adds a listener to be told when the user selects and clicks on files.
void paint(Graphics &g) override
Components can override this method to draw their content.
void resized() override
Called when this component's size has been changed.
void centreWithDefaultSize(Component *componentToCentreAround=nullptr)
Sets the size of this dialog box to its default and positions it either in the centre of the screen,...
FileChooserDialogBox(const String &title, const String &instructions, FileBrowserComponent &browserComponent, bool warnAboutOverwritingExistingFiles, Colour backgroundColour, Component *parentComponent=nullptr)
Creates a file chooser box.
bool isDirectory() const
Checks whether the file is a directory that exists.
const String & getFullPathName() const noexcept
Returns the complete, absolute path of this file.
Definition juce_File.h:153
static String createLegalFileName(const String &fileNameToFix)
Returns a version of a filename with any illegal characters removed.
bool exists() const
Checks whether the file actually exists.
A graphics context, used for drawing a component or image.
Represents a key press, including any modifier keys that are needed.
static const int escapeKey
key-code for the escape key
static const int returnKey
key-code for the return key
static MessageBoxOptions makeOptionsOkCancel(MessageBoxIconType iconType, const String &title, const String &message, const String &button1Text=String(), const String &button2Text=String(), Component *associatedComponent=nullptr)
Creates options suitable for a message box with two buttons.
static MessageBoxOptions makeOptionsOk(MessageBoxIconType iconType, const String &title, const String &message, const String &buttonText=String(), Component *associatedComponent=nullptr)
Creates options suitable for a message box with a single button.
static ModalComponentManager::Callback * forComponent(void(*functionToCall)(int, ComponentType *), ComponentType *component)
This is a utility function to create a ModalComponentManager::Callback that will call a static functi...
Rectangle< float > toFloat() const noexcept
Casts this rectangle to a Rectangle<float>.
A base class for top-level windows that can be dragged around and resized.
void setResizable(bool shouldBeResizable, bool useBottomRightCornerResizer)
Make the window resizable or fixed.
void setResizeLimits(int newMinimumWidth, int newMinimumHeight, int newMaximumWidth, int newMaximumHeight) noexcept
This sets the maximum and minimum sizes for the window.
void setContentOwned(Component *newContentComponent, bool resizeToFitWhenContentChangesSize)
Changes the current content component.
The JUCE String class!
Definition juce_String.h:53
A button that uses the standard lozenge-shaped background with a line of text on it.
void changeWidthToFitText()
Changes this button's width to fit neatly around its current text, without changing its height.
A Pre-formatted piece of text, which may contain multiple fonts and colours.
void draw(Graphics &, Rectangle< float > area) const
Draws the layout within the specified area.
float getHeight() const noexcept
Returns the maximum height of the content.
void createLayout(const AttributedString &, float maxWidth)
Creates a layout from the given attributed string.
void centreAroundComponent(Component *componentToCentreAround, int width, int height)
This will set the bounds of the window so that it's centred in front of another window.
#define TRANS(stringLiteral)
Uses the LocalisedStrings class to translate the given string literal.
JUCE Namespace.
@ WarningIcon
An exclamation mark to indicate that the dialog is a warning about something and shouldn't be ignored...
@ NoIcon
No icon will be shown on the dialog box.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
static bool areThereAnyAlwaysOnTopWindows()
Returns true if any windows have a z order that is higher than normal.