mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-21 01:24:21 +00:00
Minor string clean-ups. Made key-shortcut indicators in popup menus use icons for shift/command/option on the mac.
This commit is contained in:
parent
04351861ae
commit
06d436a3ab
34 changed files with 99 additions and 92 deletions
|
|
@ -98,8 +98,7 @@ namespace
|
|||
if (parent == 0)
|
||||
break;
|
||||
|
||||
TCHAR windowType [32];
|
||||
zeromem (windowType, sizeof (windowType));
|
||||
TCHAR windowType [32] = { 0 };
|
||||
GetClassName (parent, windowType, 31);
|
||||
|
||||
if (String (windowType).equalsIgnoreCase ("MDIClient"))
|
||||
|
|
|
|||
|
|
@ -180,8 +180,7 @@ namespace
|
|||
if (parent == 0)
|
||||
break;
|
||||
|
||||
TCHAR windowType [32];
|
||||
zeromem (windowType, sizeof (windowType));
|
||||
TCHAR windowType[32] = { 0 };
|
||||
GetClassName (parent, windowType, 31);
|
||||
|
||||
if (String (windowType).equalsIgnoreCase ("MDIClient"))
|
||||
|
|
@ -1253,8 +1252,7 @@ public:
|
|||
if (parent == 0)
|
||||
break;
|
||||
|
||||
TCHAR windowType [32];
|
||||
zeromem (windowType, sizeof (windowType));
|
||||
TCHAR windowType [32] = { 0 };
|
||||
GetClassName (parent, windowType, 31);
|
||||
|
||||
if (String (windowType).equalsIgnoreCase ("MDIClient"))
|
||||
|
|
@ -1489,8 +1487,7 @@ private:
|
|||
|
||||
const String getHostName()
|
||||
{
|
||||
char host[256];
|
||||
zeromem (host, sizeof (host));
|
||||
char host[256] = { 0 };
|
||||
getHostProductString (host);
|
||||
return host;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,8 +308,7 @@ private:
|
|||
output->writeIntBigEndian (lengthInSamples);
|
||||
output->writeShortBigEndian ((short) bitsPerSample);
|
||||
|
||||
uint8 sampleRateBytes[10];
|
||||
zeromem (sampleRateBytes, 10);
|
||||
uint8 sampleRateBytes[10] = { 0 };
|
||||
|
||||
if (sampleRate <= 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ void ResamplingAudioSource::setFilterCoefficients (double c1, double c2, double
|
|||
|
||||
void ResamplingAudioSource::resetFilters()
|
||||
{
|
||||
zeromem (filterStates, sizeof (FilterState) * numChannels);
|
||||
filterStates.clear (numChannels);
|
||||
}
|
||||
|
||||
void ResamplingAudioSource::applyFilter (float* samples, int num, FilterState& fs)
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void AudioSampleBuffer::setSize (const int newNumChannels,
|
|||
if (avoidReallocating && allocatedBytes >= newTotalBytes)
|
||||
{
|
||||
if (clearExtraSpace)
|
||||
zeromem (allocatedData, newTotalBytes);
|
||||
allocatedData.clear (newTotalBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -448,16 +448,12 @@ const String Time::getTimeZone() const throw()
|
|||
_tzset();
|
||||
|
||||
#ifdef USE_NEW_SECURE_TIME_FNS
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
char name [128];
|
||||
char name[128] = { 0 };
|
||||
size_t length;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
zeromem (name, sizeof (name));
|
||||
_get_tzname (&length, name, 127, i);
|
||||
zone[i] = name;
|
||||
}
|
||||
_get_tzname (&length, name, 127, i);
|
||||
zone[i] = name;
|
||||
}
|
||||
#else
|
||||
const char** const zonePtr = (const char**) _tzname;
|
||||
|
|
|
|||
|
|
@ -216,9 +216,7 @@ void MD5::ProcessContext::finish (void* const result)
|
|||
const int paddingLength = (index < 56) ? (56 - index)
|
||||
: (120 - index);
|
||||
|
||||
uint8 paddingBuffer [64];
|
||||
zeromem (paddingBuffer, paddingLength);
|
||||
paddingBuffer [0] = 0x80;
|
||||
uint8 paddingBuffer[64] = { 0x80 }; // first byte is 0x80, remaining bytes are zero.
|
||||
processBlock (paddingBuffer, paddingLength);
|
||||
|
||||
processBlock (encodedLength, 8);
|
||||
|
|
|
|||
|
|
@ -234,18 +234,18 @@ const String KeyPress::getTextDescription() const
|
|||
if (mods.isShiftDown())
|
||||
desc << "shift + ";
|
||||
|
||||
#if JUCE_MAC
|
||||
// only do this on the mac, because on Windows ctrl and command are the same,
|
||||
// and this would get confusing
|
||||
if (mods.isCommandDown())
|
||||
desc << "command + ";
|
||||
|
||||
#if JUCE_MAC
|
||||
if (mods.isAltDown())
|
||||
desc << "option + ";
|
||||
#else
|
||||
|
||||
// only do this on the mac, because on Windows ctrl and command are the same,
|
||||
// and this would get confusing
|
||||
if (mods.isCommandDown())
|
||||
desc << "command + ";
|
||||
#else
|
||||
if (mods.isAltDown())
|
||||
desc << "alt + ";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < numElementsInArray (KeyPressHelpers::translations); ++i)
|
||||
if (keyCode == KeyPressHelpers::translations[i].code)
|
||||
|
|
@ -278,5 +278,16 @@ const String KeyPress::getTextDescription() const
|
|||
return desc;
|
||||
}
|
||||
|
||||
const String KeyPress::getTextDescriptionWithIcons() const
|
||||
{
|
||||
#if JUCE_MAC
|
||||
return getTextDescription().replace ("shift + ", String::charToString (0x21e7))
|
||||
.replace ("command + ", String::charToString (0x2318))
|
||||
.replace ("option + ", String::charToString (0x2325));
|
||||
#else
|
||||
return getTextDescription();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -148,6 +148,13 @@ public:
|
|||
*/
|
||||
const String getTextDescription() const;
|
||||
|
||||
/** Creates a textual description of the key combination, using unicode icon symbols if possible.
|
||||
|
||||
On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual
|
||||
modifier key descriptions that are returned by getTextDescription()
|
||||
*/
|
||||
const String getTextDescriptionWithIcons() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether the user is currently holding down the keys that make up this
|
||||
KeyPress.
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public:
|
|||
|
||||
for (int i = 0; i < keyPresses.size(); ++i)
|
||||
{
|
||||
const String key (keyPresses.getReference(i).getTextDescription());
|
||||
const String key (keyPresses.getReference(i).getTextDescriptionWithIcons());
|
||||
|
||||
if (shortcutKey.isNotEmpty())
|
||||
shortcutKey << ", ";
|
||||
|
|
|
|||
|
|
@ -1083,8 +1083,7 @@ private:
|
|||
{
|
||||
if (s [index] == '#')
|
||||
{
|
||||
uint32 hex [6];
|
||||
zeromem (hex, sizeof (hex));
|
||||
uint32 hex[6] = { 0 };
|
||||
int numChars = 0;
|
||||
|
||||
for (int i = 6; --i >= 0;)
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ bool File::isAChildOf (const File& potentialParent) const
|
|||
//==============================================================================
|
||||
bool File::isAbsolutePath (const String& path)
|
||||
{
|
||||
return path.startsWithChar ('/') || path.startsWithChar ('\\')
|
||||
return path.startsWithChar (separator)
|
||||
#if JUCE_WINDOWS
|
||||
|| (path.isNotEmpty() && path[1] == ':');
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -343,8 +343,7 @@ int ZipFile::findEndOfZipEntryTable (InputStream& input, int& numEntries)
|
|||
int64 pos = in.getPosition();
|
||||
const int64 lowestPos = jmax ((int64) 0, pos - 1024);
|
||||
|
||||
char buffer [32];
|
||||
zeromem (buffer, sizeof (buffer));
|
||||
char buffer [32] = { 0 };
|
||||
|
||||
while (pos > lowestPos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ int MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumB
|
|||
|
||||
const String MemoryOutputStream::toUTF8() const
|
||||
{
|
||||
return String::fromUTF8 (static_cast <const char*> (getData()), (int) getDataSize());
|
||||
const char* const d = static_cast <const char*> (getData());
|
||||
return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize()));
|
||||
}
|
||||
|
||||
const String MemoryOutputStream::toString() const
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ void BigInteger::clear()
|
|||
}
|
||||
else
|
||||
{
|
||||
zeromem (values, sizeof (uint32) * (numValues + 1));
|
||||
values.clear (numValues + 1);
|
||||
}
|
||||
|
||||
highestBit = -1;
|
||||
|
|
|
|||
|
|
@ -230,6 +230,14 @@ public:
|
|||
swapVariables (data, other.data);
|
||||
}
|
||||
|
||||
/** This fills the block with zeros, up to the number of elements specified.
|
||||
Since the block has no way of knowing its own size, you must make sure that the number of
|
||||
elements you specify doesn't exceed the allocated size.
|
||||
*/
|
||||
void clear (size_t numElements) throw()
|
||||
{
|
||||
zeromem (data, sizeof (ElementType) * numElements);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -113,12 +113,16 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
/**
|
||||
Used to point to an object of type ReferenceCountedObject.
|
||||
A smart-pointer class which points to a reference-counted object.
|
||||
|
||||
It's wise to use a typedef instead of typing out the templated name
|
||||
each time - e.g.
|
||||
The template parameter specifies the class of the object you want to point to - the easiest
|
||||
way to make a class reference-countable is to simply make it inherit from ReferenceCountedObject,
|
||||
but if you need to, you could roll your own reference-countable class by implementing a pair of
|
||||
mathods called incReferenceCount() and decReferenceCount().
|
||||
|
||||
typedef ReferenceCountedObjectPtr<MyClass> MyClassPtr;
|
||||
When using this class, you'll probably want to create a typedef to abbreviate the full
|
||||
templated name - e.g.
|
||||
@code typedef ReferenceCountedObjectPtr<MyClass> MyClassPtr;@endcode
|
||||
|
||||
@see ReferenceCountedObject, ReferenceCountedObjectArray
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ public:
|
|||
|
||||
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
|
||||
{
|
||||
filenameFound = String::fromUTF8 (de->d_name);
|
||||
filenameFound = CharPointer_UTF8 (de->d_name);
|
||||
|
||||
updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ const String SystemStats::getLogonName()
|
|||
user = pw->pw_name;
|
||||
}
|
||||
|
||||
return String::fromUTF8 (user);
|
||||
return CharPointer_UTF8 (user);
|
||||
}
|
||||
|
||||
const String SystemStats::getFullUserName()
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ const File File::getCurrentWorkingDirectory()
|
|||
bufferSize += 1024;
|
||||
}
|
||||
|
||||
return File (String::fromUTF8 (cwd));
|
||||
return File (CharPointer_UTF8 (cwd));
|
||||
}
|
||||
|
||||
bool File::setAsCurrentWorkingDirectory() const
|
||||
|
|
@ -490,7 +490,7 @@ const File juce_getExecutableFile()
|
|||
#else
|
||||
Dl_info exeInfo;
|
||||
dladdr ((void*) juce_getExecutableFile, &exeInfo); // (can't be a const void* on android)
|
||||
return File::getCurrentWorkingDirectory().getChildFile (String::fromUTF8 (exeInfo.dli_fname));
|
||||
return File::getCurrentWorkingDirectory().getChildFile (CharPointer_UTF8 (exeInfo.dli_fname));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ const File File::getSpecialLocation (const SpecialLocationType type)
|
|||
homeDir = pw->pw_dir;
|
||||
}
|
||||
|
||||
return File (String::fromUTF8 (homeDir));
|
||||
return File (CharPointer_UTF8 (homeDir));
|
||||
}
|
||||
|
||||
case userDocumentsDirectory:
|
||||
|
|
@ -185,7 +185,7 @@ const File File::getSpecialLocation (const SpecialLocationType type)
|
|||
|
||||
case invokedExecutableFile:
|
||||
if (juce_Argv0 != 0)
|
||||
return File (String::fromUTF8 (juce_Argv0));
|
||||
return File (CharPointer_UTF8 (juce_Argv0));
|
||||
// deliberate fall-through...
|
||||
|
||||
case currentExecutableFile:
|
||||
|
|
@ -260,7 +260,7 @@ public:
|
|||
|
||||
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
|
||||
{
|
||||
filenameFound = String::fromUTF8 (de->d_name);
|
||||
filenameFound = CharPointer_UTF8 (de->d_name);
|
||||
|
||||
updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly);
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
}
|
||||
|
||||
StringArray fontDirs;
|
||||
fontDirs.addTokens (String::fromUTF8 (getenv ("JUCE_FONT_PATH")), ";,", String::empty);
|
||||
fontDirs.addTokens (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH")), ";,", String::empty);
|
||||
fontDirs.removeEmptyStrings (true);
|
||||
|
||||
if (fontDirs.size() == 0)
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ private:
|
|||
numConsecutiveLFs = 0;
|
||||
}
|
||||
|
||||
const String header (String::fromUTF8 ((const char*) buffer.getData()));
|
||||
const String header (CharPointer_UTF8 ((const char*) buffer.getData()));
|
||||
|
||||
if (header.startsWithIgnoreCase ("HTTP/"))
|
||||
return header.trimEnd();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ const String SystemStats::getLogonName()
|
|||
user = pw->pw_name;
|
||||
}
|
||||
|
||||
return String::fromUTF8 (user);
|
||||
return CharPointer_UTF8 (user);
|
||||
}
|
||||
|
||||
const String SystemStats::getFullUserName()
|
||||
|
|
|
|||
|
|
@ -507,12 +507,9 @@ public:
|
|||
if (! usingXShm)
|
||||
#endif
|
||||
{
|
||||
imageDataAllocated.malloc (lineStride * h);
|
||||
imageDataAllocated.allocate (lineStride * h, format_ == Image::ARGB && clearImage);
|
||||
imageData = imageDataAllocated;
|
||||
|
||||
if (format_ == Image::ARGB && clearImage)
|
||||
zeromem (imageData, h * lineStride);
|
||||
|
||||
xImage = (XImage*) juce_calloc (sizeof (XImage));
|
||||
|
||||
xImage->width = w;
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ END_JUCE_NAMESPACE
|
|||
|
||||
if ([err length] > 0)
|
||||
{
|
||||
*error = JUCE_NAMESPACE::String::fromUTF8 ([err UTF8String]);
|
||||
*error = JUCE_NAMESPACE::CharPointer_UTF8 ([err UTF8String]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -482,7 +482,7 @@ const StringArray AudioCDBurner::findAvailableDevices()
|
|||
StringArray s;
|
||||
|
||||
for (unsigned int i = 0; i < [names count]; ++i)
|
||||
s.add (String::fromUTF8 ([[names objectAtIndex: i] UTF8String]));
|
||||
s.add (CharPointer_UTF8 ([[names objectAtIndex: i] UTF8String]));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,8 +150,7 @@ public:
|
|||
String name;
|
||||
|
||||
{
|
||||
char channelName [256];
|
||||
zerostruct (channelName);
|
||||
char channelName [256] = { 0 };
|
||||
UInt32 nameSize = sizeof (channelName);
|
||||
UInt32 channelNum = chanNum + 1;
|
||||
pa.mSelector = kAudioDevicePropertyChannelName;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ const File File::getSpecialLocation (const SpecialLocationType type)
|
|||
|
||||
case invokedExecutableFile:
|
||||
if (juce_Argv0 != 0)
|
||||
return File (String::fromUTF8 (juce_Argv0));
|
||||
return File (CharPointer_UTF8 (juce_Argv0));
|
||||
// deliberate fall-through...
|
||||
|
||||
case currentExecutableFile:
|
||||
|
|
@ -449,11 +449,10 @@ bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path)
|
|||
|
||||
const String PlatformUtilities::makePathFromFSRef (FSRef* file)
|
||||
{
|
||||
char path [2048];
|
||||
zerostruct (path);
|
||||
char path [2048] = { 0 };
|
||||
|
||||
if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr)
|
||||
return PlatformUtilities::convertToPrecomposedUnicode (String::fromUTF8 (path));
|
||||
return PlatformUtilities::convertToPrecomposedUnicode (CharPointer_UTF8 (path));
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace
|
|||
{
|
||||
const String nsStringToJuce (NSString* s)
|
||||
{
|
||||
return String::fromUTF8 ([s UTF8String]);
|
||||
return CharPointer_UTF8 ([s UTF8String]);
|
||||
}
|
||||
|
||||
NSString* juceStringToNS (const String& s)
|
||||
|
|
|
|||
|
|
@ -245,9 +245,8 @@ public:
|
|||
if (sampleRate == 0)
|
||||
sampleRate = 44100;
|
||||
|
||||
long numSources = 32;
|
||||
ASIOClockSource clocks[32];
|
||||
zeromem (clocks, sizeof (clocks));
|
||||
ASIOClockSource clocks[32] = { 0 };
|
||||
long numSources = numElementsInArray (clocks);
|
||||
asioObject->getClockSources (clocks, &numSources);
|
||||
bool isSourceSet = false;
|
||||
|
||||
|
|
@ -842,8 +841,7 @@ private:
|
|||
{
|
||||
if (asioObject != 0)
|
||||
{
|
||||
char buffer [256];
|
||||
zeromem (buffer, sizeof (buffer));
|
||||
char buffer [256] = { 0 };
|
||||
|
||||
if (! asioObject->init (windowHandle))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -327,8 +327,7 @@ void findCDDevices (Array<CDDeviceDescription>& list)
|
|||
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
char buffer[100];
|
||||
zeromem (buffer, sizeof (buffer));
|
||||
char buffer[100] = { 0 };
|
||||
|
||||
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER p;
|
||||
zerostruct (p);
|
||||
|
|
@ -1688,7 +1687,7 @@ bool AudioCDBurner::addAudioTrack (AudioSource* audioSource, int numSamples)
|
|||
source->getNextAudioBlock (info);
|
||||
}
|
||||
|
||||
zeromem (buffer, bytesPerBlock);
|
||||
buffer.clear (bytesPerBlock);
|
||||
|
||||
typedef AudioData::Pointer <AudioData::Int16, AudioData::LittleEndian,
|
||||
AudioData::Interleaved, AudioData::NonConst> CDSampleFormat;
|
||||
|
|
|
|||
|
|
@ -430,8 +430,7 @@ private:
|
|||
if (availableExtensions.contains ("WGL_ARB_multisample"))
|
||||
attributes[numAttributes++] = WGL_SAMPLES_ARB;
|
||||
|
||||
int values[32];
|
||||
zeromem (values, sizeof (values));
|
||||
int values[32] = { 0 };
|
||||
|
||||
if (wglGetPixelFormatAttribivARB (dc, pixelFormatIndex, 0, numAttributes, attributes, values))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ const String SystemStats::getCpuVendor()
|
|||
|
||||
static void juce_getCpuVendor (char* const v)
|
||||
{
|
||||
int vendor[4];
|
||||
zeromem (vendor, 16);
|
||||
int vendor[4] = { 0 };
|
||||
|
||||
#ifdef JUCE_64BIT
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -2102,13 +2102,17 @@ const String String::createStringFromData (const void* const data_, const int si
|
|||
}
|
||||
else
|
||||
{
|
||||
const uint8* start = data;
|
||||
const uint8* end = data + size;
|
||||
|
||||
if (size >= 3
|
||||
&& data[0] == (uint8) CharPointer_UTF8::byteOrderMark1
|
||||
&& data[1] == (uint8) CharPointer_UTF8::byteOrderMark2
|
||||
&& data[2] == (uint8) CharPointer_UTF8::byteOrderMark3)
|
||||
return String::fromUTF8 ((const char*) data + 3, size - 3);
|
||||
start += 3;
|
||||
|
||||
return String::fromUTF8 ((const char*) data, size);
|
||||
return String (CharPointer_UTF8 ((const char*) start),
|
||||
CharPointer_UTF8 ((const char*) end));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2218,18 +2222,13 @@ int String::getNumBytesAsUTF8() const throw()
|
|||
|
||||
const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes)
|
||||
{
|
||||
if (buffer == 0)
|
||||
return empty;
|
||||
|
||||
CharPointer_UTF8 b (buffer);
|
||||
|
||||
if (bufferSizeBytes < 0)
|
||||
return String (b);
|
||||
|
||||
const size_t numChars = b.lengthUpTo (CharPointer_UTF8 (buffer + bufferSizeBytes));
|
||||
|
||||
if (numChars > 0)
|
||||
return String (b, numChars);
|
||||
if (buffer != 0)
|
||||
{
|
||||
if (bufferSizeBytes < 0)
|
||||
return String (CharPointer_UTF8 (buffer));
|
||||
else if (bufferSizeBytes > 0)
|
||||
return String (CharPointer_UTF8 (buffer), CharPointer_UTF8 (buffer + bufferSizeBytes));
|
||||
}
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue