| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2020 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
 -    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 - 
 -    End User License Agreement: www.juce.com/juce-6-licence
 -    Privacy Policy: www.juce.com/juce-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #pragma once
 - 
 - class LiveBuildCodeEditorDocument;
 - 
 - //==============================================================================
 - class LiveBuildCodeEditor  : public CppCodeEditorComponent,
 -                              private Timer
 - {
 - public:
 -     LiveBuildCodeEditor (LiveBuildCodeEditorDocument& edDoc, CodeDocument& doc)
 -         : CppCodeEditorComponent (edDoc.getFile(), doc),
 -           editorDoc (edDoc),
 -           classList (*this, edDoc)
 -     {
 -     }
 - 
 -     ~LiveBuildCodeEditor() override
 -     {
 -         for (int i = getNumChildComponents(); --i >= 0;)
 -             if (auto* c = dynamic_cast<DiagnosticOverlayComponent*> (getChildComponent (i)))
 -                 delete c;
 -     }
 - 
 -     CompileEngineChildProcess::Ptr getChildProcess() const
 -     {
 -         return editorDoc.getChildProcess();
 -     }
 - 
 -     Component* addDiagnosticOverlay (CodeDocument::Position start, CodeDocument::Position end,
 -                                      DiagnosticMessage::Type diagType)
 -     {
 -         auto* d = new DiagnosticOverlayComponent (*this, start, end, diagType);
 -         addAndMakeVisible (d);
 -         return d;
 -     }
 - 
 - private:
 -     LiveBuildCodeEditorDocument& editorDoc;
 - 
 -     //==============================================================================
 -     struct OverlayComponent : public Component,
 -                               private GenericCodeEditorComponent::Listener,
 -                               private CodeDocument::Listener
 -     {
 -         OverlayComponent (CodeDocument::Position start,
 -                           CodeDocument::Position end)
 -             : startPosition (start),
 -               endPosition (end)
 -         {
 -             startPosition.setPositionMaintained (true);
 -             endPosition.setPositionMaintained (true);
 -         }
 - 
 -         ~OverlayComponent() override
 -         {
 -             setEditor (nullptr);
 -         }
 - 
 -         void setEditor (GenericCodeEditorComponent* editor)
 -         {
 -             if (editor != codeEditor)
 -             {
 -                 if (codeEditor != nullptr)
 -                 {
 -                     codeEditor->removeListener (this);
 -                     codeEditor->getDocument().removeListener (this);
 -                     codeEditor->removeChildComponent (this);
 -                 }
 - 
 -                 codeEditor = editor;
 - 
 -                 if (codeEditor != nullptr)
 -                 {
 -                     codeEditor->addListener (this);
 -                     codeEditor->getDocument().addListener (this);
 -                     codeEditor->addAndMakeVisible (this);
 -                 }
 - 
 -                 if (editor != nullptr)
 -                     updatePosition();
 -             }
 -         }
 - 
 -         void codeEditorViewportMoved (CodeEditorComponent& editor) override
 -         {
 -             setEditor (dynamic_cast<GenericCodeEditorComponent*> (&editor));
 -             updatePosition();
 -         }
 - 
 -         void codeDocumentTextInserted (const String&, int) override          { updatePosition(); }
 -         void codeDocumentTextDeleted (int, int) override                     { updatePosition(); }
 - 
 -         void parentSizeChanged() override
 -         {
 -             updatePosition();
 -         }
 - 
 -         virtual void updatePosition() = 0;
 - 
 -         Component::SafePointer<GenericCodeEditorComponent> codeEditor;
 -         CodeDocument::Position startPosition, endPosition;
 -     };
 - 
 -     //==============================================================================
 -     struct LaunchClassOverlayComponent : public OverlayComponent
 -     {
 -         LaunchClassOverlayComponent (GenericCodeEditorComponent& editor,
 -                                      CodeDocument::Position start, CodeDocument::Position end,
 -                                      const String className)
 -             : OverlayComponent (start, end),
 -               launchButton (className.fromLastOccurrenceOf ("::", false, false)),
 -               name (className)
 -         {
 -             setAlwaysOnTop (true);
 -             setEditor (&editor);
 -             addAndMakeVisible (launchButton);
 -         }
 - 
 -         void updatePosition() override
 -         {
 -             if (codeEditor != nullptr)
 -             {
 -                 jassert (isVisible());
 - 
 -                 const auto charArea = codeEditor->getCharacterBounds (startPosition);
 -                 const int height = charArea.getHeight() + 8;
 - 
 -                 Font f ((float) height * 0.7f);
 - 
 -                 const int width = jmin (height * 2 + f.getStringWidth (launchButton.getName()),
 -                                         jmax (120, codeEditor->proportionOfWidth (0.2f)));
 - 
 -                 setBounds (codeEditor->getWidth() - width - 10, charArea.getY() - 4,
 -                            width, height);
 -             }
 -         }
 - 
 -         void resized() override
 -         {
 -             launchButton.setBounds (getLocalBounds());
 -         }
 - 
 -         struct LaunchButton  : public Button
 -         {
 -             LaunchButton (const String& nm)  : Button (nm)
 -             {
 -                 setMouseCursor (MouseCursor::PointingHandCursor);
 -             }
 - 
 -             void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
 -             {
 -                 Colour background (findColour (CodeEditorComponent::backgroundColourId)
 -                                      .contrasting()
 -                                      .overlaidWith (Colours::yellow.withAlpha (0.5f))
 -                                      .withAlpha (0.4f));
 -                 g.setColour (background);
 -                 g.fillRoundedRectangle (getLocalBounds().toFloat(), 3.0f);
 - 
 -                 const Path& path = getIcons().play;
 - 
 -                 Colour col (background.contrasting (Colours::lightgreen, 0.6f));
 - 
 -                 Rectangle<int> r (getLocalBounds().reduced (getHeight() / 5));
 - 
 -                 Icon (path, col.withAlpha (isButtonDown ? 1.0f : (isMouseOverButton ? 0.8f : 0.5f)))
 -                    .draw (g, r.removeFromLeft (getHeight()).toFloat(), false);
 - 
 -                 g.setColour (Colours::white);
 -                 g.setFont ((float) getHeight() * 0.7f);
 -                 g.drawFittedText (getName(), r, Justification::centredLeft, 1);
 -             }
 - 
 -             void clicked() override
 -             {
 -                 if (auto* l = findParentComponentOfClass<LaunchClassOverlayComponent>())
 -                     l->launch();
 -             }
 - 
 -             using Button::clicked;
 -         };
 - 
 -         void launch()
 -         {
 -             if (auto* e = findParentComponentOfClass<LiveBuildCodeEditor>())
 -                 e->launch (name);
 -         }
 - 
 -     private:
 -         LaunchButton launchButton;
 -         String name;
 -     };
 - 
 -     struct ComponentClassList  : private Timer
 -     {
 -         ComponentClassList (GenericCodeEditorComponent& e, LiveBuildCodeEditorDocument& edDoc)
 -             : owner (e),
 -               childProcess (edDoc.getChildProcess()),
 -               file (edDoc.getFile())
 -         {
 -             startTimer (600);
 -         }
 - 
 -         ~ComponentClassList() override
 -         {
 -             deleteOverlays();
 -         }
 - 
 -         void timerCallback() override
 -         {
 -             Array<WeakReference<ClassDatabase::Class>> newClasses;
 - 
 -             if (childProcess != nullptr)
 -                 const_cast <ClassDatabase::ClassList&> (childProcess->getComponentList()).globalNamespace.findClassesDeclaredInFile (newClasses, file);
 - 
 -             for (int i = newClasses.size(); --i >= 0;)
 -             {
 -                 auto& c = newClasses.getReference (i);
 - 
 -                 if (c == nullptr || ! c->getInstantiationFlags().canBeInstantiated())
 -                     newClasses.remove (i);
 -             }
 - 
 -             if (newClasses != classes)
 -             {
 -                 classes = newClasses;
 -                 deleteOverlays();
 - 
 -                 for (auto c : classes)
 -                 {
 -                     if (c != nullptr)
 -                     {
 -                         CodeDocument::Position pos (owner.getDocument(), c->getClassDeclarationRange().range.getStart());
 -                         overlays.add (new LaunchClassOverlayComponent (owner, pos, pos, c->getName()));
 -                     }
 -                 }
 -             }
 -         }
 - 
 -         void deleteOverlays()
 -         {
 -             for (auto& o : overlays)
 -                 o.deleteAndZero();
 - 
 -             overlays.clear();
 -         }
 - 
 -         GenericCodeEditorComponent& owner;
 -         CompileEngineChildProcess::Ptr childProcess;
 -         File file;
 -         Array<WeakReference<ClassDatabase::Class>> classes;
 -         Array<Component::SafePointer<Component>> overlays;
 - 
 -         JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentClassList)
 -     };
 - 
 -     ComponentClassList classList;
 - 
 -     //==============================================================================
 -     struct DiagnosticOverlayComponent : public OverlayComponent
 -     {
 -         DiagnosticOverlayComponent (GenericCodeEditorComponent& editor,
 -                                     CodeDocument::Position start, CodeDocument::Position end,
 -                                     DiagnosticMessage::Type diagType)
 -             : OverlayComponent (start, end), diagnosticType (diagType)
 -         {
 -             setInterceptsMouseClicks (false, false);
 -             setEditor (&editor);
 -         }
 - 
 -         void updatePosition() override
 -         {
 -             if (codeEditor != nullptr)
 -             {
 -                 jassert (isVisible());
 - 
 -                 const auto charStartRect = codeEditor->getCharacterBounds (startPosition);
 -                 const auto charEndRect   = codeEditor->getCharacterBounds (endPosition);
 - 
 -                 auto charHeight = charStartRect.getHeight();
 -                 const auto editorBounds = codeEditor->getBounds();
 - 
 -                 arrowXMin = static_cast<int> (jmin (charStartRect.getX(), charEndRect.getX()));
 -                 arrowXMax = static_cast<int> (jmax (charStartRect.getX() + charStartRect.getWidth(),  charEndRect.getX() + charEndRect.getWidth()));
 - 
 -                 lineYMin = charStartRect.getY();
 -                 lineOffset = charHeight;
 - 
 -                 setBounds (0, lineYMin, editorBounds.getWidth(), lineOffset + charHeight);
 -                 repaint();
 -             }
 -         }
 - 
 -         void paint (Graphics& g) override
 -         {
 -             const auto diagColour = diagnosticType == DiagnosticMessage::Type::error ? Colours::red
 -                                                                                      : Colour (200, 200, 64);
 - 
 -             g.setColour (diagColour.withAlpha (0.2f));
 -             g.fillRect (getLocalBounds().withTrimmedBottom (lineOffset));
 - 
 -             Path path;
 -             const float bottomY = (float) getHeight() - ((float) lineOffset / 2.0f);
 -             path.addTriangle ((float) arrowXMin, bottomY,
 -                               (float) (arrowXMax + arrowXMin) / 2.0f, (float) lineOffset,
 -                               (float) arrowXMax, bottomY);
 - 
 -             g.setColour (diagColour.withAlpha (0.8f));
 -             g.fillPath (path);
 -         }
 - 
 -     private:
 -         int arrowXMin, arrowXMax;
 -         int lineYMin, lineOffset;
 -         const DiagnosticMessage::Type diagnosticType;
 -     };
 - 
 -     //==============================================================================
 -     void timerCallback() override
 -     {
 -         if (isMouseButtonDownAnywhere())
 -             return;
 - 
 -         MouseInputSource mouse = Desktop::getInstance().getMainMouseSource();
 -         Component* underMouse = mouse.getComponentUnderMouse();
 - 
 -         if (underMouse != nullptr
 -              && (dynamic_cast<ControlsComponent*> (underMouse) != nullptr
 -                    || underMouse->findParentComponentOfClass<ControlsComponent>() != nullptr))
 -             return;
 - 
 -         overlay.reset();
 - 
 -         if (hasKeyboardFocus (true) && underMouse != nullptr
 -               && (underMouse == this || underMouse->isParentOf (this)))
 -         {
 -             Point<int> mousePos = getLocalPoint (nullptr, mouse.getScreenPosition()).toInt();
 - 
 -             CodeDocument::Position start, end;
 -             getDocument().findTokenContaining (getPositionAt (mousePos.x, mousePos.y), start, end);
 - 
 -             if (end.getPosition() > start.getPosition())
 -             {
 -                 Range<int> selection = optimiseSelection ({ start.getPosition(), end.getPosition() });
 - 
 -                 String text = getTextInRange (selection).toLowerCase();
 - 
 -                 if (isIntegerLiteral (text) || isFloatLiteral (text))
 -                     overlay.reset (new LiteralHighlightOverlay (*this, selection, mightBeColourValue (text)));
 -             }
 -         }
 - 
 -         startTimerHz (10);
 -     }
 - 
 -     void hideOverlay()
 -     {
 -         stopTimer();
 -         overlay.reset();
 -     }
 - 
 -     void focusLost (FocusChangeType) override
 -     {
 -         if (CompileEngineChildProcess::Ptr childProcess = getChildProcess())
 -             childProcess->flushEditorChanges();
 -     }
 - 
 -     void mouseMove (const MouseEvent& e) override
 -     {
 -         if (overlay == nullptr)
 -             startTimer (100);
 - 
 -         CppCodeEditorComponent::mouseMove (e);
 -     }
 - 
 -     void mouseDrag (const MouseEvent& e) override
 -     {
 -         if (e.getDistanceFromDragStart() > 0)
 -             hideOverlay();
 - 
 -         CppCodeEditorComponent::mouseDrag (e);
 -     }
 - 
 -     void mouseDown (const MouseEvent& e) override
 -     {
 -         CppCodeEditorComponent::mouseDown (e);
 -     }
 - 
 -     void mouseUp (const MouseEvent& e) override
 -     {
 -         CppCodeEditorComponent::mouseUp (e);
 -     }
 - 
 -     bool keyPressed (const KeyPress& key) override
 -     {
 -         hideOverlay();
 -         return CppCodeEditorComponent::keyPressed (key);
 -     }
 - 
 -     static bool isIntegerLiteral (const String& text)   { return CppParserHelpers::parseSingleToken (text) == CPlusPlusCodeTokeniser::tokenType_integer; }
 -     static bool isFloatLiteral (const String& text)     { return CppParserHelpers::parseSingleToken (text) == CPlusPlusCodeTokeniser::tokenType_float; }
 - 
 -     static bool mightBeColourValue (const String& text)
 -     {
 -         return isIntegerLiteral (text)
 -                  && text.trim().startsWith ("0x")
 -                  && text.trim().length() > 7;
 -     }
 - 
 -     Range<int> optimiseSelection (Range<int> selection)
 -     {
 -         String text (getTextInRange (selection));
 - 
 -         if (CharacterFunctions::isDigit (text[0]) || text[0] == '.')
 -             if (getTextInRange (Range<int> (selection.getStart() - 1, selection.getStart())) == "-")
 -                 selection.setStart (selection.getStart() - 1);
 - 
 -         selection.setStart (selection.getStart() + (text.length() - text.trimStart().length()));
 -         selection.setEnd (selection.getEnd() - (text.length() - text.trimEnd().length()));
 - 
 -         return selection;
 -     }
 - 
 -     void launch (const String& name)
 -     {
 -         if (CompileEngineChildProcess::Ptr p = getChildProcess())
 -             if (auto* cls = p->getComponentList().globalNamespace.findClass (name))
 -                 p->openPreview (*cls);
 -     }
 - 
 -     //==============================================================================
 -     class ControlsComponent   : public Component,
 -                                 private ChangeListener
 -     {
 -     public:
 -         ControlsComponent (CodeDocument& doc, const Range<int>& selection,
 -                            CompileEngineChildProcess::Ptr cp, bool showColourSelector)
 -             : document (doc),
 -               start (doc, selection.getStart()),
 -               end (doc, selection.getEnd()),
 -               childProcess (cp)
 -         {
 -             slider.setTextBoxStyle (Slider::NoTextBox, true, 0, 0);
 -             slider.setWantsKeyboardFocus (false);
 -             slider.setMouseClickGrabsKeyboardFocus (false);
 -             setWantsKeyboardFocus (false);
 -             setMouseClickGrabsKeyboardFocus (false);
 -             addAndMakeVisible (&slider);
 -             updateRange();
 -             slider.onValueChange = [this] { updateSliderValue(); };
 -             slider.onDragEnd = [this] { updateRange(); };
 - 
 -             if (showColourSelector)
 -             {
 -                 updateColourSelector();
 -                 selector.setWantsKeyboardFocus (false);
 -                 selector.setMouseClickGrabsKeyboardFocus (false);
 -                 addAndMakeVisible (&selector);
 -                 setSize (400, sliderHeight + 400);
 -                 selector.addChangeListener (this);
 -             }
 -             else
 -             {
 -                 setSize (400, sliderHeight);
 -             }
 - 
 -             end.setPositionMaintained (true);
 -         }
 - 
 -         void updateRange()
 -         {
 -             double v = getValue();
 - 
 -             if (isFloat())
 -                 slider.setRange (v - 10, v + 10);
 -             else
 -                 slider.setRange (v - 100, v + 100);
 - 
 -             slider.setValue (v, dontSendNotification);
 -         }
 - 
 -     private:
 -         Slider slider;
 -         ColourSelector selector;
 - 
 -         CodeDocument& document;
 -         CodeDocument::Position start, end;
 -         CompileEngineChildProcess::Ptr childProcess;
 - 
 -         static const int sliderHeight = 26;
 - 
 -         void paint (Graphics& g) override
 -         {
 -             g.setColour (LiteralHighlightOverlay::getBackgroundColour());
 -             g.fillRoundedRectangle (getLocalBounds().toFloat(), 8.0f);
 -         }
 - 
 -         void updateSliderValue()
 -         {
 -             const String oldText (document.getTextBetween (start, end));
 -             const String newText (CppParserHelpers::getReplacementStringInSameFormat (oldText, slider.getValue()));
 - 
 -             if (oldText != newText)
 -                 document.replaceSection (start.getPosition(), end.getPosition(), newText);
 - 
 -             if (childProcess != nullptr)
 -                 childProcess->flushEditorChanges();
 - 
 -             updateColourSelector();
 -         }
 - 
 -         void changeListenerCallback (ChangeBroadcaster*) override
 -         {
 -             setNewColour (selector.getCurrentColour());
 -         }
 - 
 -         void updateColourSelector()
 -         {
 -             selector.setCurrentColour (getCurrentColour());
 -         }
 - 
 -         Colour getCurrentColour() const
 -         {
 -             int64 val;
 -             if (CppParserHelpers::parseInt (document.getTextBetween (start, end), val))
 -                 return Colour ((uint32) val);
 - 
 -             return Colours::white;
 -         }
 - 
 -         void setNewColour (const Colour& c)
 -         {
 -             const String oldText (document.getTextBetween (start, end));
 -             const String newText (CppParserHelpers::getReplacementStringInSameFormat (oldText, (int64) c.getARGB()));
 - 
 -             if (oldText != newText)
 -                 document.replaceSection (start.getPosition(), end.getPosition(), newText);
 - 
 -             if (childProcess != nullptr)
 -                 childProcess->flushEditorChanges();
 -         }
 - 
 -         void resized() override
 -         {
 -             Rectangle<int> r (getLocalBounds());
 - 
 -             slider.setBounds (r.removeFromTop (sliderHeight));
 - 
 -             r.removeFromTop (10);
 - 
 -             if (selector.isVisible())
 -                 selector.setBounds (r);
 - 
 -         }
 - 
 -         double getValue() const
 -         {
 -             const String text (document.getTextBetween (start, end));
 - 
 -             if (text.containsChar ('.'))
 -             {
 -                 double f;
 -                 if (CppParserHelpers::parseFloat (text, f))
 -                     return f;
 -             }
 -             else
 -             {
 -                 int64 val;
 -                 if (CppParserHelpers::parseInt (text, val))
 -                     return (double) val;
 -             }
 - 
 -             jassertfalse;
 -             return 0;
 -         }
 - 
 -         bool isFloat() const
 -         {
 -             return document.getTextBetween (start, end).containsChar ('.');
 -         }
 -     };
 - 
 -     //==============================================================================
 -     struct LiteralHighlightOverlay  : public Component,
 -                                       private CodeDocument::Listener
 -     {
 -         LiteralHighlightOverlay (LiveBuildCodeEditor& e, Range<int> section, bool showColourSelector)
 -             : owner (e),
 -               start (e.getDocument(), section.getStart()),
 -               end   (e.getDocument(), section.getEnd()),
 -               controls (e.getDocument(), section, e.getChildProcess(), showColourSelector)
 -         {
 -             if (e.hasKeyboardFocus (true))
 -                 previouslyFocused = Component::getCurrentlyFocusedComponent();
 - 
 -             start.setPositionMaintained (true);
 -             end.setPositionMaintained (true);
 - 
 -             setInterceptsMouseClicks (false, false);
 - 
 -             if (Component* parent = owner.findParentComponentOfClass<ProjectContentComponent>())
 -                 parent->addAndMakeVisible (controls);
 -             else
 -                 jassertfalse;
 - 
 -             owner.addAndMakeVisible (this);
 -             toBack();
 - 
 -             updatePosition();
 - 
 -             owner.getDocument().addListener (this);
 -         }
 - 
 -         ~LiteralHighlightOverlay() override
 -         {
 -             if (auto* p = getParentComponent())
 -             {
 -                 p->removeChildComponent (this);
 - 
 -                 if (previouslyFocused != nullptr && ! previouslyFocused->hasKeyboardFocus (true))
 -                     previouslyFocused->grabKeyboardFocus();
 -             }
 - 
 -             owner.getDocument().removeListener (this);
 -         }
 - 
 -         void paint (Graphics& g) override
 -         {
 -             g.setColour (getBackgroundColour());
 - 
 -             Rectangle<int> r (getLocalBounds());
 -             g.fillRect (r.removeFromTop (borderSize));
 -             g.fillRect (r.removeFromLeft (borderSize));
 -             g.fillRect (r.removeFromRight (borderSize));
 -         }
 - 
 -         void updatePosition()
 -         {
 -             Rectangle<int> area = owner.getCharacterBounds (start)
 -                                        .getUnion (owner.getCharacterBounds (end.movedBy (-1)))
 -                                        .expanded (borderSize)
 -                                        .withTrimmedBottom (borderSize);
 - 
 -             setBounds (getParentComponent()->getLocalArea (&owner, area));
 - 
 -             area.setPosition (area.getX() - controls.getWidth() / 2, area.getBottom());
 -             area.setSize (controls.getWidth(), controls.getHeight());
 - 
 -             controls.setBounds (controls.getParentComponent()->getLocalArea (&owner, area));
 -         }
 - 
 -         void codeDocumentTextInserted (const String&, int) override         { updatePosition(); }
 -         void codeDocumentTextDeleted (int, int) override                    { updatePosition(); }
 - 
 -         LiveBuildCodeEditor& owner;
 -         CodeDocument::Position start, end;
 -         ControlsComponent controls;
 -         Component::SafePointer<Component> previouslyFocused;
 - 
 -         static const int borderSize = 4;
 -         static Colour getBackgroundColour() { return Colour (0xcb5c7879); }
 -     };
 - 
 -     std::unique_ptr<LiteralHighlightOverlay> overlay;
 - };
 - 
 - //==============================================================================
 - class LiveBuildCodeEditorDocument  : public SourceCodeDocument
 - {
 - public:
 -     LiveBuildCodeEditorDocument (Project* projectToUse, const File& file)
 -         : SourceCodeDocument (projectToUse, file)
 -     {
 -         if (projectToUse != nullptr)
 -             if (CompileEngineChildProcess::Ptr childProcess = getChildProcess())
 -                 childProcess->editorOpened (file, getCodeDocument());
 -     }
 - 
 -     struct Type  : public SourceCodeDocument::Type
 -     {
 -         Document* openFile (Project* proj, const File& file) override
 -         {
 -             return new LiveBuildCodeEditorDocument (proj, file);
 -         }
 -     };
 - 
 -     Component* createEditor() override
 -     {
 -         SourceCodeEditor* e = nullptr;
 - 
 -         if (fileNeedsCppSyntaxHighlighting (getFile()))
 -             e = new SourceCodeEditor (this, new LiveBuildCodeEditor (*this, getCodeDocument()));
 -         else
 -             e = new SourceCodeEditor (this, getCodeDocument());
 - 
 -         applyLastState (*(e->editor));
 -         return e;
 -     }
 - 
 -     // override save() to make a few more attempts at saving if it fails, since on Windows
 -     // the compiler can interfere with things saving..
 -     bool save() override
 -     {
 -         for (int i = 5; --i >= 0;)
 -         {
 -             if (SourceCodeDocument::save()) // should already re-try for up to half a second
 -                 return true;
 - 
 -             Thread::sleep (100);
 -         }
 - 
 -         return false;
 -     }
 - 
 -     CompileEngineChildProcess::Ptr getChildProcess() const
 -     {
 -         return ProjucerApplication::getApp().childProcessCache->getExisting (*project);
 -     }
 - };
 
 
  |