diff --git a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj index 9341922d87..0526b0516d 100644 --- a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj +++ b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj @@ -86,6 +86,7 @@ F2F98DA41146390D05A44EAD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectContentComponent.h; path = ../../Source/Project/jucer_ProjectContentComponent.h; sourceTree = SOURCE_ROOT; }; 296E0498784BF03FA18B164B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectExporter.cpp; path = ../../Source/Project/jucer_ProjectExporter.cpp; sourceTree = SOURCE_ROOT; }; 5DE419991013E7C0F203E99F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExporter.h; path = ../../Source/Project/jucer_ProjectExporter.h; sourceTree = SOURCE_ROOT; }; + AB9EE4734D894FBF1CF62C5F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Android.h; path = ../../Source/Project/jucer_ProjectExport_Android.h; sourceTree = SOURCE_ROOT; }; 889715B0152919B2EAA1F5F9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Make.h; path = ../../Source/Project/jucer_ProjectExport_Make.h; sourceTree = SOURCE_ROOT; }; 907F302BB89308CDB2C5FD0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_MSVC.h; path = ../../Source/Project/jucer_ProjectExport_MSVC.h; sourceTree = SOURCE_ROOT; }; D250274734D729D2E0389A20 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_XCode.h; path = ../../Source/Project/jucer_ProjectExport_XCode.h; sourceTree = SOURCE_ROOT; }; @@ -165,6 +166,7 @@ F2F98DA41146390D05A44EAD, 296E0498784BF03FA18B164B, 5DE419991013E7C0F203E99F, + AB9EE4734D894FBF1CF62C5F, 889715B0152919B2EAA1F5F9, 907F302BB89308CDB2C5FD0E, D250274734D729D2E0389A20, diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj index b81b006292..4c768a4e60 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj @@ -162,6 +162,7 @@ + diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj index dfcfa551f9..6c95751d08 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj @@ -162,6 +162,7 @@ + diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj index 6971cec82c..9ca167f9a5 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj @@ -167,6 +167,7 @@ + diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters index e077948cb6..19e09167bc 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters +++ b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters @@ -183,6 +183,9 @@ The Jucer\Project + + The Jucer\Project + The Jucer\Project diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer index b9e039f2d9..588b158e16 100644 --- a/extras/Jucer (experimental)/Jucer.jucer +++ b/extras/Jucer (experimental)/Jucer.jucer @@ -90,6 +90,8 @@ file="Source/Project/jucer_ProjectExporter.cpp"/> + = size && im2.getWidth() >= size) + im = im1.getWidth() < im2.getWidth() ? im1 : im2; + else if (im1.getWidth() >= size) + im = im1; + else if (im2.getWidth() >= size) + im = im2; + else + return Image(); + } + else + { + im = im1.isValid() ? im1 : im2; + } + + if (size == im.getWidth() && size == im.getHeight()) + return im; + + if (returnNullIfNothingBigEnough && im.getWidth() < size && im.getHeight() < size) + return Image::null; + + Image newIm (Image::ARGB, size, size, true); + Graphics g (newIm); + g.drawImageWithin (im, 0, 0, size, size, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); + return newIm; +} + + const StringPairArray Project::getPreprocessorDefs() const { return parsePreprocessorDefs (getProjectPreprocessorDefs().toString()); diff --git a/extras/Jucer (experimental)/Source/Project/jucer_Project.h b/extras/Jucer (experimental)/Source/Project/jucer_Project.h index a171df4f95..8859cf2e17 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_Project.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_Project.h @@ -109,6 +109,7 @@ public: Value getSmallIconImageItemID() const { return getProjectValue ("smallIcon"); } const Image getBigIcon(); const Image getSmallIcon(); + const Image getBestIconForSize (int size, bool returnNullIfNothingBigEnough); Value shouldBuildVST() const { return getProjectValue ("buildVST"); } Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); } diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Android.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Android.h new file mode 100644 index 0000000000..05cb736eea --- /dev/null +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Android.h @@ -0,0 +1,374 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 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. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ +#define __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ + +#include "jucer_ProjectExporter.h" + + +//============================================================================== +class AndroidProjectExporter : public ProjectExporter +{ +public: + //============================================================================== + static const char* getNameAndroid() { return "Android Project"; } + static const char* getValueTreeTypeName() { return "ANDROID"; } + + static AndroidProjectExporter* createForSettings (Project& project, const ValueTree& settings) + { + if (settings.hasType (getValueTreeTypeName())) + return new AndroidProjectExporter (project, settings); + + return 0; + } + + //============================================================================== + AndroidProjectExporter (Project& project_, const ValueTree& settings_) + : ProjectExporter (project_, settings_) + { + name = getNameAndroid(); + + if (getTargetLocation().toString().isEmpty()) + getTargetLocation() = getDefaultBuildsRootFolder() + "Android"; + + if (getSDKPath().toString().isEmpty()) + getSDKPath() = "${user.home}/SDKs/android-sdk-mac_86"; + + if (getNDKPath().toString().isEmpty()) + getNDKPath() = "${user.home}/SDKs/android-ndk-r4-crystax"; + } + + //============================================================================== + bool isDefaultFormatForCurrentOS() + { + #if JUCE_ANDROID + return true; + #else + return false; + #endif + } + + bool isPossibleForCurrentProject() { return project.isGUIApplication(); } + bool usesMMFiles() const { return false; } + + void launchProject() + { + } + + void createPropertyEditors (Array & props) + { + ProjectExporter::createPropertyEditors (props); + + props.add (new TextPropertyComponent (getSDKPath(), "Android SDK Path", 1024, false)); + props.getLast()->setTooltip ("The path to the Android SDK folder on the target build machine"); + + props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false)); + props.getLast()->setTooltip ("The path to the Android NDK folder on the target build machine"); + } + + Value getSDKPath() const { return getSetting (Ids::androidSDKPath); } + Value getNDKPath() const { return getSetting (Ids::androidNDKPath); } + + //============================================================================== + void create() + { + const File target (getTargetFolder()); + const File jniFolder (target.getChildFile ("jni")); + + createDirectoryOrThrow (target.getChildFile ("src/com")); + createDirectoryOrThrow (jniFolder); + createDirectoryOrThrow (target.getChildFile ("res/drawable-hdpi")); + createDirectoryOrThrow (target.getChildFile ("res/drawable-mdpi")); + createDirectoryOrThrow (target.getChildFile ("res/drawable-ldpi")); + createDirectoryOrThrow (target.getChildFile ("res/values")); + createDirectoryOrThrow (target.getChildFile ("libs")); + createDirectoryOrThrow (target.getChildFile ("bin")); + + { + ScopedPointer manifest (createManifestXML()); + writeXmlOrThrow (*manifest, target.getChildFile ("AndroidManifest.xml"), "utf-8", 100); + } + + writeJNIMakefile (jniFolder.getChildFile ("Android.mk")); + + { + ScopedPointer antBuildXml (createAntBuildXML()); + writeXmlOrThrow (*antBuildXml, target.getChildFile ("build.xml"), "UTF-8", 100); + } + + writeBuildPropertiesFile (target.getChildFile ("build.properties")); + writeDefaultPropertiesFile (target.getChildFile ("default.properties")); + writeLocalPropertiesFile (target.getChildFile ("local.properties")); + + writeIcon (target.getChildFile ("res/drawable-hdpi/icon.png"), 72); + writeIcon (target.getChildFile ("res/drawable-mdpi/icon.png"), 48); + writeIcon (target.getChildFile ("res/drawable-ldpi/icon.png"), 36); + + writeStringsFile (target.getChildFile ("res/values/strings.xml")); + } + +private: + //============================================================================== + XmlElement* createManifestXML() + { + XmlElement* manifest = new XmlElement ("manifest"); + + manifest->setAttribute ("xmlns:android", "http://schemas.android.com/apk/res/android"); + manifest->setAttribute ("android:versionCode", "1"); + manifest->setAttribute ("android:versionName", "1.0"); + manifest->setAttribute ("package", "com.juce"); + + XmlElement* screens = manifest->createNewChildElement ("supports-screens"); + screens->setAttribute ("android:smallScreens", "true"); + screens->setAttribute ("android:normalScreens", "true"); + screens->setAttribute ("android:largeScreens", "true"); + screens->setAttribute ("android:xlargeScreens", "true"); + screens->setAttribute ("android:anyDensity", "true"); + + XmlElement* app = manifest->createNewChildElement ("application"); + app->setAttribute ("android:label", "@string/app_name"); + app->setAttribute ("android:icon", "@drawable/icon"); + + XmlElement* act = app->createNewChildElement ("activity"); + act->setAttribute ("android:name", "JuceAppActivity"); + act->setAttribute ("android:label", "@string/app_name"); + + XmlElement* intent = act->createNewChildElement ("intent-filter"); + intent->createNewChildElement ("action")->setAttribute ("android:name", "android.intent.action.MAIN"); + intent->createNewChildElement ("category")->setAttribute ("android:name", "android.intent.category.LAUNCHER"); + + return manifest; + } + + //============================================================================== + void findAllFilesToCompile (const Project::Item& projectItem, Array& results) + { + if (projectItem.isGroup()) + { + for (int i = 0; i < projectItem.getNumChildren(); ++i) + findAllFilesToCompile (projectItem.getChild(i), results); + } + else + { + if (projectItem.shouldBeCompiled()) + results.add (RelativePath (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder)); + } + } + + void writeJNIMakefile (const File& file) + { + Array files; + findAllFilesToCompile (project.getMainGroup(), files); + + for (int i = 0; i < juceWrapperFiles.size(); ++i) + if (shouldFileBeCompiledByDefault (juceWrapperFiles.getReference(i))) + files.add (juceWrapperFiles.getReference(i)); + + MemoryOutputStream mo; + writeJNIMakefile (mo, files); + + overwriteFileIfDifferentOrThrow (file, mo); + } + + void writeJNIMakefile (OutputStream& out, const Array& files) + { + out << "# Automatically generated makefile, created by the Jucer" << newLine + << "# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project!" << newLine + << newLine + << "LOCAL_PATH := $(call my-dir)" << newLine + << newLine + << "include $(CLEAR_VARS)" << newLine + << newLine + << "LOCAL_CPP_EXTENSION := cpp" << newLine + << "LOCAL_MODULE := juce_jni" << newLine + << "LOCAL_SRC_FILES := \\" << newLine; + + for (int i = 0; i < files.size(); ++i) + out << " ../" << escapeSpaces (files.getReference(i).toUnixStyle()) << "\\" << newLine; + + out << newLine + << "ifeq ($(CONFIG),Debug)" << newLine + << " LOCAL_CFLAGS +=" << createPreprocessorDefs (true) << newLine + << "else" << newLine + << " LOCAL_CFLAGS +=" << createPreprocessorDefs (false) << newLine + << "endif" << newLine + << newLine + << "include $(BUILD_SHARED_LIBRARY)" << newLine; + } + + const String createPreprocessorDefs (bool forDebug) + { + StringPairArray defines; + defines.set ("JUCE_ANDROID", "1"); + + if (forDebug) + { + defines.set ("DEBUG", "1"); + defines.set ("_DEBUG", "1"); + } + else + { + defines.set ("NDEBUG", "1"); + } + + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration(i)); + + if (config.isDebug() == forDebug) + { + defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); + break; + } + } + + return createGCCPreprocessorFlags (defines); + } + + //============================================================================== + XmlElement* createAntBuildXML() + { + XmlElement* proj = new XmlElement ("project"); + proj->setAttribute ("name", project.getProjectName().toString()); + proj->setAttribute ("default", "help"); + + proj->createNewChildElement ("property")->setAttribute ("file", "local.properties"); + proj->createNewChildElement ("property")->setAttribute ("file", "build.properties"); + proj->createNewChildElement ("property")->setAttribute ("file", "default.properties"); + + XmlElement* path = proj->createNewChildElement ("path"); + path->setAttribute ("id", "android.antlibs"); + path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/anttasks.jar"); + path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/sdklib.jar"); + path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/androidprefs.jar"); + + XmlElement* taskdef = proj->createNewChildElement ("taskdef"); + taskdef->setAttribute ("name", "setup"); + taskdef->setAttribute ("classname", "com.android.ant.SetupTask"); + taskdef->setAttribute ("classpathref", "android.antlibs"); + + addNDKBuildStep (proj, "clean", "clean"); + + //addLinkStep (proj, "${basedir}/" + rebaseFromProjectFolderToBuildTarget (RelativePath()).toUnixStyle() + "/", "jni/app"); + addLinkStep (proj, "${basedir}/" + getJucePathFromTargetFolder().toUnixStyle() + "/src/native/android/java/", "src/com/juce"); + + addNDKBuildStep (proj, "debug", "CONFIG=Debug"); + addNDKBuildStep (proj, "release", "CONFIG=Release"); + + proj->createNewChildElement ("setup"); + + return proj; + } + + static void addNDKBuildStep (XmlElement* project, const String& type, const String& arg) + { + XmlElement* target = project->createNewChildElement ("target"); + target->setAttribute ("name", type); + + XmlElement* executable = target->createNewChildElement ("exec"); + executable->setAttribute ("executable", "${ndk.dir}/ndk-build"); + executable->setAttribute ("dir", "${basedir}"); + executable->setAttribute ("failonerror", "true"); + + executable->createNewChildElement ("arg")->setAttribute ("value", arg); + } + + static void addLinkStep (XmlElement* project, const String& from, const String& to) + { + XmlElement* executable = project->createNewChildElement ("exec"); + executable->setAttribute ("executable", "ln"); + executable->setAttribute ("dir", "${basedir}"); + executable->setAttribute ("failonerror", "false"); + + executable->createNewChildElement ("arg")->setAttribute ("value", "-s"); + executable->createNewChildElement ("arg")->setAttribute ("value", from); + executable->createNewChildElement ("arg")->setAttribute ("value", to); + } + + void writeBuildPropertiesFile (const File& file) + { + MemoryOutputStream mo; + mo << "# This file is used to override default values used by the Ant build system." << newLine; + overwriteFileIfDifferentOrThrow (file, mo); + } + + void writeDefaultPropertiesFile (const File& file) + { + MemoryOutputStream mo; + mo << "# This file is used to override default values used by the Ant build system." << newLine + << "# It is automatically generated - DO NOT EDIT IT or your changes will be lost!." << newLine + << newLine + << "target=android-9" + << newLine; + + overwriteFileIfDifferentOrThrow (file, mo); + } + + void writeLocalPropertiesFile (const File& file) + { + MemoryOutputStream mo; + mo << "# This file is used to override default values used by the Ant build system." << newLine + << "# It is automatically generated by the Jucer - DO NOT EDIT IT or your changes will be lost!." << newLine + << newLine + << "sdk.dir=" << escapeSpaces (replacePreprocessorDefs (getAllPreprocessorDefs(), getSDKPath().toString())) << newLine + << "ndk.dir=" << escapeSpaces (replacePreprocessorDefs (getAllPreprocessorDefs(), getNDKPath().toString())) << newLine + << newLine; + + overwriteFileIfDifferentOrThrow (file, mo); + } + + void writeIcon (const File& file, int size) + { + Image im (project.getBestIconForSize (size, false)); + + if (im.isValid()) + { + PNGImageFormat png; + MemoryOutputStream mo; + + if (! png.writeImageToStream (im, mo)) + throw SaveError ("Can't generate Android icon file"); + + overwriteFileIfDifferentOrThrow (file, mo); + } + } + + void writeStringsFile (const File& file) + { + XmlElement strings ("resources"); + XmlElement* name = strings.createNewChildElement ("string"); + name->setAttribute ("name", "app_name"); + name->addTextElement (project.getProjectName().toString()); + + writeXmlOrThrow (strings, file, "utf-8", 100); + } + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE (AndroidProjectExporter); +}; + + +#endif // __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h index 169acdc843..cc5e54e292 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h @@ -377,59 +377,23 @@ protected: out << dataBlock; } - static const Image getBestIconImage (const Image& im1, const Image& im2, int size) - { - Image im; - - if (im1.isValid() && im2.isValid()) - { - if (im1.getWidth() >= size && im2.getWidth() >= size) - im = im1.getWidth() < im2.getWidth() ? im1 : im2; - else if (im1.getWidth() >= size) - im = im1; - else if (im2.getWidth() >= size) - im = im2; - else - return Image(); - } - else - { - im = im1.isValid() ? im1 : im2; - } - - if (size == im.getWidth() && size == im.getHeight()) - return im; - - if (im.getWidth() < size && im.getHeight() < size) - return Image(); - - Image newIm (Image::ARGB, size, size, true); - Graphics g (newIm); - g.drawImageWithin (im, 0, 0, size, size, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); - return newIm; - } - bool createIconFile() { Array images; - const Image smallIcon (project.getSmallIcon()); - const Image bigIcon (project.getBigIcon()); - - Image im (getBestIconImage (smallIcon, bigIcon, 16)); + Image im (project.getBestIconForSize (16, true)); if (im.isValid()) images.add (im); - im = getBestIconImage (smallIcon, bigIcon, 32); + im = project.getBestIconForSize (32, true); if (im.isValid()) images.add (im); - im = getBestIconImage (smallIcon, bigIcon, 48); + im = project.getBestIconForSize (48, true); if (im.isValid()) images.add (im); - im = getBestIconImage (smallIcon, bigIcon, 128); + im = project.getBestIconForSize (128, true); if (im.isValid()) images.add (im); @@ -485,7 +449,7 @@ public: } //============================================================================== - const String create() + void create() { createIconFile(); @@ -498,23 +462,15 @@ public: { XmlElement projectXml ("VisualStudioProject"); fillInProjectXml (projectXml); - - MemoryOutputStream mo; - projectXml.writeToStream (mo, String::empty, false, true, "UTF-8", 10); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) - return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); + writeXmlOrThrow (projectXml, getVCProjFile(), "UTF-8", 10); } { MemoryOutputStream mo; writeSolutionFile (mo, getSolutionVersionString(), getVCProjFile()); - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) - return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); + overwriteFileIfDifferentOrThrow (getSLNFile(), mo); } - - return String::empty; } protected: @@ -873,25 +829,19 @@ public: } //============================================================================== - const String create() + void create() { { MemoryOutputStream mo; writeProject (mo); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo)) - return "Can't write to the VC project file: " + getDSPFile().getFullPathName(); + overwriteFileIfDifferentOrThrow (getDSPFile(), mo); } { MemoryOutputStream mo; writeDSWFile (mo); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo)) - return "Can't write to the VC solution file: " + getDSWFile().getFullPathName(); + overwriteFileIfDifferentOrThrow (getDSWFile(), mo); } - - return String::empty; } private: @@ -1140,41 +1090,28 @@ public: } //============================================================================== - const String create() + void create() { createIconFile(); { XmlElement projectXml ("Project"); fillInProjectXml (projectXml); - - MemoryOutputStream mo; - projectXml.writeToStream (mo, String::empty, false, true, "utf-8", 100); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) - return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); + writeXmlOrThrow (projectXml, getVCProjFile(), "utf-8", 100); } { XmlElement filtersXml ("Project"); fillInFiltersXml (filtersXml); - - MemoryOutputStream mo; - filtersXml.writeToStream (mo, String::empty, false, true, "utf-8", 100); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFiltersFile(), mo)) - return "Can't write to the VC project file: " + getVCProjFiltersFile().getFullPathName(); + writeXmlOrThrow (filtersXml, getVCProjFiltersFile(), "utf-8", 100); } { MemoryOutputStream mo; writeSolutionFile (mo, "11.00", getVCProjFile()); - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) - return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); + overwriteFileIfDifferentOrThrow (getSLNFile(), mo); } - - return String::empty; } protected: diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Make.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Make.h index 582f74fc5c..790b43bf09 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Make.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_Make.h @@ -83,7 +83,7 @@ public: } //============================================================================== - const String create() + void create() { Array files; findAllFilesToCompile (project.getMainGroup(), files); @@ -99,11 +99,7 @@ public: MemoryOutputStream mo; writeMakefile (mo, files); - const File makefile (getTargetFolder().getChildFile ("Makefile")); - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (makefile, mo)) - return "Can't write to the Makefile: " + makefile.getFullPathName(); - - return String::empty; + overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo); } private: @@ -137,17 +133,7 @@ private: defines.set ("NDEBUG", "1"); } - defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); - - for (int i = 0; i < defines.size(); ++i) - { - String def (defines.getAllKeys()[i]); - const String value (defines.getAllValues()[i]); - if (value.isNotEmpty()) - def << "=" << value; - - out << " -D " << def.quoted(); - } + out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config))); } void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config) @@ -334,11 +320,6 @@ private: out << "-include $(OBJECTS:%.o=%.d)" << newLine; } - static const String escapeSpaces (const String& s) - { - return s.replace (" ", "\\ "); - } - const String getObjectFileFor (const RelativePath& file) const { return file.getFileNameWithoutExtension() diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h index 430b49581b..1d8bb91c7c 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_XCode.h @@ -106,16 +106,14 @@ public: } //============================================================================== - const String create() + void create() { infoPlistFile = getTargetFolder().getChildFile ("Info.plist"); - if (! createIconFile()) - return "Can't write the icon file"; + createIconFile(); File projectBundle (getProjectBundle()); - if (! projectBundle.createDirectory()) - return "Can't write to the target directory"; + createDirectoryOrThrow (projectBundle); createObjects(); @@ -124,15 +122,10 @@ public: { MemoryOutputStream mo; writeProjectFile (mo); - - if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo)) - return "Can't write to file: " + projectFile.getFullPathName(); + overwriteFileIfDifferentOrThrow (projectFile, mo); } - if (! writeInfoPlistFile()) - return "Can't write the Info.plist file"; - - return String::empty; + writeInfoPlistFile(); } private: @@ -303,7 +296,7 @@ private: out << data; } - bool createIconFile() + void createIconFile() { Array images; @@ -315,20 +308,20 @@ private: if (smallIcon.isValid()) images.add (smallIcon); - if (images.size() == 0) - return true; - - MemoryOutputStream mo; - writeIcnsFile (images, mo); + if (images.size() > 0) + { + MemoryOutputStream mo; + writeIcnsFile (images, mo); - iconFile = getTargetFolder().getChildFile ("Icon.icns"); - return FileHelpers::overwriteFileWithNewDataIfDifferent (iconFile, mo); + iconFile = getTargetFolder().getChildFile ("Icon.icns"); + overwriteFileIfDifferentOrThrow (iconFile, mo); + } } - bool writeInfoPlistFile() + void writeInfoPlistFile() { if (! hasPList()) - return true; + return; XmlElement plist ("plist"); XmlElement* dict = plist.createNewChildElement ("dict"); @@ -353,7 +346,7 @@ private: addPlistDictionaryKey (dict, "CFBundleVersion", project.getVersion().toString()); StringArray documentExtensions; - documentExtensions.addTokens (replacePreprocessorDefs (project.getPreprocessorDefs(), getSetting ("documentExtensions").toString()), + documentExtensions.addTokens (replacePreprocessorDefs (getAllPreprocessorDefs(), getSetting ("documentExtensions").toString()), ",", String::empty); documentExtensions.trim(); documentExtensions.removeEmptyStrings (true); @@ -380,7 +373,7 @@ private: MemoryOutputStream mo; plist.writeToStream (mo, ""); - return FileHelpers::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo); + overwriteFileIfDifferentOrThrow (infoPlistFile, mo); } const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.cpp b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.cpp index 0798663e07..ec07044633 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.cpp +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.cpp @@ -27,6 +27,7 @@ #include "jucer_ProjectExport_Make.h" #include "jucer_ProjectExport_MSVC.h" #include "jucer_ProjectExport_XCode.h" +#include "jucer_ProjectExport_Android.h" //============================================================================== @@ -55,6 +56,7 @@ const StringArray ProjectExporter::getExporterNames() s.add (MSVCProjectExporterVC2008::getName()); s.add (MSVCProjectExporterVC2010::getName()); s.add (MakefileProjectExporter::getNameLinux()); + //s.add (AndroidProjectExporter::getNameAndroid()); return s; } @@ -71,6 +73,7 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int case 4: exp = new MSVCProjectExporterVC2008 (project, ValueTree (MSVCProjectExporterVC2008::getValueTreeTypeName())); break; case 5: exp = new MSVCProjectExporterVC2010 (project, ValueTree (MSVCProjectExporterVC2010::getValueTreeTypeName())); break; case 6: exp = new MakefileProjectExporter (project, ValueTree (MakefileProjectExporter::getValueTreeTypeName())); break; + case 7: exp = new AndroidProjectExporter (project, ValueTree (AndroidProjectExporter::getValueTreeTypeName())); break; default: jassertfalse; return 0; } @@ -93,6 +96,7 @@ ProjectExporter* ProjectExporter::createExporter (Project& project, const ValueT if (exp == 0) exp = MSVCProjectExporterVC2010::createForSettings (project, settings); if (exp == 0) exp = XCodeProjectExporter::createForSettings (project, settings); if (exp == 0) exp = MakefileProjectExporter::createForSettings (project, settings); + if (exp == 0) exp = AndroidProjectExporter::createForSettings (project, settings); jassert (exp != 0); return exp; @@ -208,6 +212,14 @@ const StringPairArray ProjectExporter::getAllPreprocessorDefs (const Project::Bu return defs; } +const StringPairArray ProjectExporter::getAllPreprocessorDefs() const +{ + StringPairArray defs (mergePreprocessorDefs (project.getPreprocessorDefs(), + parsePreprocessorDefs (getExporterPreprocessorDefs().toString()))); + defs.set (getExporterIdentifierMacro(), "1"); + return defs; +} + const String ProjectExporter::replacePreprocessorTokens (const Project::BuildConfiguration& config, const String& sourceString) const { return replacePreprocessorDefs (getAllPreprocessorDefs (config), sourceString); diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.h index 914ad97e9f..18aa40b4da 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExporter.h @@ -53,7 +53,7 @@ public: virtual bool usesMMFiles() const = 0; virtual void createPropertyEditors (Array & props); virtual void launchProject() = 0; - virtual const String create() = 0; + virtual void create() = 0; // may throw a SaveError virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const; //============================================================================== @@ -78,7 +78,11 @@ public: Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); } Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } - const StringPairArray getAllPreprocessorDefs (const Project::BuildConfiguration& config) const; // includes inherited ones.. + + // includes exporter, project + config defs + const StringPairArray getAllPreprocessorDefs (const Project::BuildConfiguration& config) const; + // includes exporter + project defs.. + const StringPairArray getAllPreprocessorDefs() const; const String replacePreprocessorTokens (const Project::BuildConfiguration& config, const String& sourceString) const; @@ -95,6 +99,20 @@ public: Array juceWrapperFiles; RelativePath juceWrapperFolder; + // An exception that can be thrown by the create() method. + class SaveError + { + public: + SaveError (const String& error) : message (error) + {} + + SaveError (const File& fileThatFailedToWrite) + : message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName()) + {} + + String message; + }; + protected: //============================================================================== Project& project; @@ -103,7 +121,7 @@ protected: const RelativePath getJucePathFromTargetFolder() const; - const String getDefaultBuildsRootFolder() const { return "Builds/"; } + static const String getDefaultBuildsRootFolder() { return "Builds/"; } const Array getVSTFilesRequired() const; @@ -118,6 +136,26 @@ protected: const RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const; + //============================================================================== + static void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData) + { + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (file, newData)) + throw SaveError (file); + } + + static void createDirectoryOrThrow (const File& dirToCreate) + { + if (! dirToCreate.createDirectory()) + throw SaveError ("Can't create folder: " + dirToCreate.getFullPathName()); + } + + static void writeXmlOrThrow (const XmlElement& xml, const File& file, const String& encoding, int maxCharsPerLine) + { + MemoryOutputStream mo; + xml.writeToStream (mo, String::empty, false, true, encoding, maxCharsPerLine); + overwriteFileIfDifferentOrThrow (file, mo); + } + private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter); }; diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectSaver.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectSaver.h index 2148a7edc1..0fde6082e9 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectSaver.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectSaver.h @@ -515,10 +515,14 @@ private: if (project.isAudioPlugin()) exporter->juceWrapperFiles.add (RelativePath (pluginCharacteristicsFile, targetFolder, RelativePath::buildTargetFolder)); - String error = exporter->create(); - - if (error.isNotEmpty()) - errors.add (error); + try + { + exporter->create(); + } + catch (ProjectExporter::SaveError& error) + { + errors.add (error.message); + } } else { diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp index c9cfbd0e02..70833cbd04 100644 --- a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp +++ b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp @@ -77,46 +77,45 @@ const String createGUID (const String& seed) return guid; } -//============================================================================== -static void skipWhitespace (const String& s, int& i) +const String escapeSpaces (const String& s) { - while (CharacterFunctions::isWhitespace (s[i])) - ++i; + return s.replace (" ", "\\ "); } -const StringPairArray parsePreprocessorDefs (const String& s) +//============================================================================== +const StringPairArray parsePreprocessorDefs (const String& text) { StringPairArray result; - int i = 0; + String::CharPointerType s (text.getCharPointer()); - while (s[i] != 0) + while (! s.isEmpty()) { String token, value; - skipWhitespace (s, i); + s = s.findEndOfWhitespace(); - while (s[i] != 0 && s[i] != '=' && ! CharacterFunctions::isWhitespace (s[i])) - token << s[i++]; + while ((! s.isEmpty()) && *s != '=' && ! s.isWhitespace()) + token << s.getAndAdvance(); - skipWhitespace (s, i); + s = s.findEndOfWhitespace(); - if (s[i] == '=') + if (*s == '=') { - ++i; + ++s; - skipWhitespace (s, i); + s = s.findEndOfWhitespace(); - while (s[i] != 0 && ! CharacterFunctions::isWhitespace (s[i])) + while ((! s.isEmpty()) && ! s.isWhitespace()) { - if (s[i] == ',') + if (*s == ',') { - ++i; + ++s; break; } - if (s[i] == '\\' && (s[i + 1] == ' ' || s[i + 1] == ',')) - ++i; + if (*s == '\\' && (s[1] == ' ' || s[1] == ',')) + ++s; - value << s[i++]; + value << s.getAndAdvance(); } } @@ -135,6 +134,23 @@ const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, cons return inheritedDefs; } +const String createGCCPreprocessorFlags (const StringPairArray& defs) +{ + String s; + + for (int i = 0; i < defs.size(); ++i) + { + String def (defs.getAllKeys()[i]); + const String value (defs.getAllValues()[i]); + if (value.isNotEmpty()) + def << "=" << value; + + s += " -D " + def.quoted(); + } + + return s; +} + const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString) { for (int i = 0; i < definitions.size(); ++i) diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h index 9fb70e2afb..437b7096f3 100644 --- a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h +++ b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h @@ -33,8 +33,11 @@ const String hexString8Digits (int value); const String createAlphaNumericUID(); const String createGUID (const String& seed); // Turns a seed into a windows GUID +const String escapeSpaces (const String& text); // replaces spaces with blackslash-space + const StringPairArray parsePreprocessorDefs (const String& defs); const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs); +const String createGCCPreprocessorFlags (const StringPairArray& defs); const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString); //============================================================================== diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h b/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h index 8976eac34c..29ad3db4c1 100644 --- a/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h +++ b/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h @@ -113,6 +113,8 @@ namespace Ids DECLARE_ID (memberName); DECLARE_ID (focusOrder); DECLARE_ID (hidden); + DECLARE_ID (androidSDKPath); + DECLARE_ID (androidNDKPath); const Identifier class_ ("class"); const Identifier id_ ("id"); diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index dcbc262c37..b13f4fb855 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -776,6 +776,7 @@ protected: #include #include #include +#include #include /* Got a build error here? You'll need to install the freetype library... @@ -2202,6 +2203,16 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() static_jassert (sizeof (uint32) == 4); static_jassert (sizeof (int64) == 8); static_jassert (sizeof (uint64) == 8); + + #if JUCE_NATIVE_WCHAR_IS_UTF8 + static_jassert (sizeof (wchar_t) == 1); + #elif JUCE_NATIVE_WCHAR_IS_UTF16 + static_jassert (sizeof (wchar_t) == 2); + #elif JUCE_NATIVE_WCHAR_IS_UTF32 + static_jassert (sizeof (wchar_t) == 4); + #else + #error "native wchar_t size is unknown" + #endif } JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() @@ -11142,14 +11153,14 @@ int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID + return (int) wcsftime (dest, maxChars, format, tm); + #else HeapBlock tempDest; tempDest.calloc (maxChars + 2); int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); return result; - #else - return (int) wcsftime (dest, maxChars, format, tm); #endif } @@ -11334,6 +11345,14 @@ BEGIN_JUCE_NAMESPACE #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." #endif +#if JUCE_NATIVE_WCHAR_IS_UTF8 + typedef CharPointer_UTF8 CharPointer_wchar_t; +#elif JUCE_NATIVE_WCHAR_IS_UTF16 + typedef CharPointer_UTF16 CharPointer_wchar_t; +#else + typedef CharPointer_UTF32 CharPointer_wchar_t; +#endif + NewLine newLine; class StringHolder @@ -11550,7 +11569,7 @@ String::String (const char* const t) because there's no other way to represent these strings in a way that isn't dependent on the compiler, source code editor and platform. */ - jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits::max())); + jassert (t == 0 || CharPointer_ASCII::isValidString (t, std::numeric_limits::max())); } String::String (const char* const t, const size_t maxChars) @@ -11569,7 +11588,7 @@ String::String (const char* const t, const size_t maxChars) because there's no other way to represent these strings in a way that isn't dependent on the compiler, source code editor and platform. */ - jassert (CharPointer_ASCII::isValidString (t, (int) maxChars)); + jassert (t == 0 || CharPointer_ASCII::isValidString (t, (int) maxChars)); } String::String (const juce_wchar* const t) @@ -11607,14 +11626,16 @@ String::String (const CharPointer_ASCII& t) { } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 String::String (const wchar_t* const t) - : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) + : text (StringHolder::createFromCharPointer + (CharPointer_wchar_t (reinterpret_cast (t)))) { } String::String (const wchar_t* const t, size_t maxChars) - : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t), maxChars)) + : text (StringHolder::createFromCharPointer + (CharPointer_wchar_t (reinterpret_cast (t)), maxChars)) { } #endif @@ -11997,7 +12018,7 @@ String& String::operator+= (const juce_wchar ch) return operator+= (static_cast (asString)); } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 String& String::operator+= (const wchar_t ch) { return operator+= ((juce_wchar) ch); @@ -12065,7 +12086,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar return string1 += string2; } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) { return string1 += string2; @@ -12073,7 +12094,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) { - string1.appendCharPointer (CharPointer_UTF16 (string2)); + string1.appendCharPointer (CharPointer_wchar_t (reinterpret_cast (string2))); return string1; } @@ -13383,9 +13404,7 @@ const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) const char* String::toCString() const { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return toUTF8(); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID if (isEmpty()) return reinterpret_cast (text.getAddress()); @@ -13394,29 +13413,31 @@ const char* String::toCString() const wcstombs (extraSpace, text, len); extraSpace [len] = 0; return extraSpace; + #else + return toUTF8(); #endif } int String::getNumBytesAsCString() const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return getNumBytesAsUTF8(); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID return (int) wcstombs (0, text, 0); + #else + return getNumBytesAsUTF8(); #endif } int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return copyToUTF8 (destBuffer, maxBufferSizeBytes); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); if (destBuffer != 0 && numBytes >= 0) destBuffer [numBytes] = 0; return numBytes; + #else + return copyToUTF8 (destBuffer, maxBufferSizeBytes); #endif } @@ -253997,8 +254018,13 @@ void Thread::killThread() } } -void Thread::setCurrentThreadName (const String& /*name*/) +void Thread::setCurrentThreadName (const String& name) { + #if JUCE_MAC + pthread_setname_np (name.toUTF8()); + #elif JUCE_LINUX + prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); + #endif } bool Thread::setThreadPriority (void* handle, int priority) @@ -263904,8 +263930,13 @@ void Thread::killThread() } } -void Thread::setCurrentThreadName (const String& /*name*/) +void Thread::setCurrentThreadName (const String& name) { + #if JUCE_MAC + pthread_setname_np (name.toUTF8()); + #elif JUCE_LINUX + prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); + #endif } bool Thread::setThreadPriority (void* handle, int priority) @@ -267538,6 +267569,8 @@ END_JUCE_NAMESPACE - (bool) makeActive; - (void) makeInactive; - (void) reshape; +- (void) rightMouseDown: (NSEvent*) ev; +- (void) rightMouseUp: (NSEvent*) ev; @end @implementation ThreadSafeNSOpenGLView @@ -267606,6 +267639,16 @@ END_JUCE_NAMESPACE needsUpdate = true; } +- (void) rightMouseDown: (NSEvent*) ev +{ + [[self superview] rightMouseDown: ev]; +} + +- (void) rightMouseUp: (NSEvent*) ev +{ + [[self superview] rightMouseUp: ev]; +} + @end BEGIN_JUCE_NAMESPACE @@ -273176,6 +273219,8 @@ END_JUCE_NAMESPACE - (bool) makeActive; - (void) makeInactive; - (void) reshape; +- (void) rightMouseDown: (NSEvent*) ev; +- (void) rightMouseUp: (NSEvent*) ev; @end @implementation ThreadSafeNSOpenGLView @@ -273244,6 +273289,16 @@ END_JUCE_NAMESPACE needsUpdate = true; } +- (void) rightMouseDown: (NSEvent*) ev +{ + [[self superview] rightMouseDown: ev]; +} + +- (void) rightMouseUp: (NSEvent*) ev +{ + [[self superview] rightMouseUp: ev]; +} + @end BEGIN_JUCE_NAMESPACE @@ -278567,7 +278622,6 @@ public: inline operator jobject() const throw() { return obj; } inline jobject get() const throw() { return obj; } - inline JNIEnv* getEnv() const throw() { return env; } #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ @@ -278601,6 +278655,7 @@ public: } private: + JNIEnv* env; jobject obj; @@ -279595,8 +279650,13 @@ void Thread::killThread() } } -void Thread::setCurrentThreadName (const String& /*name*/) +void Thread::setCurrentThreadName (const String& name) { + #if JUCE_MAC + pthread_setname_np (name.toUTF8()); + #elif JUCE_LINUX + prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); + #endif } bool Thread::setThreadPriority (void* handle, int priority) diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 131e5a5bd4..eb63af9d46 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 25 +#define JUCE_BUILDNUMBER 26 /** Current Juce version number. @@ -1636,25 +1636,35 @@ inline void ByteOrder::bigEndian24BitToChars (const int value, char* const destB #ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ #define __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ -#if JUCE_ANDROID && ! DOXYGEN - typedef uint32 juce_wchar; - #define JUCE_T(stringLiteral) CharPointer_UTF8 (stringLiteral) - #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 -#elif JUCE_WINDOWS && ! DOXYGEN - typedef uint32 juce_wchar; - #define JUCE_T(stringLiteral) L##stringLiteral - #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 +#if JUCE_WINDOWS && ! DOXYGEN + #define JUCE_NATIVE_WCHAR_IS_UTF8 0 + #define JUCE_NATIVE_WCHAR_IS_UTF16 1 + #define JUCE_NATIVE_WCHAR_IS_UTF32 0 #else - /** A platform-independent unicode character type. */ - typedef wchar_t juce_wchar; - #define JUCE_T(stringLiteral) (L##stringLiteral) + /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF8 0 + /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF16 0 + /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF32 1 #endif +#if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN + /** A platform-independent 32-bit unicode character type. */ + typedef wchar_t juce_wchar; +#else + typedef uint32 juce_wchar; +#endif + +/** This macro is deprecated, but preserved for compatibility with old code.*/ +#define JUCE_T(stringLiteral) (L##stringLiteral) + #if ! JUCE_DONT_DEFINE_MACROS - /** The 'T' macro allows a literal string to be compiled as unicode. + /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal. - If you write your string literals in the form T("xyz"), it will be compiled as L"xyz" - or "xyz", depending on which representation is best for the String class to work with. + This macro is deprectated, but kept here for compatibility with old code. The best (i.e. + most portable) way to encode your string literals is just as standard 8-bit strings, but + using escaped utf-8 character codes for extended characters. Because the 'T' symbol is occasionally used inside 3rd-party library headers which you may need to include after juce.h, you can use the juce_withoutMacros.h file (in @@ -2332,7 +2342,7 @@ inline Type Atomic::operator+= (const Type amountToAdd) throw() for (;;) { const Type oldValue (value); - const Type newValue (oldValue + amountToAdd); + const Type newValue (castFrom32Bit (castTo32Bit (oldValue) + castTo32Bit (amountToAdd))); if (compareAndSetBool (newValue, oldValue)) return newValue; } @@ -2357,7 +2367,7 @@ inline Type Atomic::operator++() throw() return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); #elif JUCE_ANDROID - return (Type) __atomic_inc (&value); + return (Type) __atomic_inc ((volatile int*) &value); #elif JUCE_ATOMICS_GCC return (Type) __sync_add_and_fetch (&value, 1); #endif @@ -2373,7 +2383,7 @@ inline Type Atomic::operator--() throw() return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); #elif JUCE_ANDROID - return (Type) __atomic_dec (&value); + return (Type) __atomic_dec ((volatile int*) &value); #elif JUCE_ATOMICS_GCC return (Type) __sync_add_and_fetch (&value, -1); #endif @@ -2961,7 +2971,7 @@ private: class CharPointer_UTF16 { public: - #if JUCE_WINDOWS && ! DOXYGEN + #if JUCE_NATIVE_WCHAR_IS_UTF16 typedef wchar_t CharType; #else typedef int16 CharType; @@ -3519,13 +3529,13 @@ public: /** Returns the number of characters in this string. */ size_t length() const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID + return wcslen (data); + #else size_t n = 0; while (data[n] != 0) ++n; return n; - #else - return wcslen (data); #endif } @@ -3613,7 +3623,7 @@ public: return CharacterFunctions::compare (*this, other); } - #if ! JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID /** Compares this string with another one. */ int compare (const CharPointer_UTF32& other) const throw() { @@ -4175,7 +4185,7 @@ public: /** Creates a string from an ASCII character string */ String (const CharPointer_ASCII& text); - #if JUCE_WINDOWS + #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Creates a string from a UTF-16 character string */ String (const wchar_t* text); @@ -4221,7 +4231,7 @@ public: String& operator+= (char characterToAppend); /** Appends a character at the end of this string. */ String& operator+= (juce_wchar characterToAppend); - #if JUCE_WINDOWS + #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Appends a character at the end of this string. */ String& operator+= (wchar_t characterToAppend); /** Appends another string at the end of this one. */ @@ -5242,7 +5252,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); /** Concatenates two strings. */ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Concatenates two strings. */ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); /** Concatenates two strings. */ @@ -12535,7 +12545,8 @@ public: /** Sets the text in a text element. Note that this is only a valid call if this element is a text element. If it's - not, then no action will be performed. + not, then no action will be performed. If you're trying to add text inside a normal + element, you probably want to use addTextElement() instead. */ void setText (const String& newText); @@ -35101,7 +35112,8 @@ protected: typedef AudioData::Pointer DestType; typedef AudioData::Pointer SourceType; - static void write (void* destData, int numDestChannels, const int** source, int numSamples) throw() + static void write (void* destData, int numDestChannels, const int** source, + int numSamples, const int sourceOffset = 0) throw() { for (int i = 0; i < numDestChannels; ++i) { @@ -35109,7 +35121,7 @@ protected: if (*source != 0) { - dest.convertSamples (SourceType (*source), numSamples); + dest.convertSamples (SourceType (*source + sourceOffset), numSamples); ++source; } else diff --git a/src/audio/audio_file_formats/juce_AudioFormatWriter.h b/src/audio/audio_file_formats/juce_AudioFormatWriter.h index f9c5555343..87dc6184db 100644 --- a/src/audio/audio_file_formats/juce_AudioFormatWriter.h +++ b/src/audio/audio_file_formats/juce_AudioFormatWriter.h @@ -224,7 +224,8 @@ protected: typedef AudioData::Pointer DestType; typedef AudioData::Pointer SourceType; - static void write (void* destData, int numDestChannels, const int** source, int numSamples) throw() + static void write (void* destData, int numDestChannels, const int** source, + int numSamples, const int sourceOffset = 0) throw() { for (int i = 0; i < numDestChannels; ++i) { @@ -232,7 +233,7 @@ protected: if (*source != 0) { - dest.convertSamples (SourceType (*source), numSamples); + dest.convertSamples (SourceType (*source + sourceOffset), numSamples); ++source; } else diff --git a/src/core/juce_Initialisation.cpp b/src/core/juce_Initialisation.cpp index 93c574ea50..0ff27436f1 100644 --- a/src/core/juce_Initialisation.cpp +++ b/src/core/juce_Initialisation.cpp @@ -78,6 +78,16 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() static_jassert (sizeof (uint32) == 4); static_jassert (sizeof (int64) == 8); static_jassert (sizeof (uint64) == 8); + + #if JUCE_NATIVE_WCHAR_IS_UTF8 + static_jassert (sizeof (wchar_t) == 1); + #elif JUCE_NATIVE_WCHAR_IS_UTF16 + static_jassert (sizeof (wchar_t) == 2); + #elif JUCE_NATIVE_WCHAR_IS_UTF32 + static_jassert (sizeof (wchar_t) == 4); + #else + #error "native wchar_t size is unknown" + #endif } JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 7a43ba3425..99a2f24be4 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 25 +#define JUCE_BUILDNUMBER 26 /** Current Juce version number. diff --git a/src/memory/juce_Atomic.h b/src/memory/juce_Atomic.h index cb5b0969f6..db0f47c4f6 100644 --- a/src/memory/juce_Atomic.h +++ b/src/memory/juce_Atomic.h @@ -280,7 +280,7 @@ inline Type Atomic::operator+= (const Type amountToAdd) throw() for (;;) { const Type oldValue (value); - const Type newValue (oldValue + amountToAdd); + const Type newValue (castFrom32Bit (castTo32Bit (oldValue) + castTo32Bit (amountToAdd))); if (compareAndSetBool (newValue, oldValue)) return newValue; } @@ -305,7 +305,7 @@ inline Type Atomic::operator++() throw() return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); #elif JUCE_ANDROID - return (Type) __atomic_inc (&value); + return (Type) __atomic_inc ((volatile int*) &value); #elif JUCE_ATOMICS_GCC return (Type) __sync_add_and_fetch (&value, 1); #endif @@ -321,7 +321,7 @@ inline Type Atomic::operator--() throw() return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); #elif JUCE_ANDROID - return (Type) __atomic_dec (&value); + return (Type) __atomic_dec ((volatile int*) &value); #elif JUCE_ATOMICS_GCC return (Type) __sync_add_and_fetch (&value, -1); #endif diff --git a/src/native/android/juce_android_NativeCode.cpp b/src/native/android/juce_android_NativeCode.cpp index d1964809ea..2274cf79b4 100644 --- a/src/native/android/juce_android_NativeCode.cpp +++ b/src/native/android/juce_android_NativeCode.cpp @@ -166,11 +166,12 @@ public: } } + //============================================================================== inline operator jobject() const throw() { return obj; } inline jobject get() const throw() { return obj; } - inline JNIEnv* getEnv() const throw() { return env; } + //============================================================================== #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ returnType call##typeName##Method (jmethodID methodID, ... ) \ { \ @@ -202,6 +203,7 @@ public: } private: + //============================================================================== JNIEnv* env; jobject obj; diff --git a/src/native/common/juce_posix_SharedCode.h b/src/native/common/juce_posix_SharedCode.h index 5823fce07a..caf6a0f24d 100644 --- a/src/native/common/juce_posix_SharedCode.h +++ b/src/native/common/juce_posix_SharedCode.h @@ -742,8 +742,13 @@ void Thread::killThread() } } -void Thread::setCurrentThreadName (const String& /*name*/) +void Thread::setCurrentThreadName (const String& name) { + #if JUCE_MAC + pthread_setname_np (name.toUTF8()); + #elif JUCE_LINUX + prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); + #endif } bool Thread::setThreadPriority (void* handle, int priority) diff --git a/src/native/linux/juce_linux_NativeIncludes.h b/src/native/linux/juce_linux_NativeIncludes.h index 1d0e38ec76..abb4745a13 100644 --- a/src/native/linux/juce_linux_NativeIncludes.h +++ b/src/native/linux/juce_linux_NativeIncludes.h @@ -56,6 +56,7 @@ #include #include #include +#include #include /* Got a build error here? You'll need to install the freetype library... diff --git a/src/native/mac/juce_mac_OpenGLComponent.mm b/src/native/mac/juce_mac_OpenGLComponent.mm index 848a4dbc9d..f5d9069f7a 100644 --- a/src/native/mac/juce_mac_OpenGLComponent.mm +++ b/src/native/mac/juce_mac_OpenGLComponent.mm @@ -44,6 +44,8 @@ END_JUCE_NAMESPACE - (bool) makeActive; - (void) makeInactive; - (void) reshape; +- (void) rightMouseDown: (NSEvent*) ev; +- (void) rightMouseUp: (NSEvent*) ev; @end @implementation ThreadSafeNSOpenGLView @@ -112,6 +114,16 @@ END_JUCE_NAMESPACE needsUpdate = true; } +- (void) rightMouseDown: (NSEvent*) ev +{ + [[self superview] rightMouseDown: ev]; +} + +- (void) rightMouseUp: (NSEvent*) ev +{ + [[self superview] rightMouseUp: ev]; +} + @end BEGIN_JUCE_NAMESPACE diff --git a/src/text/juce_CharPointer_UTF16.h b/src/text/juce_CharPointer_UTF16.h index fbba22c72f..3b82c2cb64 100644 --- a/src/text/juce_CharPointer_UTF16.h +++ b/src/text/juce_CharPointer_UTF16.h @@ -36,7 +36,7 @@ class CharPointer_UTF16 { public: - #if JUCE_WINDOWS && ! DOXYGEN + #if JUCE_NATIVE_WCHAR_IS_UTF16 typedef wchar_t CharType; #else typedef int16 CharType; diff --git a/src/text/juce_CharPointer_UTF32.h b/src/text/juce_CharPointer_UTF32.h index a6872e89a7..ca02c277a2 100644 --- a/src/text/juce_CharPointer_UTF32.h +++ b/src/text/juce_CharPointer_UTF32.h @@ -159,13 +159,13 @@ public: /** Returns the number of characters in this string. */ size_t length() const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID + return wcslen (data); + #else size_t n = 0; while (data[n] != 0) ++n; return n; - #else - return wcslen (data); #endif } @@ -253,7 +253,7 @@ public: return CharacterFunctions::compare (*this, other); } - #if ! JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID /** Compares this string with another one. */ int compare (const CharPointer_UTF32& other) const throw() { diff --git a/src/text/juce_CharacterFunctions.cpp b/src/text/juce_CharacterFunctions.cpp index cdab05eea4..1ff37c63b7 100644 --- a/src/text/juce_CharacterFunctions.cpp +++ b/src/text/juce_CharacterFunctions.cpp @@ -139,14 +139,14 @@ int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID + return (int) wcsftime (dest, maxChars, format, tm); + #else HeapBlock tempDest; tempDest.calloc (maxChars + 2); int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); return result; - #else - return (int) wcsftime (dest, maxChars, format, tm); #endif } diff --git a/src/text/juce_CharacterFunctions.h b/src/text/juce_CharacterFunctions.h index f456520234..f713fc12e4 100644 --- a/src/text/juce_CharacterFunctions.h +++ b/src/text/juce_CharacterFunctions.h @@ -28,25 +28,35 @@ //============================================================================== -#if JUCE_ANDROID && ! DOXYGEN - typedef uint32 juce_wchar; - #define JUCE_T(stringLiteral) CharPointer_UTF8 (stringLiteral) - #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 -#elif JUCE_WINDOWS && ! DOXYGEN - typedef uint32 juce_wchar; - #define JUCE_T(stringLiteral) L##stringLiteral - #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 +#if JUCE_WINDOWS && ! DOXYGEN + #define JUCE_NATIVE_WCHAR_IS_UTF8 0 + #define JUCE_NATIVE_WCHAR_IS_UTF16 1 + #define JUCE_NATIVE_WCHAR_IS_UTF32 0 #else - /** A platform-independent unicode character type. */ - typedef wchar_t juce_wchar; - #define JUCE_T(stringLiteral) (L##stringLiteral) + /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF8 0 + /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF16 0 + /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */ + #define JUCE_NATIVE_WCHAR_IS_UTF32 1 #endif +#if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN + /** A platform-independent 32-bit unicode character type. */ + typedef wchar_t juce_wchar; +#else + typedef uint32 juce_wchar; +#endif + +/** This macro is deprecated, but preserved for compatibility with old code.*/ +#define JUCE_T(stringLiteral) (L##stringLiteral) + #if ! JUCE_DONT_DEFINE_MACROS - /** The 'T' macro allows a literal string to be compiled as unicode. + /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal. - If you write your string literals in the form T("xyz"), it will be compiled as L"xyz" - or "xyz", depending on which representation is best for the String class to work with. + This macro is deprectated, but kept here for compatibility with old code. The best (i.e. + most portable) way to encode your string literals is just as standard 8-bit strings, but + using escaped utf-8 character codes for extended characters. Because the 'T' symbol is occasionally used inside 3rd-party library headers which you may need to include after juce.h, you can use the juce_withoutMacros.h file (in diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index b06bf11984..7d637dbf98 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -42,6 +42,14 @@ BEGIN_JUCE_NAMESPACE #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." #endif +#if JUCE_NATIVE_WCHAR_IS_UTF8 + typedef CharPointer_UTF8 CharPointer_wchar_t; +#elif JUCE_NATIVE_WCHAR_IS_UTF16 + typedef CharPointer_UTF16 CharPointer_wchar_t; +#else + typedef CharPointer_UTF32 CharPointer_wchar_t; +#endif + NewLine newLine; //============================================================================== @@ -265,7 +273,7 @@ String::String (const char* const t) because there's no other way to represent these strings in a way that isn't dependent on the compiler, source code editor and platform. */ - jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits::max())); + jassert (t == 0 || CharPointer_ASCII::isValidString (t, std::numeric_limits::max())); } String::String (const char* const t, const size_t maxChars) @@ -284,7 +292,7 @@ String::String (const char* const t, const size_t maxChars) because there's no other way to represent these strings in a way that isn't dependent on the compiler, source code editor and platform. */ - jassert (CharPointer_ASCII::isValidString (t, (int) maxChars)); + jassert (t == 0 || CharPointer_ASCII::isValidString (t, (int) maxChars)); } String::String (const juce_wchar* const t) @@ -322,14 +330,16 @@ String::String (const CharPointer_ASCII& t) { } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 String::String (const wchar_t* const t) - : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) + : text (StringHolder::createFromCharPointer + (CharPointer_wchar_t (reinterpret_cast (t)))) { } String::String (const wchar_t* const t, size_t maxChars) - : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t), maxChars)) + : text (StringHolder::createFromCharPointer + (CharPointer_wchar_t (reinterpret_cast (t)), maxChars)) { } #endif @@ -717,7 +727,7 @@ String& String::operator+= (const juce_wchar ch) return operator+= (static_cast (asString)); } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 String& String::operator+= (const wchar_t ch) { return operator+= ((juce_wchar) ch); @@ -786,7 +796,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar return string1 += string2; } -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) { return string1 += string2; @@ -794,7 +804,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) { - string1.appendCharPointer (CharPointer_UTF16 (string2)); + string1.appendCharPointer (CharPointer_wchar_t (reinterpret_cast (string2))); return string1; } @@ -2117,9 +2127,7 @@ const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) //============================================================================== const char* String::toCString() const { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return toUTF8(); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID if (isEmpty()) return reinterpret_cast (text.getAddress()); @@ -2128,29 +2136,31 @@ const char* String::toCString() const wcstombs (extraSpace, text, len); extraSpace [len] = 0; return extraSpace; + #else + return toUTF8(); #endif } int String::getNumBytesAsCString() const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return getNumBytesAsUTF8(); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID return (int) wcstombs (0, text, 0); + #else + return getNumBytesAsUTF8(); #endif } int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() { - #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 - return copyToUTF8 (destBuffer, maxBufferSizeBytes); - #else + #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); if (destBuffer != 0 && numBytes >= 0) destBuffer [numBytes] = 0; return numBytes; + #else + return copyToUTF8 (destBuffer, maxBufferSizeBytes); #endif } diff --git a/src/text/juce_String.h b/src/text/juce_String.h index 00a06ac02f..61d41fc989 100644 --- a/src/text/juce_String.h +++ b/src/text/juce_String.h @@ -126,7 +126,7 @@ public: /** Creates a string from an ASCII character string */ String (const CharPointer_ASCII& text); - #if JUCE_WINDOWS + #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Creates a string from a UTF-16 character string */ String (const wchar_t* text); @@ -175,7 +175,7 @@ public: String& operator+= (char characterToAppend); /** Appends a character at the end of this string. */ String& operator+= (juce_wchar characterToAppend); - #if JUCE_WINDOWS + #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Appends a character at the end of this string. */ String& operator+= (wchar_t characterToAppend); /** Appends another string at the end of this one. */ @@ -1219,7 +1219,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); /** Concatenates two strings. */ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); -#if JUCE_WINDOWS +#if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Concatenates two strings. */ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); /** Concatenates two strings. */ diff --git a/src/text/juce_XmlElement.h b/src/text/juce_XmlElement.h index 9081f68c26..9aa35b744e 100644 --- a/src/text/juce_XmlElement.h +++ b/src/text/juce_XmlElement.h @@ -638,7 +638,8 @@ public: /** Sets the text in a text element. Note that this is only a valid call if this element is a text element. If it's - not, then no action will be performed. + not, then no action will be performed. If you're trying to add text inside a normal + element, you probably want to use addTextElement() instead. */ void setText (const String& newText);