| @@ -197,6 +197,7 @@ bool ComponentDocument::save() | |||
| bool ComponentDocument::reload() | |||
| { | |||
| String xmlString; | |||
| bool hadMetaDataTags = false; | |||
| { | |||
| InputStream* in = cppFile.createInputStream(); | |||
| @@ -217,7 +218,10 @@ bool ComponentDocument::reload() | |||
| { | |||
| line = buf.readNextLine(); | |||
| if (line.contains (metadataTagEnd)) | |||
| { | |||
| hadMetaDataTags = true; | |||
| break; | |||
| } | |||
| xml.append (line); | |||
| xml.append (newLine); | |||
| @@ -231,6 +235,9 @@ bool ComponentDocument::reload() | |||
| XmlDocument doc (xmlString); | |||
| ScopedPointer<XmlElement> xml (doc.getDocumentElement()); | |||
| if (xml == 0 && hadMetaDataTags) | |||
| xml = new XmlElement (componentDocumentTag); | |||
| if (xml != 0 && xml->hasTagName (componentDocumentTag)) | |||
| { | |||
| ValueTree newTree (ValueTree::fromXml (*xml)); | |||
| @@ -301,7 +308,7 @@ void ComponentDocument::addNewComponentMenuItems (PopupMenu& menu) const | |||
| menu.addItem (i + menuItemOffset, "New " + typeNames[i]); | |||
| } | |||
| void ComponentDocument::performNewComponentMenuItem (int menuResultCode) | |||
| const ValueTree ComponentDocument::performNewComponentMenuItem (int menuResultCode) | |||
| { | |||
| const StringArray typeNames (ComponentTypeManager::getInstance()->getTypeNames()); | |||
| @@ -317,8 +324,12 @@ void ComponentDocument::performNewComponentMenuItem (int menuResultCode) | |||
| handler->initialiseNewItem (*this, state); | |||
| getComponentGroup().addChild (state, -1, getUndoManager()); | |||
| return state; | |||
| } | |||
| } | |||
| return ValueTree::invalid; | |||
| } | |||
| //============================================================================== | |||
| @@ -49,7 +49,9 @@ public: | |||
| bool reload(); | |||
| bool hasChangedSinceLastSave(); | |||
| void changed(); | |||
| const File getCppFile() const { return cppFile; } | |||
| const File getCppFile() const { return cppFile; } | |||
| void cppFileHasMoved (const File& newFile) { cppFile = newFile; } | |||
| //============================================================================== | |||
| const String getUniqueId() const { return root [idProperty]; } | |||
| @@ -87,7 +89,7 @@ public: | |||
| const String getChosenMarkerMenuItem (const ValueTree& componentState, Coordinate& coord, int itemId) const; | |||
| void addNewComponentMenuItems (PopupMenu& menu) const; | |||
| void performNewComponentMenuItem (int menuResultCode); | |||
| const ValueTree performNewComponentMenuItem (int menuResultCode); | |||
| //============================================================================== | |||
| class MarkerList : public MarkerListBase | |||
| @@ -33,9 +33,8 @@ static const char* const markersGroupYTag = "MARKERS_Y"; | |||
| //============================================================================== | |||
| DrawableDocument::DrawableDocument (Project* project_, const File& drawableFile_) | |||
| DrawableDocument::DrawableDocument (Project* project_) | |||
| : project (project_), | |||
| drawableFile (drawableFile_), | |||
| root (drawableTag), | |||
| saveAsXml (true), | |||
| needsSaving (false) | |||
| @@ -51,9 +50,6 @@ DrawableDocument::DrawableDocument (Project* project_, const File& drawableFile_ | |||
| DrawableDocument::~DrawableDocument() | |||
| { | |||
| if (needsSaving) | |||
| save(); | |||
| root.removeListener (this); | |||
| } | |||
| @@ -107,7 +103,7 @@ bool DrawableDocument::hasChangedSinceLastSave() const | |||
| return needsSaving; | |||
| } | |||
| bool DrawableDocument::reload() | |||
| bool DrawableDocument::reload (const File& drawableFile) | |||
| { | |||
| ScopedPointer <InputStream> stream (drawableFile.createInputStream()); | |||
| @@ -122,7 +118,7 @@ bool DrawableDocument::reload() | |||
| return false; | |||
| } | |||
| bool DrawableDocument::save() | |||
| bool DrawableDocument::save (const File& drawableFile) | |||
| { | |||
| TemporaryFile tempFile (drawableFile); | |||
| ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream()); | |||
| @@ -38,15 +38,15 @@ class DrawableDocument : public ValueTree::Listener, | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| DrawableDocument (Project* project, const File& drawableFile); | |||
| DrawableDocument (Project* project); | |||
| ~DrawableDocument(); | |||
| //============================================================================== | |||
| void setName (const String& name); | |||
| const String getName() const; | |||
| bool reload(); | |||
| bool save(); | |||
| bool reload (const File& drawableFile); | |||
| bool save (const File& drawableFile); | |||
| bool hasChangedSinceLastSave() const; | |||
| void changed(); | |||
| @@ -101,7 +101,6 @@ public: | |||
| private: | |||
| Project* project; | |||
| File drawableFile; | |||
| ValueTree root; | |||
| ScopedPointer<MarkerList> markersX, markersY; | |||
| mutable UndoManager undoManager; | |||
| @@ -141,9 +141,9 @@ public: | |||
| if (newFile != File::nonexistent) | |||
| { | |||
| DrawableDocument newDrawable (&(parent.getProject()), newFile); | |||
| DrawableDocument newDrawable (&(parent.getProject())); | |||
| if (newDrawable.save()) | |||
| if (newDrawable.save (newFile)) | |||
| parent.addFile (newFile, 0); | |||
| else | |||
| showFailedToWriteMessage (newFile); | |||
| @@ -494,6 +494,39 @@ void Project::Item::setFile (const File& file) | |||
| jassert (getFile() == file); | |||
| } | |||
| bool Project::Item::renameFile (const File& newFile) | |||
| { | |||
| const File oldFile (getFile()); | |||
| if (oldFile.moveFileTo (newFile)) | |||
| { | |||
| setFile (newFile); | |||
| OpenDocumentManager::getInstance()->fileHasBeenRenamed (oldFile, newFile); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| Project::Item Project::Item::findItemForFile (const File& file) const | |||
| { | |||
| if (getFile() == file) | |||
| return *this; | |||
| if (isGroup()) | |||
| { | |||
| for (int i = getNumChildren(); --i >= 0;) | |||
| { | |||
| Item found (getChild(i).findItemForFile (file)); | |||
| if (found.isValid()) | |||
| return found; | |||
| } | |||
| } | |||
| return Item (project, ValueTree::invalid); | |||
| } | |||
| const File Project::Item::determineGroupFolder() const | |||
| { | |||
| jassert (isGroup()); | |||
| @@ -157,6 +157,7 @@ public: | |||
| ~Item(); | |||
| //============================================================================== | |||
| bool isValid() const { return node.isValid(); } | |||
| const ValueTree& getNode() const throw() { return node; } | |||
| ValueTree& getNode() throw() { return node; } | |||
| Project& getProject() const throw() { return project; } | |||
| @@ -176,6 +177,7 @@ public: | |||
| const File getFile() const; | |||
| void setFile (const File& file); | |||
| const File determineGroupFolder() const; | |||
| bool renameFile (const File& newFile); | |||
| bool shouldBeAddedToTargetProject() const; | |||
| bool shouldBeCompiled() const; | |||
| @@ -191,6 +193,7 @@ public: | |||
| bool addFile (const File& file, int insertIndex); | |||
| void removeItemFromProject(); | |||
| void sortAlphabetically(); | |||
| Item findItemForFile (const File& file) const; | |||
| Item getParent() const; | |||
| @@ -26,8 +26,8 @@ | |||
| #include "../../jucer_Headers.h" | |||
| #include "../../model/Component/jucer_ComponentDocument.h" | |||
| #include "../jucer_JucerTreeViewBase.h" | |||
| #include "../Editor Base/jucer_EditorDragOperation.h" | |||
| #include "../Editor Base/jucer_EditorPanel.h" | |||
| #include "../Editor Base/jucer_EditorDragOperation.h" | |||
| #include "jucer_ComponentEditor.h" | |||
| #include "jucer_ComponentEditorCanvas.h" | |||
| #include "jucer_ComponentEditorTreeView.h" | |||
| @@ -256,6 +256,19 @@ void ComponentEditor::selectionToBack() | |||
| getDocument().beginNewTransaction(); | |||
| } | |||
| //============================================================================== | |||
| void ComponentEditor::showNewComponentMenu (Component* componentToAttachTo) | |||
| { | |||
| PopupMenu m; | |||
| getDocument().addNewComponentMenuItems (m); | |||
| const int r = m.showAt (componentToAttachTo); | |||
| const ValueTree newComp (getDocument().performNewComponentMenuItem (r)); | |||
| if (newComp.isValid()) | |||
| getSelection().selectOnly (newComp [ComponentDocument::idProperty]); | |||
| } | |||
| //============================================================================== | |||
| class TestComponent : public Component | |||
| @@ -307,6 +320,8 @@ void ComponentEditor::getAllCommands (Array <CommandID>& commands) | |||
| CommandIDs::test, | |||
| CommandIDs::showOrHideProperties, | |||
| CommandIDs::showOrHideTree, | |||
| CommandIDs::showOrHideMarkers, | |||
| CommandIDs::toggleSnapping, | |||
| StandardApplicationCommandIDs::del }; | |||
| commands.addArray (ids, numElementsInArray (ids)); | |||
| @@ -344,10 +359,22 @@ void ComponentEditor::getCommandInfo (CommandID commandID, ApplicationCommandInf | |||
| case CommandIDs::showOrHideProperties: | |||
| result.setInfo ("Show/Hide Tree", "Shows or hides the component tree view", CommandCategories::editing, 0); | |||
| result.setTicked (layoutEditorHolder != 0 && layoutEditorHolder->arePropertiesVisible()); | |||
| break; | |||
| case CommandIDs::showOrHideTree: | |||
| result.setInfo ("Show/Hide Properties", "Shows or hides the component properties panel", CommandCategories::editing, 0); | |||
| result.setTicked (layoutEditorHolder != 0 && layoutEditorHolder->isTreeVisible()); | |||
| break; | |||
| case CommandIDs::showOrHideMarkers: | |||
| result.setInfo ("Show/Hide Markers", "Shows or hides the markers", CommandCategories::editing, 0); | |||
| result.setTicked (layoutEditorHolder != 0 && layoutEditorHolder->areMarkersVisible()); | |||
| break; | |||
| case CommandIDs::toggleSnapping: | |||
| result.setInfo ("Toggle snapping", "Turns object snapping on or off", CommandCategories::editing, 0); | |||
| result.setTicked (layoutEditorHolder != 0 && layoutEditorHolder->isSnappingEnabled()); | |||
| break; | |||
| case StandardApplicationCommandIDs::del: | |||
| @@ -394,6 +421,14 @@ bool ComponentEditor::perform (const InvocationInfo& info) | |||
| layoutEditorHolder->showOrHideTree(); | |||
| return true; | |||
| case CommandIDs::showOrHideMarkers: | |||
| layoutEditorHolder->showOrHideMarkers(); | |||
| return true; | |||
| case CommandIDs::toggleSnapping: | |||
| layoutEditorHolder->toggleSnapping(); | |||
| return true; | |||
| case StandardApplicationCommandIDs::del: | |||
| deleteSelection(); | |||
| return true; | |||
| @@ -61,6 +61,7 @@ public: | |||
| void deselectNonComponents(); | |||
| void selectionToFront(); | |||
| void selectionToBack(); | |||
| void showNewComponentMenu (Component* componentToAttachTo); | |||
| //============================================================================== | |||
| void test(); | |||
| @@ -146,10 +146,9 @@ public: | |||
| void showPopupMenu (const Point<int>& position) | |||
| { | |||
| PopupMenu m; | |||
| if (findObjectIdAt (position).isNotEmpty()) | |||
| { | |||
| PopupMenu m; | |||
| m.addCommandItem (commandManager, CommandIDs::toFront); | |||
| m.addCommandItem (commandManager, CommandIDs::toBack); | |||
| m.addSeparator(); | |||
| @@ -159,9 +158,7 @@ public: | |||
| } | |||
| else | |||
| { | |||
| getDocument().addNewComponentMenuItems (m); | |||
| const int r = m.show(); | |||
| getDocument().performNewComponentMenuItem (r); | |||
| editor.showNewComponentMenu (0); | |||
| } | |||
| } | |||
| @@ -27,6 +27,82 @@ | |||
| #define __JUCER_COMPONENTEDITORTOOLBAR_H_6B5CA931__ | |||
| //============================================================================== | |||
| class JucerToolbarButton : public ToolbarItemComponent | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| JucerToolbarButton (ComponentEditor& editor_, int itemId_, const String& labelText) | |||
| : ToolbarItemComponent (itemId_, labelText, true), | |||
| editor (editor_) | |||
| { | |||
| setClickingTogglesState (false); | |||
| } | |||
| ~JucerToolbarButton() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| bool getToolbarItemSizes (int toolbarDepth, bool isToolbarVertical, int& preferredSize, int& minSize, int& maxSize) | |||
| { | |||
| preferredSize = minSize = maxSize = 50; | |||
| return true; | |||
| } | |||
| void paintButton (Graphics& g, const bool over, const bool down) | |||
| { | |||
| Path p; | |||
| p.addRoundedRectangle (1.5f, 2.5f, getWidth() - 3.0f, getHeight() - 5.0f, 3.0f); | |||
| if (getToggleState()) | |||
| { | |||
| g.setColour (Colours::grey.withAlpha (0.5f)); | |||
| g.fillPath (p); | |||
| } | |||
| g.setColour (Colours::darkgrey.withAlpha (0.3f)); | |||
| g.strokePath (p, PathStrokeType (1.0f)); | |||
| g.setFont (11.0f); | |||
| g.setColour (Colours::black.withAlpha ((over || down) ? 1.0f : 0.7f)); | |||
| g.drawFittedText (getButtonText(), 2, 2, getWidth() - 4, getHeight() - 4, Justification::centred, 2); | |||
| } | |||
| void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown) | |||
| { | |||
| } | |||
| void contentAreaChanged (const Rectangle<int>& newBounds) | |||
| { | |||
| } | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| ComponentEditor& editor; | |||
| private: | |||
| JucerToolbarButton (const JucerToolbarButton&); | |||
| JucerToolbarButton& operator= (const JucerToolbarButton&); | |||
| }; | |||
| //============================================================================== | |||
| class NewComponentToolbarButton : public JucerToolbarButton | |||
| { | |||
| public: | |||
| NewComponentToolbarButton (ComponentEditor& editor_, int itemId_) | |||
| : JucerToolbarButton (editor_, itemId_, "create...") | |||
| { | |||
| setTriggeredOnMouseDown (true); | |||
| } | |||
| void clicked() | |||
| { | |||
| editor.showNewComponentMenu (this); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class ComponentEditorToolbarFactory : public ToolbarItemFactory | |||
| { | |||
| @@ -46,6 +122,8 @@ public: | |||
| createComponent = 1, | |||
| showInfo = 2, | |||
| showComponentTree = 3, | |||
| showOrHideMarkers = 4, | |||
| toggleSnapping = 5 | |||
| }; | |||
| void getAllToolbarItemIds (Array <int>& ids) | |||
| @@ -53,6 +131,8 @@ public: | |||
| ids.add (createComponent); | |||
| ids.add (showInfo); | |||
| ids.add (showComponentTree); | |||
| ids.add (showOrHideMarkers); | |||
| ids.add (toggleSnapping); | |||
| ids.add (separatorBarId); | |||
| ids.add (spacerId); | |||
| @@ -64,6 +144,9 @@ public: | |||
| ids.add (spacerId); | |||
| ids.add (createComponent); | |||
| ids.add (flexibleSpacerId); | |||
| ids.add (showOrHideMarkers); | |||
| ids.add (toggleSnapping); | |||
| ids.add (flexibleSpacerId); | |||
| ids.add (showComponentTree); | |||
| ids.add (showInfo); | |||
| ids.add (spacerId); | |||
| @@ -76,13 +159,15 @@ public: | |||
| switch (itemId) | |||
| { | |||
| case createComponent: name = "new"; break; | |||
| case createComponent: name = "new"; return new NewComponentToolbarButton (editor, createComponent); | |||
| case showInfo: name = "info"; commandId = CommandIDs::showOrHideProperties; break; | |||
| case showComponentTree: name = "tree"; commandId = CommandIDs::showOrHideTree; break; | |||
| case showOrHideMarkers: name = "markers"; commandId = CommandIDs::showOrHideMarkers; break; | |||
| case toggleSnapping: name = "snap"; commandId = CommandIDs::toggleSnapping; break; | |||
| default: jassertfalse; return 0; | |||
| } | |||
| ToolbarButton* b = new ToolbarButton (itemId, name, new DrawablePath(), 0); | |||
| JucerToolbarButton* b = new JucerToolbarButton (editor, itemId, name); | |||
| b->setCommandToTrigger (commandManager, commandId, true); | |||
| return b; | |||
| } | |||
| @@ -26,9 +26,9 @@ | |||
| #include "../../jucer_Headers.h" | |||
| #include "../../model/Drawable/jucer_DrawableDocument.h" | |||
| #include "../jucer_JucerTreeViewBase.h" | |||
| #include "../Editor Base/jucer_EditorDragOperation.h" | |||
| #include "../Editor Base/jucer_EditorPanel.h" | |||
| #include "../Editor Base/jucer_EditorCanvas.h" | |||
| #include "../Editor Base/jucer_EditorDragOperation.h" | |||
| #include "jucer_DrawableEditor.h" | |||
| #include "jucer_DrawableEditorCanvas.h" | |||
| #include "jucer_DrawableEditorTreeView.h" | |||
| @@ -25,6 +25,7 @@ | |||
| #include "../../jucer_Headers.h" | |||
| #include "jucer_EditorCanvas.h" | |||
| #include "jucer_EditorPanel.h" | |||
| //============================================================================== | |||
| @@ -749,6 +750,11 @@ void EditorCanvasBase::shutdown() | |||
| deleteAllChildren(); | |||
| } | |||
| EditorPanelBase* EditorCanvasBase::getPanel() const | |||
| { | |||
| return findParentComponentOfClass ((EditorPanelBase*) 0); | |||
| } | |||
| //============================================================================== | |||
| void EditorCanvasBase::paint (Graphics& g) | |||
| { | |||
| @@ -28,7 +28,7 @@ | |||
| #include "../../utility/jucer_Coordinate.h" | |||
| #include "../../utility/jucer_MarkerListBase.h" | |||
| class EditorPanelBase; | |||
| //============================================================================== | |||
| class EditorCanvasBase : public Component, | |||
| @@ -101,7 +101,8 @@ public: | |||
| void endDrag (const MouseEvent& e); | |||
| //============================================================================== | |||
| Component* getComponentHolder() const { return componentHolder; } | |||
| Component* getComponentHolder() const { return componentHolder; } | |||
| EditorPanelBase* getPanel() const; | |||
| //============================================================================== | |||
| class OverlayItemComponent : public Component | |||
| @@ -183,8 +183,11 @@ public: | |||
| snapGuides.clear(); | |||
| performSnap (verticalSnapTargets, getVerticalSnapPositions (distance), true, distance); | |||
| performSnap (horizontalSnapTargets, getHorizontalSnapPositions (distance), false, distance); | |||
| if (canvas->getPanel()->isSnappingEnabled() != e.mods.isCommandDown()) | |||
| { | |||
| performSnap (verticalSnapTargets, getVerticalSnapPositions (distance), true, distance); | |||
| performSnap (horizontalSnapTargets, getHorizontalSnapPositions (distance), false, distance); | |||
| } | |||
| for (int n = 50;;) | |||
| { | |||
| @@ -279,11 +282,13 @@ private: | |||
| if (absDiff <= absBest) | |||
| { | |||
| if (absDiff < absBest) | |||
| { | |||
| absBest = absDiff; | |||
| best = diff; | |||
| lines.clearQuick(); | |||
| } | |||
| lines.add (SnapLine (target.position, jmin (target.start, source.start), jmax (target.end, source.end))); | |||
| best = diff; | |||
| absBest = absDiff; | |||
| } | |||
| } | |||
| } | |||
| @@ -32,7 +32,7 @@ class EditorPanelBase : public Component | |||
| { | |||
| public: | |||
| EditorPanelBase() | |||
| : infoPanel (0), tree (0) | |||
| : infoPanel (0), tree (0), markersVisible (true), snappingEnabled (true) | |||
| { | |||
| addAndMakeVisible (toolbar = new Toolbar()); | |||
| toolbar->setStyle (Toolbar::textOnly); | |||
| @@ -68,18 +68,40 @@ public: | |||
| deleteAndZero (infoPanel); | |||
| } | |||
| //============================================================================== | |||
| void showOrHideProperties() | |||
| { | |||
| infoPanel->setVisible (! infoPanel->isVisible()); | |||
| resized(); | |||
| } | |||
| bool arePropertiesVisible() const { return infoPanel->isVisible(); } | |||
| void showOrHideTree() | |||
| { | |||
| tree->setVisible (! tree->isVisible()); | |||
| resized(); | |||
| } | |||
| bool isTreeVisible() const { return tree->isVisible(); } | |||
| void showOrHideMarkers() | |||
| { | |||
| markersVisible = ! markersVisible; | |||
| commandManager->commandStatusChanged(); | |||
| } | |||
| bool areMarkersVisible() const { return markersVisible; } | |||
| void toggleSnapping() | |||
| { | |||
| snappingEnabled = ! snappingEnabled; | |||
| commandManager->commandStatusChanged(); | |||
| } | |||
| bool isSnappingEnabled() const { return snappingEnabled; } | |||
| //============================================================================== | |||
| virtual SelectedItemSet<String>& getSelection() = 0; | |||
| virtual void getSelectedItemProperties (Array<PropertyComponent*>& newComps) = 0; | |||
| @@ -89,21 +111,21 @@ public: | |||
| toolbar->setBounds (0, 0, getWidth(), toolbarHeight); | |||
| int infoPanelWidth = 200; | |||
| if (infoPanel != 0 && infoPanel->isVisible()) | |||
| infoPanel->setBounds (getWidth() - infoPanelWidth, toolbar->getBottom(), infoPanelWidth, getHeight() - toolbar->getBottom()); | |||
| else | |||
| infoPanelWidth = 0; | |||
| int contentL = 0, contentR = getWidth(); | |||
| if (tree->isVisible()) | |||
| if (infoPanel != 0 && infoPanel->isVisible()) | |||
| { | |||
| tree->setBounds (0, toolbar->getBottom(), infoPanelWidth, getHeight() - toolbar->getBottom()); | |||
| viewport->setBounds (infoPanelWidth, toolbar->getBottom(), getWidth() - infoPanelWidth * 2, getHeight() - toolbar->getBottom()); | |||
| contentR -= 200; | |||
| infoPanel->setBounds (contentR, toolbar->getBottom(), getWidth() - contentR, getHeight() - toolbar->getBottom()); | |||
| } | |||
| else | |||
| if (tree->isVisible()) | |||
| { | |||
| viewport->setBounds (0, toolbar->getBottom(), getWidth() - infoPanelWidth, getHeight() - toolbar->getBottom()); | |||
| contentL = 200; | |||
| tree->setBounds (0, toolbar->getBottom(), contentL, getHeight() - toolbar->getBottom()); | |||
| } | |||
| viewport->setBounds (contentL, toolbar->getBottom(), contentR - contentL, getHeight() - toolbar->getBottom()); | |||
| } | |||
| private: | |||
| @@ -157,6 +179,7 @@ private: | |||
| Viewport* viewport; | |||
| InfoPanel* infoPanel; | |||
| TreeView* tree; | |||
| bool markersVisible, snappingEnabled; | |||
| }; | |||
| @@ -165,6 +165,68 @@ SourceFileTreeViewItem::~SourceFileTreeViewItem() | |||
| { | |||
| } | |||
| const String SourceFileTreeViewItem::getDisplayName() const | |||
| { | |||
| return getFile().getFileName(); | |||
| } | |||
| static const File findCorrespondingHeaderOrCpp (const File& f) | |||
| { | |||
| if (f.hasFileExtension (".cpp")) | |||
| return f.withFileExtension (".h"); | |||
| else if (f.hasFileExtension (".h")) | |||
| return f.withFileExtension (".cpp"); | |||
| return File::nonexistent; | |||
| } | |||
| void SourceFileTreeViewItem::setName (const String& newName) | |||
| { | |||
| if (newName != File::createLegalFileName (newName)) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "File Rename", | |||
| "That filename contained some illegal characters!"); | |||
| triggerAsyncRename (item); | |||
| return; | |||
| } | |||
| File oldFile (getFile()); | |||
| File newFile (oldFile.getSiblingFile (newName)); | |||
| File correspondingFile (findCorrespondingHeaderOrCpp (oldFile)); | |||
| if (correspondingFile.exists() && newFile.hasFileExtension (oldFile.getFileExtension())) | |||
| { | |||
| Project::Item correspondingItem (item.getProject().getMainGroup().findItemForFile (correspondingFile)); | |||
| if (correspondingItem.isValid()) | |||
| { | |||
| if (AlertWindow::showOkCancelBox (AlertWindow::NoIcon, "File Rename", | |||
| "Do you also want to rename the corresponding file \"" + correspondingFile.getFileName() | |||
| + "\" to match?")) | |||
| { | |||
| if (! item.renameFile (newFile)) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "File Rename", | |||
| "Failed to rename \"" + oldFile.getFullPathName() + "\"!\n\nCheck your file permissions!"); | |||
| return; | |||
| } | |||
| if (! correspondingItem.renameFile (newFile.withFileExtension (correspondingFile.getFileExtension()))) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "File Rename", | |||
| "Failed to rename \"" + correspondingFile.getFullPathName() + "\"!\n\nCheck your file permissions!"); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if (! item.renameFile (newFile)) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "File Rename", | |||
| "Failed to rename the file!\n\nCheck your file permissions!"); | |||
| } | |||
| } | |||
| ProjectTreeViewBase* SourceFileTreeViewItem::createSubItem (const Project::Item& child) | |||
| { | |||
| jassertfalse | |||
| @@ -193,13 +255,15 @@ void SourceFileTreeViewItem::showPopupMenu() | |||
| } | |||
| m.addItem (1, "Open in external editor"); | |||
| m.addItem (2, | |||
| #if JUCE_MAC | |||
| m.addItem (2, "Reveal in Finder"); | |||
| "Reveal in Finder"); | |||
| #else | |||
| m.addItem (2, "Reveal in Explorer"); | |||
| "Reveal in Explorer"); | |||
| #endif | |||
| //m.addItem (4, "Rename..."); | |||
| m.addItem (4, "Rename File..."); | |||
| m.addSeparator(); | |||
| m.addItem (3, "Delete"); | |||
| const int res = m.show(); | |||
| @@ -208,7 +272,7 @@ void SourceFileTreeViewItem::showPopupMenu() | |||
| case 1: getFile().startAsProcess(); break; | |||
| case 2: revealInFinder(); break; | |||
| case 3: deleteAllSelectedItems(); break; | |||
| //case 4: triggerAsyncRename(); break; | |||
| case 4: triggerAsyncRename (item); break; | |||
| default: | |||
| if (parentGroup != 0) | |||
| @@ -41,6 +41,8 @@ public: | |||
| ProjectTreeViewBase* createSubItem (const Project::Item& child); | |||
| void showDocument(); | |||
| void showPopupMenu(); | |||
| const String getDisplayName() const; | |||
| void setName (const String& newName); | |||
| }; | |||
| //============================================================================== | |||
| @@ -51,6 +51,8 @@ namespace CommandIDs | |||
| static const int toBack = 0x2030a1; | |||
| static const int showOrHideProperties = 0x2030b0; | |||
| static const int showOrHideTree = 0x2030b1; | |||
| static const int showOrHideMarkers = 0x2030b2; | |||
| static const int toggleSnapping = 0x2030b3; | |||
| static const int group = 0x202170; | |||
| static const int ungroup = 0x202180; | |||
| @@ -53,6 +53,7 @@ public: | |||
| const String getType() const { return modDetector.getFile().getFileExtension() + " file"; } | |||
| bool needsSaving() const { return codeDoc != 0 && codeDoc->hasChangedSinceSavePoint(); } | |||
| bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); } | |||
| void fileHasBeenRenamed (const File& newFile) { modDetector.fileHasBeenRenamed (newFile); } | |||
| void reloadFromFile() | |||
| { | |||
| @@ -119,6 +120,14 @@ public: | |||
| bool needsSaving() const { return componentDoc != 0 && componentDoc->hasChangedSinceLastSave(); } | |||
| bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); } | |||
| void fileHasBeenRenamed (const File& newFile) | |||
| { | |||
| if (componentDoc != 0) | |||
| componentDoc->cppFileHasMoved (newFile); | |||
| modDetector.fileHasBeenRenamed (newFile); | |||
| } | |||
| void reloadFromFile() | |||
| { | |||
| modDetector.updateHash(); | |||
| @@ -178,21 +187,22 @@ public: | |||
| const String getName() const { return modDetector.getFile().getFileName(); } | |||
| bool needsSaving() const { return drawableDoc != 0 && drawableDoc->hasChangedSinceLastSave(); } | |||
| bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); } | |||
| void fileHasBeenRenamed (const File& newFile) { modDetector.fileHasBeenRenamed (newFile); } | |||
| void reloadFromFile() | |||
| { | |||
| modDetector.updateHash(); | |||
| if (drawableDoc == 0) | |||
| drawableDoc = new DrawableDocument (project, modDetector.getFile()); | |||
| drawableDoc = new DrawableDocument (project); | |||
| if (! drawableDoc->reload()) | |||
| if (! drawableDoc->reload (modDetector.getFile())) | |||
| drawableDoc = 0; | |||
| } | |||
| bool save() | |||
| { | |||
| return drawableDoc->save(); | |||
| return drawableDoc->save (modDetector.getFile()); | |||
| } | |||
| Component* createEditor() | |||
| @@ -233,6 +243,7 @@ public: | |||
| void reloadFromFile() { fileModificationTime = file.getLastModificationTime(); } | |||
| const String getName() const { return file.getFileName(); } | |||
| Component* createEditor() { return new ItemPreviewComponent (file); } | |||
| void fileHasBeenRenamed (const File& newFile) { file = newFile; } | |||
| const String getType() const | |||
| { | |||
| @@ -245,7 +256,7 @@ public: | |||
| private: | |||
| Project* const project; | |||
| const File file; | |||
| File file; | |||
| Time fileModificationTime; | |||
| UnknownDocument (const UnknownDocument&); | |||
| @@ -448,3 +459,14 @@ void OpenDocumentManager::reloadModifiedFiles() | |||
| d->reloadFromFile(); | |||
| } | |||
| } | |||
| void OpenDocumentManager::fileHasBeenRenamed (const File& oldFile, const File& newFile) | |||
| { | |||
| for (int i = documents.size(); --i >= 0;) | |||
| { | |||
| Document* d = documents.getUnchecked (i); | |||
| if (d->isForFile (oldFile)) | |||
| d->fileHasBeenRenamed (newFile); | |||
| } | |||
| } | |||
| @@ -61,6 +61,7 @@ public: | |||
| virtual bool hasFileBeenModifiedExternally() = 0; | |||
| virtual void reloadFromFile() = 0; | |||
| virtual Component* createEditor() = 0; | |||
| virtual void fileHasBeenRenamed (const File& newFile) = 0; | |||
| }; | |||
| Document* getDocumentForFile (Project* project, const File& file); | |||
| @@ -79,6 +80,7 @@ public: | |||
| bool saveAll(); | |||
| FileBasedDocument::SaveResult saveIfNeededAndUserAgrees (Document* doc); | |||
| void reloadModifiedFiles(); | |||
| void fileHasBeenRenamed (const File& oldFile, const File& newFile); | |||
| //============================================================================== | |||
| void registerEditor (DocumentEditorComponent* editor); | |||
| @@ -89,7 +89,8 @@ public: | |||
| { | |||
| } | |||
| const File& getFile() const { return file; } | |||
| const File& getFile() const { return file; } | |||
| void fileHasBeenRenamed (const File& newFile) { file = newFile; } | |||
| bool hasBeenModified() const | |||
| { | |||
| @@ -1725,7 +1725,7 @@ static void juce_testAtomics() | |||
| juce_testAtomicType ((long) 0); | |||
| juce_testAtomicType ((void*) 0); | |||
| juce_testAtomicType ((int*) 0); | |||
| #if ! (JUCE_WINDOWS && JUCE_32BIT) // some 64-bit intrinsics aren't available on win32 | |||
| #if ! ((JUCE_WINDOWS && JUCE_32BIT) || JUCE_PPC) // 64-bit intrinsics aren't available on some old platforms | |||
| juce_testAtomicType ((int64) 0); | |||
| juce_testAtomicType ((uint64) 0); | |||
| #endif | |||