| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    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 5 End-User License
 -    Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 -    27th April 2017).
 - 
 -    End User License Agreement: www.juce.com/juce-5-licence
 -    Privacy Policy: www.juce.com/juce-5-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.
 - 
 -   ==============================================================================
 - */
 - 
 - class ErrorListComp     : public TreePanelBase,
 -                           private ChangeListener
 - {
 - public:
 -     ErrorListComp (ErrorList& el)
 -         : TreePanelBase (nullptr, String()),
 -           errorList (el)
 -     {
 -         setName ("Errors and Warnings");
 -         setEmptyTreeMessage ("(No Messages)");
 - 
 -         tree.setMultiSelectEnabled (false);
 -         tree.setRootItemVisible (false);
 -         setRoot (new ErrorRootTreeItem (errorList));
 - 
 -         errorList.addChangeListener (this);
 -         errorListChanged();
 -     }
 - 
 -     ~ErrorListComp()
 -     {
 -         errorList.removeChangeListener (this);
 -     }
 - 
 -     void errorListChanged()
 -     {
 -         static_cast<ErrorRootTreeItem*> (rootItem.get())->refreshSubItems();
 -     }
 - 
 -     void moveBy (const int delta)
 -     {
 -         if (delta < 0)
 -             if (TreeViewItem* selected = tree.getSelectedItem (0))
 -                 if (selected->getRowNumberInTree() <= 1)
 -                     return;
 - 
 -         tree.moveSelectedRow (delta);
 - 
 -         if (dynamic_cast<ErrorMessageTreeItem*> (tree.getSelectedItem (0)) == nullptr)
 -             tree.moveSelectedRow (delta);
 -     }
 - 
 -     void showNext()         { moveBy (1); }
 -     void showPrevious()     { moveBy (-1); }
 - 
 - private:
 -     TreeView list;
 -     ErrorList& errorList;
 -     struct ErrorMessageTreeItem;
 - 
 -     void changeListenerCallback (ChangeBroadcaster*) override
 -     {
 -         errorListChanged();
 -     }
 - 
 -     static void limitNumberOfSubItems (TreeViewItem& item, const int maxSubItems)
 -     {
 -         while (item.getNumSubItems() > maxSubItems)
 -             item.removeSubItem (item.getNumSubItems() - 1);
 -     }
 - 
 -     //==============================================================================
 -     class ErrorRootTreeItem  : public JucerTreeViewBase
 -     {
 -     public:
 -         ErrorRootTreeItem (ErrorList& el)  : errorList (el) {}
 - 
 -         String getRenamingName() const override          { return getDisplayName(); }
 -         String getDisplayName() const override           { return "Errors and Warnings"; }
 -         void setName (const String&) override            {}
 -         bool isMissing() const override                  { return false; }
 -         Icon getIcon() const override                    { return Icon (getIcons().bug, getContentColour (true)); }
 -         bool canBeSelected() const override              { return true; }
 -         bool mightContainSubItems() override             { return true; }
 -         String getUniqueName() const override            { return "errors"; }
 - 
 -         void refreshSubItems()
 -         {
 -             Array<DiagnosticMessage> errors;
 -             errorList.takeCopy (errors);
 - 
 -             StringArray files;
 - 
 -             for (const auto& m : errors)
 -             {
 -                 files.addIfNotAlreadyThere (m.mainFile);
 - 
 -                 if (m.associatedDiagnostic != nullptr)
 -                     files.addIfNotAlreadyThere (m.associatedDiagnostic->mainFile);
 -             }
 - 
 -             limitNumberOfSubItems (*this, files.size());
 - 
 -             int i = 0;
 - 
 -             for (const auto& f : files)
 -             {
 -                 if (i >= getNumSubItems() || static_cast<CompileUnitTreeItem*> (getSubItem (i))->compileUnit != f)
 -                 {
 -                     limitNumberOfSubItems (*this, i);
 -                     addSubItem (new CompileUnitTreeItem (f));
 -                 }
 - 
 -                 static_cast<CompileUnitTreeItem*> (getSubItem (i))->refresh (errors);
 -                 ++i;
 -             }
 -         }
 - 
 -     private:
 -         ErrorList& errorList;
 -     };
 - 
 -     //==============================================================================
 -     struct CompileUnitTreeItem  : public JucerTreeViewBase
 -     {
 -         CompileUnitTreeItem (const String& filename)   : compileUnit (filename) {}
 - 
 -         void setName (const String&) override    {}
 -         void addSubItems() override              {}
 -         bool isMissing() const override          { return false; }
 -         Icon getIcon() const override            { return Icon (getIcons().bug, getContentColour (true)); }
 -         bool canBeSelected() const override      { return true; }
 -         bool mightContainSubItems() override     { return true; }
 -         String getUniqueName() const override    { return String::toHexString (compileUnit.hashCode64()); }
 - 
 -         String getRenamingName() const override  { return getDisplayName(); }
 -         String getDisplayName() const override
 -         {
 -             if (File::isAbsolutePath (compileUnit))
 -             {
 -                 File f (compileUnit);
 -                 return f.exists() ? f.getFileName() : compileUnit;
 -             }
 - 
 -             if (! compileUnit.isEmpty())
 -                 return compileUnit;
 - 
 -             return String ("Global");
 -         }
 - 
 -         void showOverlays()
 -         {
 -             for (int i = 0; i < getNumSubItems(); ++i)
 -                 if (auto* e = dynamic_cast<ErrorMessageTreeItem*> (getSubItem (i)))
 -                     e->showOverlays();
 -         }
 - 
 -         ErrorMessageTreeItem* getItemForError (const DiagnosticMessage& m) const
 -         {
 -             for (int i = 0; i < getNumSubItems(); ++i)
 -                 if (auto* item = dynamic_cast<ErrorMessageTreeItem*> (getSubItem(i)))
 -                     if (item->message == m)
 -                         return item;
 - 
 -             return nullptr;
 -         }
 - 
 -         void refresh (const Array<DiagnosticMessage>& allErrors)
 -         {
 -             clearSubItems();
 - 
 -             for (const auto& error : allErrors)
 -                 if (error.mainFile == compileUnit && error.associatedDiagnostic == nullptr)
 -                     addSubItem (new ErrorMessageTreeItem (error));
 - 
 -             for (const auto& error : allErrors)
 -                 if (error.mainFile == compileUnit && error.associatedDiagnostic != nullptr)
 -                     if (ErrorMessageTreeItem* parent = getItemForError (*error.associatedDiagnostic))
 -                         parent->addSubItem (new ErrorMessageTreeItem (error));
 -         }
 - 
 -         void showDocument() override
 -         {
 -             if (ProjectContentComponent* pcc = getProjectContentComponent())
 -                 if (File::isAbsolutePath (compileUnit) && File (compileUnit).exists())
 -                     pcc->showEditorForFile (File (compileUnit), true);
 -         }
 - 
 -         String compileUnit;
 -     };
 - 
 -     //==============================================================================
 -     struct ErrorMessageTreeItem  : public JucerTreeViewBase
 -     {
 -         ErrorMessageTreeItem (const DiagnosticMessage& m)
 -             : message (m), itemHeight (25)
 -         {
 -             setOpenness (Openness::opennessClosed);
 -             uniqueID << message.message << ':' << message.range.toString();
 -         }
 - 
 -         ~ErrorMessageTreeItem()
 -         {
 -             overlay.deleteAndZero();
 -         }
 - 
 -         String getRenamingName() const override          { return getDisplayName(); }
 -         String getDisplayName() const override           { return message.message; }
 -         void setName (const String&) override            {}
 -         bool isMissing() const override                  { return false; }
 -         Icon getIcon() const override                    { return Icon (message.isNote() ? getIcons().info
 -                                                                                          : getIcons().warning, getContentColour (true)); }
 -         bool canBeSelected() const override              { return true; }
 -         bool mightContainSubItems() override             { return getNumSubItems() != 0; }
 -         String getUniqueName() const override            { return uniqueID; }
 - 
 -         void paintContent (Graphics& g, const Rectangle<int>& area) override
 -         {
 -             jassert (area.getWidth() >= 0);
 - 
 -             AttributedString s (message.message);
 -             s.setFont (Font (12.0f));
 -             s.setColour (getContentColour (false));
 -             s.setJustification (Justification::centredLeft);
 - 
 -             text.createLayout (s, (float) area.getWidth());
 - 
 -             const auto newHeight = 2 + jmax (25, (int) text.getHeight());
 -             if (itemHeight != newHeight)
 -             {
 -                 itemHeight = newHeight;
 -                 treeHasChanged();
 -             }
 - 
 -             text.draw (g, area.toFloat());
 -         }
 - 
 -         Colour getContentColour (bool isIcon) const override
 -         {
 -             if (isIcon)
 -             {
 -                 if (isSelected())
 -                     return getOwnerView()->findColour (defaultHighlightedTextColourId);
 - 
 -                 if (message.isError())
 -                     return Colours::red;
 - 
 -                 if (message.isWarning())
 -                     return Colours::yellow;
 - 
 -                 return getOwnerView()->findColour (treeIconColourId);
 -             }
 - 
 -             return getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId
 -                                                             : defaultTextColourId);
 -         }
 - 
 -         void showPopupMenu() override
 -         {
 -             PopupMenu menu;
 -             menu.addItem (1, "Copy");
 -             launchPopupMenu (menu);
 -         }
 - 
 -         void handlePopupMenuResult (int resultCode) override
 -         {
 -             if (resultCode == 1)
 -                 SystemClipboard::copyTextToClipboard (message.toString());
 -         }
 - 
 -         int getItemHeight() const override
 -         {
 -             return itemHeight;
 -         }
 - 
 -         SourceCodeEditor* getEditor()
 -         {
 -             if (ProjectContentComponent* pcc = getProjectContentComponent())
 -             {
 -                 const File file (File::createFileWithoutCheckingPath (message.range.file));
 - 
 -                 if (message.range.isValid() && file.exists() && pcc->showEditorForFile (file, false))
 -                 {
 -                     if (SourceCodeEditor* ed = dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent()))
 -                     {
 -                         return ed;
 -                     }
 -                 }
 -             }
 - 
 -             return nullptr;
 -         }
 - 
 -         void showDocument() override
 -         {
 -             if (SourceCodeEditor* ed = getEditor())
 -             {
 -                 ed->grabKeyboardFocus();
 -                 ed->highlight (message.range.range, false);
 - 
 -                 if (auto cu = findCompileUnitParent())
 -                     cu->showOverlays();
 -             }
 -         }
 - 
 -         CompileUnitTreeItem* findCompileUnitParent()
 -         {
 -             for (TreeViewItem* p = getParentItem(); p != nullptr; p = p->getParentItem())
 -                 if (auto cu = dynamic_cast<CompileUnitTreeItem*> (p))
 -                     return cu;
 - 
 -             return nullptr;
 -         }
 - 
 -         void showOverlays()
 -         {
 -             overlay.deleteAndZero();
 - 
 -             if (ProjectContentComponent* pcc = getProjectContentComponent())
 -             {
 -                 if (SourceCodeEditor* ed = dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent()))
 -                 {
 -                     auto start = CodeDocument::Position (ed->editor->getDocument(), message.range.range.getStart());
 -                     auto end   = CodeDocument::Position (ed->editor->getDocument(), message.range.range.getEnd());
 - 
 -                     if (auto* ce = dynamic_cast<LiveBuildCodeEditor*> (ed->editor.get()))
 -                         overlay = ce->addDiagnosticOverlay (start, end, message.type);
 -                 }
 -             }
 - 
 -             for (int i = 0; i < getNumSubItems(); ++i)
 -                 if (auto* e = dynamic_cast<ErrorMessageTreeItem*> (getSubItem (i)))
 -                     e->showOverlays();
 -         }
 - 
 -         DiagnosticMessage message;
 - 
 -     private:
 -         String uniqueID;
 -         TextLayout text;
 -         int itemHeight;
 -         Component::SafePointer<Component> overlay;
 -     };
 - };
 
 
  |