2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../../core/juce_StandardHeader.h"
30 #include "juce_FileChooserDialogBox.h"
31 #include "../lookandfeel/juce_LookAndFeel.h"
32 #include "../../../text/juce_LocalisedStrings.h"
35 //==============================================================================
36 class FileChooserDialogBox::ContentComponent
: public Component
39 //==============================================================================
40 ContentComponent (const String
& name
, const String
& instructions_
, FileBrowserComponent
& chooserComponent_
)
42 chooserComponent (chooserComponent_
),
43 okButton (chooserComponent_
.getActionVerb()),
44 cancelButton (TRANS ("Cancel")),
45 newFolderButton (TRANS ("New Folder")),
46 instructions (instructions_
)
48 addAndMakeVisible (&chooserComponent
);
50 addAndMakeVisible (&okButton
);
51 okButton
.addShortcut (KeyPress::returnKey
);
53 addAndMakeVisible (&cancelButton
);
54 cancelButton
.addShortcut (KeyPress::escapeKey
);
56 addChildComponent (&newFolderButton
);
58 setInterceptsMouseClicks (false, true);
61 void paint (Graphics
& g
)
63 g
.setColour (getLookAndFeel().findColour (FileChooserDialogBox::titleTextColourId
));
69 const int buttonHeight
= 26;
71 Rectangle
<int> area (getLocalBounds());
73 getLookAndFeel().createFileChooserHeaderText (getName(), instructions
, text
, getWidth());
74 const Rectangle
<float> bb (text
.getBoundingBox (0, text
.getNumGlyphs(), false));
75 area
.removeFromTop (roundToInt (bb
.getBottom()) + 10);
77 chooserComponent
.setBounds (area
.removeFromTop (area
.getHeight() - buttonHeight
- 20));
78 Rectangle
<int> buttonArea (area
.reduced (16, 10));
80 okButton
.changeWidthToFitText (buttonHeight
);
81 okButton
.setBounds (buttonArea
.removeFromRight (okButton
.getWidth() + 16));
83 buttonArea
.removeFromRight (16);
85 cancelButton
.changeWidthToFitText (buttonHeight
);
86 cancelButton
.setBounds (buttonArea
.removeFromRight (cancelButton
.getWidth()));
88 newFolderButton
.changeWidthToFitText (buttonHeight
);
89 newFolderButton
.setBounds (buttonArea
.removeFromLeft (newFolderButton
.getWidth()));
92 FileBrowserComponent
& chooserComponent
;
93 TextButton okButton
, cancelButton
, newFolderButton
;
97 GlyphArrangement text
;
100 //==============================================================================
101 FileChooserDialogBox::FileChooserDialogBox (const String
& name
,
102 const String
& instructions
,
103 FileBrowserComponent
& chooserComponent
,
104 const bool warnAboutOverwritingExistingFiles_
,
105 const Colour
& backgroundColour
)
106 : ResizableWindow (name
, backgroundColour
, true),
107 warnAboutOverwritingExistingFiles (warnAboutOverwritingExistingFiles_
)
109 content
= new ContentComponent (name
, instructions
, chooserComponent
);
110 setContentOwned (content
, false);
112 setResizable (true, true);
113 setResizeLimits (300, 300, 1200, 1000);
115 content
->okButton
.addListener (this);
116 content
->cancelButton
.addListener (this);
117 content
->newFolderButton
.addListener (this);
118 content
->chooserComponent
.addListener (this);
120 FileChooserDialogBox::selectionChanged();
123 FileChooserDialogBox::~FileChooserDialogBox()
125 content
->chooserComponent
.removeListener (this);
128 //==============================================================================
129 #if JUCE_MODAL_LOOPS_PERMITTED
130 bool FileChooserDialogBox::show (int w
, int h
)
132 return showAt (-1, -1, w
, h
);
135 bool FileChooserDialogBox::showAt (int x
, int y
, int w
, int h
)
139 Component
* const previewComp
= content
->chooserComponent
.getPreviewComponent();
141 if (previewComp
!= nullptr)
142 w
= 400 + previewComp
->getWidth();
151 centreWithSize (w
, h
);
153 setBounds (x
, y
, w
, h
);
155 const bool ok
= (runModalLoop() != 0);
161 void FileChooserDialogBox::centreWithDefaultSize (Component
* componentToCentreAround
)
163 Component
* const previewComp
= content
->chooserComponent
.getPreviewComponent();
165 centreAroundComponent (componentToCentreAround
,
166 previewComp
!= nullptr ? 400 + previewComp
->getWidth() : 600,
170 //==============================================================================
171 void FileChooserDialogBox::buttonClicked (Button
* button
)
173 if (button
== &(content
->okButton
))
177 else if (button
== &(content
->cancelButton
))
179 closeButtonPressed();
181 else if (button
== &(content
->newFolderButton
))
187 void FileChooserDialogBox::closeButtonPressed()
192 void FileChooserDialogBox::selectionChanged()
194 content
->okButton
.setEnabled (content
->chooserComponent
.currentFileIsValid());
196 content
->newFolderButton
.setVisible (content
->chooserComponent
.isSaveMode()
197 && content
->chooserComponent
.getRoot().isDirectory());
200 void FileChooserDialogBox::fileClicked (const File
&, const MouseEvent
&)
204 void FileChooserDialogBox::fileDoubleClicked (const File
&)
207 content
->okButton
.triggerClick();
210 void FileChooserDialogBox::okToOverwriteFileCallback (int result
, FileChooserDialogBox
* box
)
212 if (result
!= 0 && box
!= nullptr)
213 box
->exitModalState (1);
216 void FileChooserDialogBox::okButtonPressed()
218 if (warnAboutOverwritingExistingFiles
219 && content
->chooserComponent
.isSaveMode()
220 && content
->chooserComponent
.getSelectedFile(0).exists())
222 AlertWindow::showOkCancelBox (AlertWindow::WarningIcon
,
223 TRANS("File already exists"),
224 TRANS("There's already a file called:")
225 + "\n\n" + content
->chooserComponent
.getSelectedFile(0).getFullPathName()
226 + "\n\n" + TRANS("Are you sure you want to overwrite it?"),
230 ModalCallbackFunction::forComponent (okToOverwriteFileCallback
, this));
238 void FileChooserDialogBox::createNewFolderCallback (int result
, FileChooserDialogBox
* box
,
239 Component::SafePointer
<AlertWindow
> alert
)
241 if (result
!= 0 && alert
!= nullptr && box
!= nullptr)
243 alert
->setVisible (false);
244 box
->createNewFolderConfirmed (alert
->getTextEditorContents ("name"));
248 void FileChooserDialogBox::createNewFolder()
250 File
parent (content
->chooserComponent
.getRoot());
252 if (parent
.isDirectory())
254 AlertWindow
* aw
= new AlertWindow (TRANS("New Folder"),
255 TRANS("Please enter the name for the folder"),
256 AlertWindow::NoIcon
, this);
258 aw
->addTextEditor ("name", String::empty
, String::empty
, false);
259 aw
->addButton (TRANS("ok"), 1, KeyPress::returnKey
);
260 aw
->addButton (TRANS("cancel"), KeyPress::escapeKey
);
262 aw
->enterModalState (true,
263 ModalCallbackFunction::forComponent (createNewFolderCallback
, this,
264 Component::SafePointer
<AlertWindow
> (aw
)),
269 void FileChooserDialogBox::createNewFolderConfirmed (const String
& nameFromDialog
)
271 const String
name (File::createLegalFileName (nameFromDialog
));
273 if (! name
.isEmpty())
275 const File
parent (content
->chooserComponent
.getRoot());
277 if (! parent
.getChildFile (name
).createDirectory())
279 AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon
,
280 TRANS ("New Folder"),
281 TRANS ("Couldn't create the folder!"));
284 content
->chooserComponent
.refresh();