@@ -228,6 +228,14 @@ | |||
*/ | |||
#define JUCE_INCLUDE_ZLIB_CODE 1 | |||
/** Config: JUCE_USE_CURL | |||
Enables http/https support via libcurl (Linux only). Enabling this will add an additional | |||
run-time dynmic dependency to libcurl. | |||
If you disable this then https/ssl support will not be available on linux. | |||
*/ | |||
#define JUCE_USE_CURL 0 | |||
/* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
If enabled, this will add some exception-catching code to forward unhandled exceptions | |||
to your JUCEApplication::unhandledException() callback. | |||
@@ -918,9 +918,11 @@ struct AAXClasses | |||
for (int parameterIndex = 0; parameterIndex < numParameters; ++parameterIndex) | |||
{ | |||
AAX_CString paramName (audioProcessor.getParameterName (parameterIndex, 31).toRawUTF8()); | |||
AAX_IParameter* parameter | |||
= new AAX_CParameter<float> (IndexAsParamID (parameterIndex), | |||
audioProcessor.getParameterName (parameterIndex, 31).toRawUTF8(), | |||
paramName, | |||
audioProcessor.getParameterDefaultValue (parameterIndex), | |||
AAX_CLinearTaperDelegate<float, 0>(), | |||
AAX_CNumberDisplayDelegate<float, 3>(), | |||
@@ -47,6 +47,7 @@ public: | |||
CakewalkSonarGeneric, | |||
DigidesignProTools, | |||
DigitalPerformer, | |||
FinalCut, | |||
FruityLoops, | |||
MagixSamplitude, | |||
MergingPyramix, | |||
@@ -72,8 +73,8 @@ public: | |||
StudioOne, | |||
Tracktion3, | |||
TracktionGeneric, | |||
WaveBurner, | |||
VBVSTScanner | |||
VBVSTScanner, | |||
WaveBurner | |||
}; | |||
HostType type; | |||
@@ -87,6 +88,7 @@ public: | |||
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); } | |||
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; } | |||
bool isLogic() const noexcept { return type == AppleLogic; } | |||
bool isFinalCut() const noexcept { return type == FinalCut; } | |||
bool isFruityLoops() const noexcept { return type == FruityLoops; } | |||
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; } | |||
bool isPremiere() const noexcept { return type == AdobePremierePro; } | |||
@@ -120,6 +122,7 @@ public: | |||
case CakewalkSonarGeneric: return "Cakewalk Sonar"; | |||
case DigidesignProTools: return "ProTools"; | |||
case DigitalPerformer: return "DigitalPerformer"; | |||
case FinalCut: return "Final Cut"; | |||
case FruityLoops: return "FruityLoops"; | |||
case MagixSamplitude: return "Magix Samplitude"; | |||
case MergingPyramix: return "Pyramix"; | |||
@@ -167,6 +170,8 @@ private: | |||
const String hostFilename (File (hostPath).getFileName()); | |||
#if JUCE_MAC | |||
if (hostPath.containsIgnoreCase ("Final Cut Pro.app")) return FinalCut; | |||
if (hostPath.containsIgnoreCase ("Final Cut Pro Trial.app")) return FinalCut; | |||
if (hostPath.containsIgnoreCase ("Live 6.")) return AbletonLive6; | |||
if (hostPath.containsIgnoreCase ("Live 7.")) return AbletonLive7; | |||
if (hostPath.containsIgnoreCase ("Live 8.")) return AbletonLive8; | |||
@@ -977,7 +977,6 @@ bool AudioProcessorGraph::removeNode (const uint32 nodeId) | |||
{ | |||
if (nodes.getUnchecked(i)->nodeId == nodeId) | |||
{ | |||
nodes.getUnchecked(i)->setParentGraph (nullptr); | |||
nodes.remove (i); | |||
triggerAsyncUpdate(); | |||
@@ -82,6 +82,10 @@ | |||
#if JUCE_LINUX | |||
#include <langinfo.h> | |||
#include <ifaddrs.h> | |||
#if JUCE_USE_CURL | |||
#include <curl/curl.h> | |||
#endif | |||
#endif | |||
#include <pwd.h> | |||
@@ -210,6 +214,9 @@ namespace juce | |||
#include "native/juce_linux_CommonFile.cpp" | |||
#include "native/juce_linux_Files.cpp" | |||
#include "native/juce_linux_Network.cpp" | |||
#if JUCE_USE_CURL | |||
#include "native/juce_curl_Network.cpp" | |||
#endif | |||
#include "native/juce_linux_SystemStats.cpp" | |||
#include "native/juce_linux_Threads.cpp" | |||
@@ -126,6 +126,17 @@ | |||
#define JUCE_ZLIB_INCLUDE_PATH <zlib.h> | |||
#endif | |||
/** Config: JUCE_USE_CURL | |||
Enables http/https support via libcurl (Linux only). Enabling this will add an additional | |||
run-time dynmic dependency to libcurl. | |||
If you disable this then https/ssl support will not be available on linux. | |||
*/ | |||
#ifndef JUCE_USE_CURL | |||
#define JUCE_USE_CURL 0 | |||
#endif | |||
/* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
If enabled, this will add some exception-catching code to forward unhandled exceptions | |||
to your JUCEApplicationBase::unhandledException() callback. | |||
@@ -67,8 +67,8 @@ bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /* targetEma | |||
return false; | |||
} | |||
//============================================================================== | |||
#if ! JUCE_USE_CURL | |||
class WebInputStream : public InputStream | |||
{ | |||
public: | |||
@@ -77,8 +77,9 @@ public: | |||
const String& headers_, int timeOutMs_, StringPairArray* responseHeaders, | |||
const int maxRedirects) | |||
: statusCode (0), socketHandle (-1), levelsOfRedirection (0), | |||
address (address_), headers (headers_), postData (postData_), position (0), | |||
finished (false), isPost (isPost_), timeOutMs (timeOutMs_), numRedirectsToFollow (maxRedirects) | |||
address (address_), headers (headers_), postData (postData_), contentLength (-1), position (0), | |||
finished (false), isPost (isPost_), timeOutMs (timeOutMs_), numRedirectsToFollow (maxRedirects), | |||
chunkEnd (0), isChunked (false), readingChunk (false) | |||
{ | |||
statusCode = createConnection (progressCallback, progressCallbackContext, numRedirectsToFollow); | |||
@@ -104,18 +105,63 @@ public: | |||
bool isError() const { return socketHandle < 0; } | |||
bool isExhausted() override { return finished; } | |||
int64 getPosition() override { return position; } | |||
int64 getTotalLength() override | |||
{ | |||
//xxx to do | |||
return -1; | |||
} | |||
int64 getTotalLength() override { return contentLength; } | |||
int read (void* buffer, int bytesToRead) override | |||
{ | |||
if (finished || isError()) | |||
return 0; | |||
if (isChunked && ! readingChunk) | |||
{ | |||
if (position >= chunkEnd) | |||
{ | |||
const ScopedValueSetter<bool> setter (readingChunk, true, false); | |||
MemoryOutputStream chunkLengthBuffer; | |||
char c = 0; | |||
if (chunkEnd > 0) | |||
{ | |||
if (read (&c, 1) != 1 || c != '\r' | |||
|| read (&c, 1) != 1 || c != '\n') | |||
{ | |||
finished = true; | |||
return 0; | |||
} | |||
} | |||
while (chunkLengthBuffer.getDataSize() < 512 && ! (finished || isError())) | |||
{ | |||
if (read (&c, 1) != 1) | |||
{ | |||
finished = true; | |||
return 0; | |||
} | |||
if (c == '\r') | |||
continue; | |||
if (c == '\n') | |||
break; | |||
chunkLengthBuffer.writeByte (c); | |||
} | |||
const int64 chunkSize = chunkLengthBuffer.toString().trimStart().getHexValue64(); | |||
if (chunkSize == 0) | |||
{ | |||
finished = true; | |||
return 0; | |||
} | |||
chunkEnd += chunkSize; | |||
} | |||
if (bytesToRead > chunkEnd - position) | |||
bytesToRead = chunkEnd - position; | |||
} | |||
fd_set readbits; | |||
FD_ZERO (&readbits); | |||
FD_SET (socketHandle, &readbits); | |||
@@ -131,7 +177,9 @@ public: | |||
if (bytesRead == 0) | |||
finished = true; | |||
position += bytesRead; | |||
if (! readingChunk) | |||
position += bytesRead; | |||
return bytesRead; | |||
} | |||
@@ -165,11 +213,13 @@ private: | |||
StringArray headerLines; | |||
String address, headers; | |||
MemoryBlock postData; | |||
int64 position; | |||
int64 contentLength, position; | |||
bool finished; | |||
const bool isPost; | |||
const int timeOutMs; | |||
const int numRedirectsToFollow; | |||
int64 chunkEnd; | |||
bool isChunked, readingChunk; | |||
void closeSocket (bool resetLevelsOfRedirection = true) | |||
{ | |||
@@ -298,6 +348,13 @@ private: | |||
return createConnection (progressCallback, progressCallbackContext, numRedirects); | |||
} | |||
String contentLengthString (findHeaderItem (headerLines, "Content-Length:")); | |||
if (contentLengthString.isNotEmpty()) | |||
contentLength = contentLengthString.getLargeIntValue(); | |||
isChunked = (findHeaderItem (headerLines, "Transfer-Encoding:") == "chunked"); | |||
return status; | |||
} | |||
@@ -345,7 +402,7 @@ private: | |||
static void writeHost (MemoryOutputStream& dest, const bool isPost, | |||
const String& path, const String& host, int port) | |||
{ | |||
dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host; | |||
dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.1\r\nHost: " << host; | |||
/* HTTP spec 14.23 says that the port number must be included in the header if it is not 80 */ | |||
if (port != 80) | |||
@@ -455,3 +512,4 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) | |||
}; | |||
#endif |
@@ -279,8 +279,12 @@ public: | |||
//============================================================================== | |||
/** Makes the font bold or non-bold. */ | |||
void setBold (bool shouldBeBold); | |||
/** Returns a copy of this font with the bold attribute set. */ | |||
/** Returns a copy of this font with the bold attribute set. | |||
If the font does not have a bold version, this will return the default font. | |||
*/ | |||
Font boldened() const; | |||
/** Returns true if the font is bold. */ | |||
bool isBold() const noexcept; | |||
@@ -443,7 +443,7 @@ public: | |||
/** Changes the component's position and size. | |||
The coordinates are relative to the top-left of the component's parent, or relative | |||
to the origin of the screen is the component is on the desktop. | |||
to the origin of the screen if the component is on the desktop. | |||
If this method changes the component's top-left position, it will make a synchronous | |||
call to moved(). If it changes the size, it will also make a call to resized(). | |||
@@ -459,7 +459,7 @@ public: | |||
/** Changes the component's position and size. | |||
The coordinates are relative to the top-left of the component's parent, or relative | |||
to the origin of the screen is the component is on the desktop. | |||
to the origin of the screen if the component is on the desktop. | |||
If this method changes the component's top-left position, it will make a synchronous | |||
call to moved(). If it changes the size, it will also make a call to resized(). | |||
@@ -85,12 +85,6 @@ struct TextEditorKeyMapper | |||
if (key.isKeyCode (KeyPress::pageDownKey)) return target.pageDown (isShiftDown); | |||
} | |||
if (numCtrlAltCommandKeys < 2) | |||
{ | |||
if (key.isKeyCode (KeyPress::backspaceKey)) return target.deleteBackwards (ctrlOrAltDown); | |||
if (key.isKeyCode (KeyPress::deleteKey)) return target.deleteForwards (ctrlOrAltDown); | |||
} | |||
if (key == KeyPress ('c', ModifierKeys::commandModifier, 0) | |||
|| key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0)) | |||
return target.copyToClipboard(); | |||
@@ -103,6 +97,13 @@ struct TextEditorKeyMapper | |||
|| key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0)) | |||
return target.pasteFromClipboard(); | |||
// NB: checking for delete must happen after the earlier check for shift + delete | |||
if (numCtrlAltCommandKeys < 2) | |||
{ | |||
if (key.isKeyCode (KeyPress::backspaceKey)) return target.deleteBackwards (ctrlOrAltDown); | |||
if (key.isKeyCode (KeyPress::deleteKey)) return target.deleteForwards (ctrlOrAltDown); | |||
} | |||
if (key == KeyPress ('a', ModifierKeys::commandModifier, 0)) | |||
return target.selectAll(); | |||
@@ -490,6 +490,12 @@ int LookAndFeel_V2::getAlertWindowButtonHeight() | |||
return 28; | |||
} | |||
Font LookAndFeel_V2::getAlertWindowTitleFont() | |||
{ | |||
Font messageFont = getAlertWindowMessageFont(); | |||
return messageFont.withHeight (messageFont.getHeight() * 1.1f).boldened(); | |||
} | |||
Font LookAndFeel_V2::getAlertWindowMessageFont() | |||
{ | |||
return Font (15.0f); | |||
@@ -67,7 +67,22 @@ public: | |||
void drawAlertBox (Graphics&, AlertWindow&, const Rectangle<int>& textArea, TextLayout&) override; | |||
int getAlertBoxWindowFlags() override; | |||
int getAlertWindowButtonHeight() override; | |||
/** Override this function to supply a custom font for the alert window title. | |||
This default implementation will use a boldened and slightly larger version | |||
of the alert window message font. | |||
@see getAlertWindowMessageFont. | |||
*/ | |||
Font getAlertWindowTitleFont() override; | |||
/** Override this function to supply a custom font for the alert window message. | |||
This default implementation will use the default font with height set to 15.0f. | |||
@see getAlertWindowTitleFont | |||
*/ | |||
Font getAlertWindowMessageFont() override; | |||
Font getAlertWindowFont() override; | |||
//============================================================================== | |||
@@ -56,6 +56,9 @@ public: | |||
The graphics context has its origin at the row's top-left, and your method | |||
should fill the area specified by the width and height parameters. | |||
Note that the rowNumber value may be greater than the number of rows in your | |||
list, so be careful that you don't assume it's less than getNumRows(). | |||
*/ | |||
virtual void paintRowBackground (Graphics&, | |||
int rowNumber, | |||
@@ -343,22 +343,24 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||
const int titleH = 24; | |||
const int iconWidth = 80; | |||
const Font font (getLookAndFeel().getAlertWindowMessageFont()); | |||
LookAndFeel& lookAndFeel = getLookAndFeel(); | |||
const int wid = jmax (font.getStringWidth (text), | |||
font.getStringWidth (getName())); | |||
const Font messageFont (lookAndFeel.getAlertWindowMessageFont()); | |||
const int sw = (int) std::sqrt (font.getHeight() * wid); | |||
const int wid = jmax (messageFont.getStringWidth (text), | |||
messageFont.getStringWidth (getName())); | |||
const int sw = (int) std::sqrt (messageFont.getHeight() * wid); | |||
int w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f)); | |||
const int edgeGap = 10; | |||
const int labelHeight = 18; | |||
int iconSpace = 0; | |||
AttributedString attributedText; | |||
attributedText.append (getName(), font.withHeight (font.getHeight() * 1.1f).boldened()); | |||
attributedText.append (getName(), lookAndFeel.getAlertWindowTitleFont()); | |||
if (text.isNotEmpty()) | |||
attributedText.append ("\n\n" + text, font); | |||
attributedText.append ("\n\n" + text, messageFont); | |||
attributedText.setColour (findColour (textColourId)); | |||
@@ -383,18 +385,18 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||
int buttonW = 40; | |||
for (int i = 0; i < buttons.size(); ++i) | |||
buttonW += 16 + buttons.getUnchecked(i)->getWidth(); | |||
buttonW += 16 + buttons.getUnchecked (i)->getWidth(); | |||
w = jmax (buttonW, w); | |||
h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50; | |||
if (buttons.size() > 0) | |||
h += 20 + buttons.getUnchecked(0)->getHeight(); | |||
h += 20 + buttons.getUnchecked (0)->getHeight(); | |||
for (int i = customComps.size(); --i >= 0;) | |||
{ | |||
Component* c = customComps.getUnchecked(i); | |||
Component* c = customComps.getUnchecked (i); | |||
w = jmax (w, (c->getWidth() * 100) / 80); | |||
h += 10 + c->getHeight(); | |||
@@ -437,6 +437,7 @@ public: | |||
virtual int getAlertWindowButtonHeight() = 0; | |||
virtual Font getAlertWindowTitleFont() = 0; | |||
virtual Font getAlertWindowMessageFont() = 0; | |||
virtual Font getAlertWindowFont() = 0; | |||
}; | |||