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

Projucer various fixes

* Use separate folder for disk cache in debug mode to avoid mixing debug/release-mode object files while testing
* Quote the server's file name as it may contain spaces etc.
* Fix saving source files during compilation on Windows
* Fix JuceDemo for live builds on Mac: long chains of recursive operator<< invocations caused compiler crash
* Move code for creating disabled Build tab to extra function and add names to improve readability
* Implement new "subscribe" behavior for createDisabledBuildTab
* Clean up trailing spaces
This commit is contained in:
stefan 2016-09-15 17:12:14 +02:00
parent e35aba3444
commit 8ec9443543
10 changed files with 150 additions and 64 deletions

View file

@ -119,7 +119,9 @@ static String getAllSystemInfo()
<< "User region: " << SystemStats::getUserRegion() << newLine
<< "User language: " << SystemStats::getUserLanguage() << newLine
<< "Display language: " << SystemStats::getDisplayLanguage() << newLine
<< newLine
<< newLine;
systemInfo
<< "Number of CPUs: " << SystemStats::getNumCpus() << newLine
<< "Memory size: " << SystemStats::getMemorySizeInMegabytes() << " MB" << newLine
<< "CPU vendor: " << SystemStats::getCpuVendor() << newLine
@ -134,12 +136,16 @@ static String getAllSystemInfo()
<< "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine
<< "CPU has AVX: " << (SystemStats::hasAVX() ? "yes" : "no") << newLine
<< "CPU has AVX2: " << (SystemStats::hasAVX2() ? "yes" : "no") << newLine
<< newLine
<< newLine;
systemInfo
<< "Current working directory: " << File::getCurrentWorkingDirectory().getFullPathName() << newLine
<< "Current application file: " << File::getSpecialLocation (File::currentApplicationFile).getFullPathName() << newLine
<< "Current executable file: " << File::getSpecialLocation (File::currentExecutableFile) .getFullPathName() << newLine
<< "Invoked executable file: " << File::getSpecialLocation (File::invokedExecutableFile) .getFullPathName() << newLine
<< newLine
<< newLine;
systemInfo
<< "User home folder: " << File::getSpecialLocation (File::userHomeDirectory) .getFullPathName() << newLine
<< "User desktop folder: " << File::getSpecialLocation (File::userDesktopDirectory) .getFullPathName() << newLine
<< "User documents folder: " << File::getSpecialLocation (File::userDocumentsDirectory) .getFullPathName() << newLine
@ -150,7 +156,9 @@ static String getAllSystemInfo()
<< "Common application data folder: " << File::getSpecialLocation (File::commonApplicationDataDirectory).getFullPathName() << newLine
<< "Common documents folder: " << File::getSpecialLocation (File::commonDocumentsDirectory) .getFullPathName() << newLine
<< "Local temp folder: " << File::getSpecialLocation (File::tempDirectory) .getFullPathName() << newLine
<< newLine
<< newLine;
systemInfo
<< "File System roots: " << getFileSystemRoots() << newLine
<< "Free space in home folder: " << File::descriptionOfSizeInBytes (File::getSpecialLocation (File::userHomeDirectory)
.getBytesFreeOnVolume()) << newLine

View file

@ -89,9 +89,15 @@ namespace ProjectProperties
static File getCacheLocation (Project& project)
{
String cacheFolderName = project.getProjectFilenameRoot() + "_" + project.getProjectUID();
#if JUCE_DEBUG
cacheFolderName += "_debug";
#endif
return getProjucerTempFolder()
.getChildFile ("Intermediate Files")
.getChildFile (project.getProjectFilenameRoot() + "_" + project.getProjectUID());
.getChildFile (cacheFolderName);
}
}

View file

@ -230,7 +230,7 @@ String createCommandLineForLaunchingServer (const String& pipeName, const String
const File exe (File::getSpecialLocation (File::currentExecutableFile).getFullPathName());
return exe.getFullPathName() + " " + commandPrefix + info.joinIntoString (commandTokenSeparator);
return "\"" + exe.getFullPathName() + "\" " + commandPrefix + info.joinIntoString (commandTokenSeparator);
}
static ServerIPC* currentServer = nullptr;

View file

@ -354,65 +354,95 @@ struct BuildTabComponent : public ConcertinaPanel
struct ProjucerDisabledComp : public Component,
private Button::Listener
{
ProjucerDisabledComp (String message, bool loggedIn, bool canLogin, bool requirePurchase = false,
const String& loginName = String())
: isLoggedIn (loggedIn), isPurchaseButton (requirePurchase)
ProjucerDisabledComp (String message, bool loggedIn, bool showSubscribeButton,
bool showSignInButton, bool showSwitchAccountButton)
: isLoggedIn (loggedIn)
{
infoLabel.setColour (Label::textColourId, findColour (mainBackgroundColourId).contrasting (0.7f));
infoLabel.setJustificationType (Justification::centred);
infoLabel.setText (message, dontSendNotification);
addAndMakeVisible (infoLabel);
if (canLogin)
if (showSubscribeButton)
{
addAndMakeVisible (loginButton);
loginButton.addListener (this);
subscribeButton = new TextButton (String ( "Subscribe..."));
addAndMakeVisible (*subscribeButton);
subscribeButton->addListener (this);
}
if (isPurchaseButton)
{
loginButton.setButtonText ("Purchase JUCE Pro...");
signOutButton = new TextButton (String ("Sign Out ") + loginName);
addAndMakeVisible (*signOutButton);
signOutButton->addListener (this);
}
if (showSignInButton)
{
signInButton = new TextButton (String ( "Sign in..."));
addAndMakeVisible (*signInButton);
signInButton->addListener (this);
}
if (showSwitchAccountButton)
{
switchAccountButton = new TextButton (String ("Switch account..."));
addAndMakeVisible (*switchAccountButton);
switchAccountButton->addListener (this);
}
}
void resized() override
{
infoLabel.centreWithSize (proportionOfWidth (0.9f), 200);
loginButton.setSize (jmin (getWidth() - 10, 150), 22);
loginButton.setCentrePosition (infoLabel.getBounds().getCentreX(),
infoLabel.getBottom() + loginButton.getHeight() * 2);
int infoWidth = proportionOfWidth (0.9f);
int infoHeight = 100;
if (signOutButton != nullptr)
infoLabel.centreWithSize (infoWidth, infoHeight);
int buttonWidth = jmin (getWidth() - 10, 150);
int buttonHeight = 22;
int itemDistance = 10;
int buttonCenterX = infoLabel.getBounds().getCentreX();
int buttonCenterY = infoLabel.getBottom() + itemDistance + buttonHeight / 2;
if (subscribeButton.get() != nullptr)
{
signOutButton->setSize (jmin (getWidth() - 10, 150), 22);
signOutButton->setCentrePosition (infoLabel.getBounds().getCentreX(),
loginButton.getBottom() + 20);
subscribeButton->setSize (buttonWidth, buttonHeight);
subscribeButton->setCentrePosition (buttonCenterX, buttonCenterY);
buttonCenterY += itemDistance + buttonHeight;
}
if (signInButton.get() != nullptr)
{
signInButton->setSize (buttonWidth, buttonHeight);
signInButton->setCentrePosition (buttonCenterX, buttonCenterY);
buttonCenterY += itemDistance + buttonHeight;
}
if (switchAccountButton.get() != nullptr)
{
switchAccountButton->setSize (buttonWidth, buttonHeight);
switchAccountButton->setCentrePosition (buttonCenterX, buttonCenterY);
}
}
void buttonClicked (Button* btn) override
{
if (btn == &loginButton)
if (btn == subscribeButton.get())
{
if (isPurchaseButton)
URL ("http://www.juce.com").launchInDefaultBrowser();
else
ProjucerApplication::getApp().showLoginForm();
URL ("http://www.juce.com/get-juce").launchInDefaultBrowser();
}
else if (btn == signOutButton.get())
else if (btn == signInButton.get())
{
ProjucerLicenses::getInstance()->logout();
ProjucerApplication::getApp().updateAllBuildTabs();
ProjucerApplication::getApp().showLoginForm();
}
else if (btn == switchAccountButton.get())
{
ProjucerApplication::getApp().showLoginForm();
}
}
bool isLoggedIn;
private:
Label infoLabel { "info", String() };
TextButton loginButton { "Log-in..." };
ScopedPointer<TextButton> signOutButton;
bool isLoggedIn, isPurchaseButton;
ScopedPointer<TextButton> subscribeButton;
ScopedPointer<TextButton> signInButton;
ScopedPointer<TextButton> switchAccountButton;
};
struct EnableBuildComp : public Component
@ -458,33 +488,30 @@ Component* ProjectContentComponent::createBuildTab (CompileEngineChildProcess* c
return new BuildTabComponent (child, new ProjucerAppClasses::ErrorListComp (child->errorList));
}
auto& unlockStatus = *ProjucerLicenses::getInstance();
jassert (project != nullptr);
const auto& unlockStatus = *ProjucerLicenses::getInstance();
if (unlockStatus.hasLiveCodingLicence()
&& project != nullptr
&& LiveBuildProjectSettings::isBuildDisabled (*project))
return new EnableBuildComp();
if (unlockStatus.hasLiveCodingLicence())
{
jassert (unlockStatus.isLoggedIn());
jassert (unlockStatus.isDLLPresent());
return new EnableBuildComp();
}
if (unlockStatus.isLoggedIn())
return new ProjucerDisabledComp (String ("The Projucer's live-build features are currently disabled!") + newLine
+ newLine
+ "Your account " + unlockStatus.getLoginName().quoted()
+ " does not have an asscociated JUCE Pro license:",
true, true, true, unlockStatus.getLoginName());
if (! unlockStatus.isDLLPresent())
return new ProjucerDisabledComp (String ("The live-building DLL is missing!") + newLine
+ newLine
+ "To enable the compiler, you'll need to install the missing DLL "
+ CompileEngineDLL::getDLLName().quoted() + newLine
+ newLine
+ "Visit the JUCE website/forum for more help on getting and installing the DLL!",
false, false);
return new ProjucerDisabledComp ("The Projucer's live-build features are currently disabled!\n\n"
"To enable them, you'll need to log-in with your JUCE account details:",
false, true, false);
return createDisabledBuildTab(unlockStatus.isLoggedIn(),
unlockStatus.isDLLPresent());
#endif
};
//==============================================================================
Component* ProjectContentComponent::createDisabledBuildTab(bool loggedIn, bool dllPresent) {
bool showSubscribeButton = true;
bool showSignInButton = dllPresent && ! loggedIn;
bool showSwitchAccountButton = dllPresent && loggedIn;
return new ProjucerDisabledComp (
"Subscribe to JUCE Pro or Indie to use the Projucer's live-build features:",
loggedIn, showSubscribeButton, showSignInButton, showSwitchAccountButton);
}
BuildTabComponent* findBuildTab (const TabbedComponent& tabs)
@ -1499,7 +1526,8 @@ void ProjectContentComponent::handleMissingSystemHeaders()
deleteProjectTabs();
createProjectTabs();
ProjucerDisabledComp* buildTab = new ProjucerDisabledComp (tabMessage, false, false);
bool isLoggedIn = ProjucerLicenses::getInstance()->isLoggedIn();
ProjucerDisabledComp* buildTab = new ProjucerDisabledComp (tabMessage, isLoggedIn, false, false, false);
treeViewTabs.addTab ("Build", Colours::transparentBlack, buildTab, true);
showBuildTab();

View file

@ -154,6 +154,8 @@ private:
void timerCallback() override;
Component* createBuildTab (CompileEngineChildProcess*);
Component* createDisabledBuildTab (bool loggedIn, bool dllPresent);
bool isContinuousRebuildEnabled() { return getAppSettings().getGlobalProperties().getBoolValue ("continuousRebuild", true); }
void setContinuousRebuildEnabled (bool b) { getAppSettings().getGlobalProperties().setValue ("continuousRebuild", b); }
void rebuildNow();

View file

@ -300,6 +300,21 @@ bool File::copyFileTo (const File& newFile) const
|| (exists() && newFile.deleteFile() && copyInternal (newFile));
}
bool File::replaceFileIn (const File& newFile) const
{
if (newFile.fullPath == fullPath)
return true;
if (! newFile.exists())
return moveFileTo (newFile);
if (! replaceInternal (newFile))
return false;
deleteFile();
return true;
}
bool File::copyDirectoryTo (const File& newDirectory) const
{
if (isDirectory() && newDirectory.createDirectory())

View file

@ -503,6 +503,18 @@ public:
*/
bool copyFileTo (const File& targetLocation) const;
/** Replaces a file.
Replace the file in the given location, assuming the replaced files identity.
Depending on the file system this will preserve file attributes such as
creation date, short file name, etc.
If replacement succeeds the original file is deleted.
@returns true if the operation succeeds
*/
bool replaceFileIn (const File& targetLocation) const;
/** Copies a directory.
Tries to copy an entire directory, recursively.
@ -982,6 +994,7 @@ private:
Result createDirectoryInternal (const String&) const;
bool copyInternal (const File&) const;
bool moveInternal (const File&) const;
bool replaceInternal (const File&) const;
bool setFileTimesInternal (int64 m, int64 a, int64 c) const;
void getFileTimesInternal (int64& m, int64& a, int64& c) const;
bool setFileReadOnlyInternal (bool) const;

View file

@ -86,7 +86,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
// Have a few attempts at overwriting the file before giving up..
for (int i = 5; --i >= 0;)
{
if (temporaryFile.moveFileTo (targetFile))
if (temporaryFile.replaceFileIn (targetFile))
return true;
Thread::sleep (100);

View file

@ -440,6 +440,11 @@ bool File::moveInternal (const File& dest) const
return false;
}
bool File::replaceInternal (const File& dest) const
{
return moveInternal (dest);
}
Result File::createDirectoryInternal (const String& fileName) const
{
return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777));

View file

@ -220,6 +220,15 @@ bool File::moveInternal (const File& dest) const
return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0;
}
bool File::replaceInternal (const File& dest) const
{
void* lpExclude = 0;
void* lpReserved = 0;
return ReplaceFile (dest.getFullPathName().toWideCharPointer(), fullPath.toWideCharPointer(),
0, REPLACEFILE_IGNORE_MERGE_ERRORS, lpExclude, lpReserved) != 0;
}
Result File::createDirectoryInternal (const String& fileName) const
{
return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok()