1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp

246 lines
7.4 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
FilenameComponent::FilenameComponent (const String& name,
const File& currentFile,
const bool canEditFilename,
const bool isDirectory,
const bool isForSaving,
const String& fileBrowserWildcard,
const String& enforcedSuffix_,
const String& textWhenNothingSelected)
: Component (name),
maxRecentFiles (30),
isDir (isDirectory),
isSaving (isForSaving),
isFileDragOver (false),
wildcard (fileBrowserWildcard),
enforcedSuffix (enforcedSuffix_)
{
addAndMakeVisible (&filenameBox);
filenameBox.setEditableText (canEditFilename);
filenameBox.addListener (this);
filenameBox.setTextWhenNothingSelected (textWhenNothingSelected);
filenameBox.setTextWhenNoChoicesAvailable (TRANS ("(no recently selected files)"));
setBrowseButtonText ("...");
setCurrentFile (currentFile, true);
}
FilenameComponent::~FilenameComponent()
{
}
//==============================================================================
void FilenameComponent::paintOverChildren (Graphics& g)
{
if (isFileDragOver)
{
g.setColour (Colours::red.withAlpha (0.2f));
g.drawRect (0, 0, getWidth(), getHeight(), 3);
}
}
void FilenameComponent::resized()
{
getLookAndFeel().layoutFilenameComponent (*this, &filenameBox, browseButton);
}
void FilenameComponent::setBrowseButtonText (const String& newBrowseButtonText)
{
browseButtonText = newBrowseButtonText;
lookAndFeelChanged();
}
void FilenameComponent::lookAndFeelChanged()
{
browseButton = nullptr;
addAndMakeVisible (browseButton = getLookAndFeel().createFilenameComponentBrowseButton (browseButtonText));
browseButton->setConnectedEdges (Button::ConnectedOnLeft);
resized();
browseButton->addListener (this);
}
void FilenameComponent::setTooltip (const String& newTooltip)
{
SettableTooltipClient::setTooltip (newTooltip);
filenameBox.setTooltip (newTooltip);
}
void FilenameComponent::setDefaultBrowseTarget (const File& newDefaultDirectory)
{
defaultBrowseFile = newDefaultDirectory;
}
void FilenameComponent::buttonClicked (Button*)
{
#if JUCE_MODAL_LOOPS_PERMITTED
FileChooser fc (TRANS("Choose a new file"),
getCurrentFile() == File::nonexistent ? defaultBrowseFile
: getCurrentFile(),
wildcard);
if (isDir ? fc.browseForDirectory()
: (isSaving ? fc.browseForFileToSave (false)
: fc.browseForFileToOpen()))
{
setCurrentFile (fc.getResult(), true);
}
#else
jassertfalse; // needs rewriting to deal with non-modal environments
#endif
}
void FilenameComponent::comboBoxChanged (ComboBox*)
{
setCurrentFile (getCurrentFile(), true);
}
bool FilenameComponent::isInterestedInFileDrag (const StringArray&)
{
return true;
}
void FilenameComponent::filesDropped (const StringArray& filenames, int, int)
{
isFileDragOver = false;
repaint();
const File f (filenames[0]);
if (f.exists() && (f.isDirectory() == isDir))
setCurrentFile (f, true);
}
void FilenameComponent::fileDragEnter (const StringArray&, int, int)
{
isFileDragOver = true;
repaint();
}
void FilenameComponent::fileDragExit (const StringArray&)
{
isFileDragOver = false;
repaint();
}
//==============================================================================
File FilenameComponent::getCurrentFile() const
{
File f (filenameBox.getText());
if (enforcedSuffix.isNotEmpty())
f = f.withFileExtension (enforcedSuffix);
return f;
}
void FilenameComponent::setCurrentFile (File newFile,
const bool addToRecentlyUsedList,
const bool sendChangeNotification)
{
if (enforcedSuffix.isNotEmpty())
newFile = newFile.withFileExtension (enforcedSuffix);
if (newFile.getFullPathName() != lastFilename)
{
lastFilename = newFile.getFullPathName();
if (addToRecentlyUsedList)
addRecentlyUsedFile (newFile);
filenameBox.setText (lastFilename, true);
if (sendChangeNotification)
triggerAsyncUpdate();
}
}
void FilenameComponent::setFilenameIsEditable (const bool shouldBeEditable)
{
filenameBox.setEditableText (shouldBeEditable);
}
StringArray FilenameComponent::getRecentlyUsedFilenames() const
{
StringArray names;
for (int i = 0; i < filenameBox.getNumItems(); ++i)
names.add (filenameBox.getItemText (i));
return names;
}
void FilenameComponent::setRecentlyUsedFilenames (const StringArray& filenames)
{
if (filenames != getRecentlyUsedFilenames())
{
filenameBox.clear();
for (int i = 0; i < jmin (filenames.size(), maxRecentFiles); ++i)
filenameBox.addItem (filenames[i], i + 1);
}
}
void FilenameComponent::setMaxNumberOfRecentFiles (const int newMaximum)
{
maxRecentFiles = jmax (1, newMaximum);
setRecentlyUsedFilenames (getRecentlyUsedFilenames());
}
void FilenameComponent::addRecentlyUsedFile (const File& file)
{
StringArray files (getRecentlyUsedFilenames());
if (file.getFullPathName().isNotEmpty())
{
files.removeString (file.getFullPathName(), true);
files.insert (0, file.getFullPathName());
setRecentlyUsedFilenames (files);
}
}
//==============================================================================
void FilenameComponent::addListener (FilenameComponentListener* const listener)
{
listeners.add (listener);
}
void FilenameComponent::removeListener (FilenameComponentListener* const listener)
{
listeners.remove (listener);
}
void FilenameComponent::handleAsyncUpdate()
{
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &FilenameComponentListener::filenameComponentChanged, this);
}