diff --git a/docs/JUCE changelist.txt b/docs/JUCE changelist.txt index eaceb90820..29a5d06b7e 100644 --- a/docs/JUCE changelist.txt +++ b/docs/JUCE changelist.txt @@ -16,6 +16,9 @@ Changelist for version 1.44 - added a Component::setExplicitFocusOrder() method for specifying the order in which components have their focus traversed, and added Jucer support for setting this value. - made slider skew factor editable in the jucer - added a background thread to the MidiOutput class, so it can be given a batch of midi events and will dispatch them itself based on their timestamps. +- added MultiDocumentPanel::createNewDocumentWindow() method to allow creation of custom document windows in a MultiDocumentPanel +- added a Thread::getCurrentThread() method +- added an option to MessageManagerLock that can check for thread termination, to avoid deadlocks. ============================================================================== Changelist for version 1.43 diff --git a/src/juce_appframework/events/juce_MessageManager.cpp b/src/juce_appframework/events/juce_MessageManager.cpp index 6df6547773..923695ffc7 100644 --- a/src/juce_appframework/events/juce_MessageManager.cpp +++ b/src/juce_appframework/events/juce_MessageManager.cpp @@ -332,7 +332,8 @@ bool MessageManager::currentThreadHasLockedMessageManager() const } //============================================================================== -MessageManagerLock::MessageManagerLock() +MessageManagerLock::MessageManagerLock() throw() + : locked (true) { if (MessageManager::instance != 0) { @@ -342,9 +343,36 @@ MessageManagerLock::MessageManagerLock() } } -MessageManagerLock::~MessageManagerLock() +MessageManagerLock::MessageManagerLock (Thread* const thread) throw() { + jassert (thread != 0); // This will only work if you give it a valid thread! + if (MessageManager::instance != 0) + { + for (;;) + { + if (MessageManager::instance->messageDispatchLock.tryEnter()) + { + locked = true; + lastLockingThreadId = MessageManager::instance->currentLockingThreadId; + MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId(); + break; + } + + if (thread != 0 && thread->threadShouldExit()) + { + locked = false; + break; + } + + Thread::sleep (1); + } + } +} + +MessageManagerLock::~MessageManagerLock() throw() +{ + if (locked && MessageManager::instance != 0) { MessageManager::instance->currentLockingThreadId = lastLockingThreadId; MessageManager::instance->messageDispatchLock.exit(); diff --git a/src/juce_appframework/events/juce_MessageManager.h b/src/juce_appframework/events/juce_MessageManager.h index ed5ceb2727..e7514fe761 100644 --- a/src/juce_appframework/events/juce_MessageManager.h +++ b/src/juce_appframework/events/juce_MessageManager.h @@ -36,6 +36,7 @@ #include "../../juce_core/containers/juce_SortedSet.h" #include "juce_ActionListenerList.h" #include "juce_Timer.h" +class Thread; class InternalTimerThread; @@ -265,26 +266,74 @@ private: class JUCE_API MessageManagerLock { public: - /** Acquires a lock on the message manager. + //============================================================================== + /** Tries to acquire a lock on the message manager. - When this constuctor returns, the message manager will have finished sending the + If this constructor + When this constructor returns, the message manager will have finished processing the last message and will not send another message until this MessageManagerLock is deleted. If the current thread already has the lock, nothing will be done, so it's perfectly safe to create these locks recursively. */ - MessageManagerLock(); + MessageManagerLock() throw(); /** Releases the current thread's lock on the message manager. Make sure this object is created and deleted by the same thread, otherwise there are no guarantees what will happen! */ - ~MessageManagerLock(); + ~MessageManagerLock() throw(); + + //============================================================================== + /** Tries to acquire a lock on the message manager. + + This does the same thing as the normal constructor, but while it's waiting to get + the lock, it checks the specified thread to see if it has been given the + Thread::signalThreadShouldExit() signal. If this happens, then it will return + without gaining the lock. + + To find out whether the lock was successful, call lockWasGained(). If this is + false, your thread is being told to die, so you'd better get out of there. + + If the current thread already has the lock, nothing will be done, so it's perfectly + safe to create these locks recursively. + + E.g. + @code + void run() + { + ... + + while (! threadShouldExit()) + { + MessageManagerLock mml (Thread::getCurrentThread()); + + if (! mml.lockWasGained) + return; // another thread is trying to kill us! + + ..do some locked stuff here.. + } + + ..and now the MM is now unlocked.. + } + @endcode + + */ + MessageManagerLock (Thread* const threadToCheckForExitSignal) throw(); + + + /** Returns true if the lock was successfully acquired. + + (See the constructor that takes a Thread for more info). + */ + bool lockWasGained() const throw() { return locked; } + private: int lastLockingThreadId; + bool locked; }; diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp index eed60ee63a..b03d0e5c5c 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp @@ -591,7 +591,7 @@ void TreeView::keyPressed (const KeyPress& key) } } -void TreeView::itemsChanged() +void TreeView::itemsChanged() throw() { needsRecalculating = true; triggerAsyncUpdate(); @@ -733,7 +733,7 @@ void TreeViewItem::clearSubItems() } } -void TreeViewItem::addSubItem (TreeViewItem* newItem, int insertPosition) +void TreeViewItem::addSubItem (TreeViewItem* const newItem, const int insertPosition) { if (newItem != 0) { @@ -779,7 +779,7 @@ void TreeViewItem::removeSubItem (const int index, const bool deleteItem) ownerView->nodeAlterationLock.exit(); } -bool TreeViewItem::isOpen() const +bool TreeViewItem::isOpen() const throw() { if (openness == opennessDefault) return ownerView != 0 && ownerView->defaultOpenness; @@ -852,7 +852,7 @@ const String TreeViewItem::getDragSourceDescription() return String::empty; } -const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const +const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() { const int indentX = getIndentX(); @@ -870,7 +870,7 @@ const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopL return r; } -void TreeViewItem::treeHasChanged() const +void TreeViewItem::treeHasChanged() const throw() { if (ownerView != 0) ownerView->itemsChanged(); @@ -901,7 +901,7 @@ void TreeViewItem::updatePositions (int newY) } } -TreeViewItem* TreeViewItem::getDeepestOpenParentItem() +TreeViewItem* TreeViewItem::getDeepestOpenParentItem() throw() { TreeViewItem* result = this; TreeViewItem* item = this; @@ -917,7 +917,7 @@ TreeViewItem* TreeViewItem::getDeepestOpenParentItem() return result; } -void TreeViewItem::setOwnerView (TreeView* const newOwner) +void TreeViewItem::setOwnerView (TreeView* const newOwner) throw() { ownerView = newOwner; @@ -925,7 +925,7 @@ void TreeViewItem::setOwnerView (TreeView* const newOwner) subItems.getUnchecked(i)->setOwnerView (newOwner); } -int TreeViewItem::getIndentX() const +int TreeViewItem::getIndentX() const throw() { const int indentWidth = ownerView->getIndentSize(); int x = indentWidth; @@ -1039,7 +1039,7 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) } } -bool TreeViewItem::isLastOfSiblings() const +bool TreeViewItem::isLastOfSiblings() const throw() { return parentItem == 0 || parentItem->subItems.getLast() == this; @@ -1051,7 +1051,7 @@ TreeViewItem* TreeViewItem::getTopLevelItem() throw() : parentItem->getTopLevelItem(); } -int TreeViewItem::getNumRows() const +int TreeViewItem::getNumRows() const throw() { int num = 1; @@ -1064,7 +1064,7 @@ int TreeViewItem::getNumRows() const return num; } -TreeViewItem* TreeViewItem::getItemOnRow (int index) +TreeViewItem* TreeViewItem::getItemOnRow (int index) throw() { if (index == 0) return this; @@ -1092,7 +1092,7 @@ TreeViewItem* TreeViewItem::getItemOnRow (int index) return 0; } -TreeViewItem* TreeViewItem::findItemRecursively (int y) +TreeViewItem* TreeViewItem::findItemRecursively (int y) throw() { if (y >= 0 && y < totalHeight) { @@ -1120,7 +1120,7 @@ TreeViewItem* TreeViewItem::findItemRecursively (int y) return 0; } -int TreeViewItem::countSelectedItemsRecursively() const +int TreeViewItem::countSelectedItemsRecursively() const throw() { int total = 0; @@ -1133,7 +1133,7 @@ int TreeViewItem::countSelectedItemsRecursively() const return total; } -TreeViewItem* TreeViewItem::getSelectedItemWithIndex (int index) +TreeViewItem* TreeViewItem::getSelectedItemWithIndex (int index) throw() { if (isSelected()) { @@ -1161,7 +1161,7 @@ TreeViewItem* TreeViewItem::getSelectedItemWithIndex (int index) return 0; } -int TreeViewItem::getRowNumberInTree() const +int TreeViewItem::getRowNumberInTree() const throw() { if (parentItem != 0 && ownerView != 0) { @@ -1185,12 +1185,12 @@ int TreeViewItem::getRowNumberInTree() const } } -void TreeViewItem::setLinesDrawnForSubItems (const bool drawLines) +void TreeViewItem::setLinesDrawnForSubItems (const bool drawLines) throw() { drawLinesInside = drawLines; } -TreeViewItem* TreeViewItem::getNextVisibleItem (const bool recurse) const +TreeViewItem* TreeViewItem::getNextVisibleItem (const bool recurse) const throw() { if (recurse && isOpen() && subItems.size() > 0) return subItems [0]; diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.h b/src/juce_appframework/gui/components/controls/juce_TreeView.h index e08579f21f..0e8ba9ed9e 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.h +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.h @@ -90,8 +90,8 @@ public: @param insertPosition the index which the new item should have when it's added. If this value is less than 0, the item will be added to the end of the list. */ - void addSubItem (TreeViewItem* newItem, - int insertPosition = -1); + void addSubItem (TreeViewItem* const newItem, + const int insertPosition = -1); /** Removes one of the sub-items. @@ -110,7 +110,7 @@ public: //============================================================================== /** True if this item is currently open in the treeview. */ - bool isOpen() const; + bool isOpen() const throw(); /** Opens or closes the item. @@ -142,14 +142,14 @@ public: the tree. If false, it is relative to the top-left of the topmost item in the tree (so this would be unaffected by scrolling the view). */ - const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const; + const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const throw(); /** Sends a signal to the treeview to make it refresh itself. Call this if your items have changed and you want the tree to update to reflect this. */ - void treeHasChanged() const; + void treeHasChanged() const throw(); /** Returns the row number of this item in the tree. @@ -157,13 +157,13 @@ public: @see TreeView::getNumRowsInTree(), TreeView::getItemOnRow() */ - int getRowNumberInTree() const; + int getRowNumberInTree() const throw(); /** Changes whether lines are drawn to connect any sub-items to this item. By default, line-drawing is turned on. */ - void setLinesDrawnForSubItems (const bool shouldDrawLines); + void setLinesDrawnForSubItems (const bool shouldDrawLines) throw(); //============================================================================== /** Tells the tree whether this item can potentially be opened. @@ -343,21 +343,21 @@ private: friend class TreeViewContentComponent; void updatePositions (int newY); - int getIndentX() const; - void setOwnerView (TreeView* const newOwner); + int getIndentX() const throw(); + void setOwnerView (TreeView* const newOwner) throw(); void paintRecursively (Graphics& g, int width); - TreeViewItem* findItemRecursively (int y); - TreeViewItem* getDeepestOpenParentItem(); + TreeViewItem* findItemRecursively (int y) throw(); + TreeViewItem* getDeepestOpenParentItem() throw(); void restoreFromXml (const XmlElement& e); XmlElement* createXmlOpenness() const; - bool isLastOfSiblings() const; + bool isLastOfSiblings() const throw(); TreeViewItem* getTopLevelItem() throw(); - int getNumRows() const; - TreeViewItem* getItemOnRow (int index); + int getNumRows() const throw(); + TreeViewItem* getItemOnRow (int index) throw(); void deselectAllRecursively(); - int countSelectedItemsRecursively() const; - TreeViewItem* getSelectedItemWithIndex (int index); - TreeViewItem* getNextVisibleItem (const bool recurse) const; + int countSelectedItemsRecursively() const throw(); + TreeViewItem* getSelectedItemWithIndex (int index) throw(); + TreeViewItem* getNextVisibleItem (const bool recurse) const throw(); TreeViewItem (const TreeViewItem&); const TreeViewItem& operator= (const TreeViewItem&); @@ -521,6 +521,8 @@ public: include information about where the tree has been scrolled to vertically, so this can also be restored + @param alsoIncludeSelectionState if this is true, the selected items will + also be stored in the state that is returned @see restoreOpennessState */ XmlElement* getOpennessState (const bool alsoIncludeScrollPosition) const; @@ -573,7 +575,7 @@ private: bool rootItemVisible : 1; bool multiSelectEnabled : 1; - void itemsChanged(); + void itemsChanged() throw(); void handleAsyncUpdate(); void moveSelectedRow (int delta); diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp index 2c241b32a6..c28efca910 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp @@ -58,7 +58,8 @@ FileBrowserComponent::FileBrowserComponent (FileChooserMode mode_, const File& initialFileOrDirectory, const FileFilter* fileFilter, FilePreviewComponent* previewComp_, - const bool useTreeView) + const bool useTreeView, + const bool filenameTextBoxIsReadOnly) : directoriesOnlyFilter (0), mode (mode_), listeners (2), @@ -124,6 +125,7 @@ FileBrowserComponent::FileBrowserComponent (FileChooserMode mode_, filenameBox->setSelectAllWhenFocused (true); filenameBox->setText (filename, false); filenameBox->addListener (this); + filenameBox->setReadOnly (filenameTextBoxIsReadOnly); Label* label = new Label (T("f"), (mode == chooseDirectoryMode) ? TRANS("folder:") : TRANS("file:")); diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h index 81d3fb51fb..9a689a02c0 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h @@ -96,7 +96,8 @@ public: const File& initialFileOrDirectory, const FileFilter* fileFilter, FilePreviewComponent* previewComp, - const bool useTreeView = false); + const bool useTreeView = false, + const bool filenameTextBoxIsReadOnly = false); /** Destructor. */ ~FileBrowserComponent(); diff --git a/src/juce_appframework/gui/components/juce_Component.cpp b/src/juce_appframework/gui/components/juce_Component.cpp index cc1f9be3c1..ab240a77a2 100644 --- a/src/juce_appframework/gui/components/juce_Component.cpp +++ b/src/juce_appframework/gui/components/juce_Component.cpp @@ -2103,7 +2103,7 @@ void Component::parentSizeChanged() // base class does nothing } -void Component::addComponentListener (ComponentListener* const newListener) +void Component::addComponentListener (ComponentListener* const newListener) throw() { if (componentListeners_ == 0) componentListeners_ = new VoidArray (4); @@ -2111,7 +2111,7 @@ void Component::addComponentListener (ComponentListener* const newListener) componentListeners_->addIfNotAlreadyThere (newListener); } -void Component::removeComponentListener (ComponentListener* const listenerToRemove) +void Component::removeComponentListener (ComponentListener* const listenerToRemove) throw() { jassert (isValidComponent()); diff --git a/src/juce_appframework/gui/components/juce_Component.h b/src/juce_appframework/gui/components/juce_Component.h index c032a4d8cc..117d8281d4 100644 --- a/src/juce_appframework/gui/components/juce_Component.h +++ b/src/juce_appframework/gui/components/juce_Component.h @@ -1683,13 +1683,13 @@ public: will be ignored. @see ComponentListener, removeComponentListener */ - void addComponentListener (ComponentListener* const newListener); + void addComponentListener (ComponentListener* const newListener) throw(); /** Removes a component listener. @see addComponentListener */ - void removeComponentListener (ComponentListener* const listenerToRemove); + void removeComponentListener (ComponentListener* const listenerToRemove) throw(); //============================================================================== /** Called when files are dragged-and-dropped onto this component. diff --git a/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.cpp b/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.cpp index 3614623c4d..815edae655 100644 --- a/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.cpp +++ b/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.cpp @@ -38,7 +38,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -ComponentBoundsConstrainer::ComponentBoundsConstrainer() +ComponentBoundsConstrainer::ComponentBoundsConstrainer() throw() : minW (0), maxW (0), minH (0x3fffffff), @@ -56,27 +56,27 @@ ComponentBoundsConstrainer::~ComponentBoundsConstrainer() } //============================================================================== -void ComponentBoundsConstrainer::setMinimumWidth (const int minimumWidth) +void ComponentBoundsConstrainer::setMinimumWidth (const int minimumWidth) throw() { minW = minimumWidth; } -void ComponentBoundsConstrainer::setMaximumWidth (const int maximumWidth) +void ComponentBoundsConstrainer::setMaximumWidth (const int maximumWidth) throw() { maxW = maximumWidth; } -void ComponentBoundsConstrainer::setMinimumHeight (const int minimumHeight) +void ComponentBoundsConstrainer::setMinimumHeight (const int minimumHeight) throw() { minH = minimumHeight; } -void ComponentBoundsConstrainer::setMaximumHeight (const int maximumHeight) +void ComponentBoundsConstrainer::setMaximumHeight (const int maximumHeight) throw() { maxH = maximumHeight; } -void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const int minimumHeight) +void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const int minimumHeight) throw() { jassert (maxW >= minimumWidth); jassert (maxH >= minimumHeight); @@ -92,7 +92,7 @@ void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const i maxH = minH; } -void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const int maximumHeight) +void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const int maximumHeight) throw() { jassert (maximumWidth >= minW); jassert (maximumHeight >= minH); @@ -105,7 +105,7 @@ void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const i void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth, const int minimumHeight, const int maximumWidth, - const int maximumHeight) + const int maximumHeight) throw() { jassert (maximumWidth >= minimumWidth); jassert (maximumHeight >= minimumHeight); @@ -121,7 +121,7 @@ void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth, void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhenOffTheTop, const int minimumWhenOffTheLeft, const int minimumWhenOffTheBottom, - const int minimumWhenOffTheRight) + const int minimumWhenOffTheRight) throw() { minOffTop = minimumWhenOffTheTop; minOffLeft = minimumWhenOffTheLeft; @@ -129,7 +129,7 @@ void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhe minOffRight = minimumWhenOffTheRight; } -void ComponentBoundsConstrainer::setFixedAspectRatio (const double widthOverHeight) +void ComponentBoundsConstrainer::setFixedAspectRatio (const double widthOverHeight) throw() { aspectRatio = jmax (0.0, widthOverHeight); } diff --git a/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h b/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h index 121205fe95..6b8ac482a3 100644 --- a/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h +++ b/src/juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h @@ -52,49 +52,49 @@ class JUCE_API ComponentBoundsConstrainer public: //============================================================================== /** When first created, the object will not impose any restrictions on the components. */ - ComponentBoundsConstrainer(); + ComponentBoundsConstrainer() throw(); /** Destructor. */ virtual ~ComponentBoundsConstrainer(); //============================================================================== /** Imposes a minimum width limit. */ - void setMinimumWidth (const int minimumWidth); + void setMinimumWidth (const int minimumWidth) throw(); /** Returns the current minimum width. */ int getMinimumWidth() const throw() { return minW; } /** Imposes a maximum width limit. */ - void setMaximumWidth (const int maximumWidth); + void setMaximumWidth (const int maximumWidth) throw(); /** Returns the current maximum width. */ int getMaximumWidth() const throw() { return maxW; } /** Imposes a minimum height limit. */ - void setMinimumHeight (const int minimumHeight); + void setMinimumHeight (const int minimumHeight) throw(); /** Returns the current minimum height. */ int getMinimumHeight() const throw() { return minH; } /** Imposes a maximum height limit. */ - void setMaximumHeight (const int maximumHeight); + void setMaximumHeight (const int maximumHeight) throw(); /** Returns the current maximum height. */ int getMaximumHeight() const throw() { return maxH; } /** Imposes a minimum width and height limit. */ void setMinimumSize (const int minimumWidth, - const int minimumHeight); + const int minimumHeight) throw(); /** Imposes a maximum width and height limit. */ void setMaximumSize (const int maximumWidth, - const int maximumHeight); + const int maximumHeight) throw(); /** Set all the maximum and minimum dimensions. */ void setSizeLimits (const int minimumWidth, const int minimumHeight, const int maximumWidth, - const int maximumHeight); + const int maximumHeight) throw(); //============================================================================== /** Sets the amount by which the component is allowed to go off-screen. @@ -116,7 +116,7 @@ public: void setMinimumOnscreenAmounts (const int minimumWhenOffTheTop, const int minimumWhenOffTheLeft, const int minimumWhenOffTheBottom, - const int minimumWhenOffTheRight); + const int minimumWhenOffTheRight) throw(); //============================================================================== /** Specifies a width-to-height ratio that the resizer should always maintain. @@ -126,7 +126,7 @@ public: @see setResizeLimits */ - void setFixedAspectRatio (const double widthOverHeight); + void setFixedAspectRatio (const double widthOverHeight) throw(); /** Returns the aspect ratio that was set with setFixedAspectRatio(). diff --git a/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.cpp b/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.cpp index b5ee66b6ce..4a14cef107 100644 --- a/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.cpp +++ b/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.cpp @@ -125,7 +125,7 @@ void ComponentMovementWatcher::componentMovedOrResized (Component&, bool wasMove componentMovedOrResized (wasMoved, wasResized); } -void ComponentMovementWatcher::registerWithParentComps() +void ComponentMovementWatcher::registerWithParentComps() throw() { Component* p = component->getParentComponent(); @@ -137,7 +137,7 @@ void ComponentMovementWatcher::registerWithParentComps() } } -void ComponentMovementWatcher::unregister() +void ComponentMovementWatcher::unregister() throw() { for (int i = registeredParentComps.size(); --i >= 0;) ((Component*) registeredParentComps.getUnchecked(i))->removeComponentListener (this); diff --git a/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h b/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h index 92b7500df4..1f856b591d 100644 --- a/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h +++ b/src/juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h @@ -92,8 +92,8 @@ private: ComponentDeletionWatcher* deletionWatcher; #endif - void unregister(); - void registerWithParentComps(); + void unregister() throw(); + void registerWithParentComps() throw(); ComponentMovementWatcher (const ComponentMovementWatcher&); const ComponentMovementWatcher& operator= (const ComponentMovementWatcher&); diff --git a/src/juce_appframework/gui/components/layout/juce_GroupComponent.cpp b/src/juce_appframework/gui/components/layout/juce_GroupComponent.cpp index a18a3987ea..fee7362deb 100644 --- a/src/juce_appframework/gui/components/layout/juce_GroupComponent.cpp +++ b/src/juce_appframework/gui/components/layout/juce_GroupComponent.cpp @@ -52,7 +52,7 @@ GroupComponent::~GroupComponent() } //============================================================================== -void GroupComponent::setText (const String& newText) +void GroupComponent::setText (const String& newText) throw() { if (text != newText) { @@ -61,7 +61,7 @@ void GroupComponent::setText (const String& newText) } } -const String GroupComponent::getText() const +const String GroupComponent::getText() const throw() { return text; } diff --git a/src/juce_appframework/gui/components/layout/juce_GroupComponent.h b/src/juce_appframework/gui/components/layout/juce_GroupComponent.h index 8a91770b24..20c6cbbd0d 100644 --- a/src/juce_appframework/gui/components/layout/juce_GroupComponent.h +++ b/src/juce_appframework/gui/components/layout/juce_GroupComponent.h @@ -58,10 +58,10 @@ public: //============================================================================== /** Changes the text that's shown at the top of the component. */ - void setText (const String& newText); + void setText (const String& newText) throw(); /** Returns the currently displayed text label. */ - const String getText() const; + const String getText() const throw(); /** Sets the positioning of the text label. diff --git a/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.cpp b/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.cpp index 83f06d9bca..f125bc0c77 100644 --- a/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.cpp +++ b/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.cpp @@ -34,71 +34,65 @@ BEGIN_JUCE_NAMESPACE #include "juce_MultiDocumentPanel.h" -#include "../windows/juce_DocumentWindow.h" #include "../lookandfeel/juce_LookAndFeel.h" //============================================================================== -class MDIDocumentWindowInternal : public DocumentWindow +MultiDocumentPanelWindow::MultiDocumentPanelWindow (const Colour& backgroundColour) + : DocumentWindow (String::empty, backgroundColour, + DocumentWindow::maximiseButton | DocumentWindow::closeButton, false) { -public: - //============================================================================== - MDIDocumentWindowInternal (const Colour& backgroundColour) - : DocumentWindow (String::empty, backgroundColour, - DocumentWindow::maximiseButton | DocumentWindow::closeButton, false) - { - } +} - ~MDIDocumentWindowInternal() - { - } +MultiDocumentPanelWindow::~MultiDocumentPanelWindow() +{ +} - //============================================================================== - void maximiseButtonPressed() - { - MultiDocumentPanel* const owner = getOwner(); +//============================================================================== +void MultiDocumentPanelWindow::maximiseButtonPressed() +{ + MultiDocumentPanel* const owner = getOwner(); - jassert (owner != 0); - if (owner != 0) - owner->setLayoutMode (MultiDocumentPanel::MaximisedWindowsWithTabs); - } + jassert (owner != 0); // these windows are only designed to be used inside a MultiDocumentPanel! + if (owner != 0) + owner->setLayoutMode (MultiDocumentPanel::MaximisedWindowsWithTabs); +} - void closeButtonPressed() - { - MultiDocumentPanel* const owner = getOwner(); +void MultiDocumentPanelWindow::closeButtonPressed() +{ + MultiDocumentPanel* const owner = getOwner(); - jassert (owner != 0); - if (owner != 0) - owner->closeDocument (getContentComponent(), true); - } + jassert (owner != 0); // these windows are only designed to be used inside a MultiDocumentPanel! + if (owner != 0) + owner->closeDocument (getContentComponent(), true); +} - void activeWindowStatusChanged() - { - DocumentWindow::activeWindowStatusChanged(); - updateOrder(); - } +void MultiDocumentPanelWindow::activeWindowStatusChanged() +{ + DocumentWindow::activeWindowStatusChanged(); + updateOrder(); +} - void broughtToFront() - { - DocumentWindow::broughtToFront(); - updateOrder(); - } +void MultiDocumentPanelWindow::broughtToFront() +{ + DocumentWindow::broughtToFront(); + updateOrder(); +} -private: - void updateOrder() - { - MultiDocumentPanel* const owner = getOwner(); +void MultiDocumentPanelWindow::updateOrder() +{ + MultiDocumentPanel* const owner = getOwner(); - if (owner != 0) - owner->updateOrder(); - } + if (owner != 0) + owner->updateOrder(); +} + +MultiDocumentPanel* MultiDocumentPanelWindow::getOwner() const throw() +{ + // (unable to use the syntax findParentComponentOfClass () because of a VC6 compiler bug) + return findParentComponentOfClass ((MultiDocumentPanel*) 0); +} - MultiDocumentPanel* getOwner() const throw() - { - // (unable to use the syntax findParentComponentOfClass () because of a VC6 compiler bug) - return findParentComponentOfClass ((MultiDocumentPanel*) 0); - } -}; //============================================================================== class MDITabbedComponentInternal : public TabbedComponent @@ -155,9 +149,14 @@ bool MultiDocumentPanel::closeAllDocuments (const bool checkItsOkToCloseFirst) return true; } +MultiDocumentPanelWindow* MultiDocumentPanel::createNewDocumentWindow() +{ + return new MultiDocumentPanelWindow (backgroundColour); +} + void MultiDocumentPanel::addWindow (Component* component) { - MDIDocumentWindowInternal* const dw = new MDIDocumentWindowInternal (backgroundColour); + MultiDocumentPanelWindow* const dw = createNewDocumentWindow(); dw->setResizable (true, false); dw->setContentComponent (component, false, true); @@ -258,7 +257,7 @@ bool MultiDocumentPanel::closeDocument (Component* component, { for (int i = getNumChildComponents(); --i >= 0;) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0 && dw->getContentComponent() == component) { @@ -277,7 +276,7 @@ bool MultiDocumentPanel::closeDocument (Component* component, { for (int i = getNumChildComponents(); --i >= 0;) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0) { @@ -343,7 +342,7 @@ Component* MultiDocumentPanel::getActiveDocument() const throw() { for (int i = getNumChildComponents(); --i >= 0;) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0 && dw->isActiveWindow()) return dw->getContentComponent(); @@ -415,7 +414,7 @@ void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode) { for (int i = getNumChildComponents(); --i >= 0;) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0) { @@ -474,7 +473,7 @@ Component* MultiDocumentPanel::getContainerComp (Component* c) const { for (int i = 0; i < getNumChildComponents(); ++i) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0 && dw->getContentComponent() == c) { @@ -493,7 +492,7 @@ void MultiDocumentPanel::componentNameChanged (Component&) { for (int i = 0; i < getNumChildComponents(); ++i) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0) dw->setName (dw->getContentComponent()->getName()); @@ -508,7 +507,7 @@ void MultiDocumentPanel::componentNameChanged (Component&) void MultiDocumentPanel::updateOrder() { - Array oldList (components); + const Array oldList (components); if (mode == FloatingWindows) { @@ -516,7 +515,7 @@ void MultiDocumentPanel::updateOrder() for (int i = 0; i < getNumChildComponents(); ++i) { - MDIDocumentWindowInternal* const dw = dynamic_cast (getChildComponent (i)); + MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); if (dw != 0) components.add (dw->getContentComponent()); diff --git a/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h b/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h index d7dc912bf4..36380b4edb 100644 --- a/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h +++ b/src/juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h @@ -33,10 +33,51 @@ #define __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__ #include "juce_TabbedComponent.h" -class MDIDocumentWindowInternal; +#include "../windows/juce_DocumentWindow.h" +class MultiDocumentPanel; class MDITabbedComponentInternal; +//============================================================================== +/** + This is a derivative of DocumentWindow that is used inside a MultiDocumentPanel + component. + + It's like a normal DocumentWindow but has some extra functionality to make sure + everything works nicely inside a MultiDocumentPanel. + + @see MultiDocumentPanel +*/ +class JUCE_API MultiDocumentPanelWindow : public DocumentWindow +{ +public: + //============================================================================== + /** + */ + MultiDocumentPanelWindow (const Colour& backgroundColour); + + /** Destructor. */ + ~MultiDocumentPanelWindow(); + + //============================================================================== + /** @internal */ + void maximiseButtonPressed(); + /** @internal */ + void closeButtonPressed(); + /** @internal */ + void activeWindowStatusChanged(); + /** @internal */ + void broughtToFront(); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + void updateOrder(); + MultiDocumentPanel* getOwner() const throw(); +}; + + //============================================================================== /** A component that contains a set of other components either in floating windows @@ -229,6 +270,13 @@ public: */ virtual bool tryToCloseDocument (Component* component) = 0; + /** Creates a new window to be used for a document. + + The default implementation of this just returns a basic MultiDocumentPanelWindow object, + but you might want to override it to return a custom component. + */ + virtual MultiDocumentPanelWindow* createNewDocumentWindow(); + //============================================================================== /** @internal */ void paint (Graphics& g); @@ -248,7 +296,7 @@ private: Colour backgroundColour; int maximumNumDocuments, numDocsBeforeTabsUsed; - friend class MDIDocumentWindowInternal; + friend class MultiDocumentPanelWindow; friend class MDITabbedComponentInternal; Component* getContainerComp (Component* c) const; diff --git a/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.cpp b/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.cpp index 39af61b1ad..141d244a13 100644 --- a/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.cpp +++ b/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.cpp @@ -153,7 +153,7 @@ bool ResizableBorderComponent::hitTest (int x, int y) || y >= getHeight() - borderSize.getBottom(); } -void ResizableBorderComponent::setBorderThickness (const BorderSize& newBorderSize) +void ResizableBorderComponent::setBorderThickness (const BorderSize& newBorderSize) throw() { if (borderSize != newBorderSize) { @@ -162,12 +162,12 @@ void ResizableBorderComponent::setBorderThickness (const BorderSize& newBorderSi } } -const BorderSize ResizableBorderComponent::getBorderThickness() const +const BorderSize ResizableBorderComponent::getBorderThickness() const throw() { return borderSize; } -void ResizableBorderComponent::updateMouseZone (const MouseEvent& e) +void ResizableBorderComponent::updateMouseZone (const MouseEvent& e) throw() { int newZone = 0; diff --git a/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h b/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h index 1ceaf560f7..adc2be40fe 100644 --- a/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h +++ b/src/juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h @@ -84,13 +84,13 @@ public: @see getBorderThickness */ - void setBorderThickness (const BorderSize& newBorderSize); + void setBorderThickness (const BorderSize& newBorderSize) throw(); /** Returns the number of pixels wide that the draggable edges of this component are. @see setBorderThickness */ - const BorderSize getBorderThickness() const; + const BorderSize getBorderThickness() const throw(); //============================================================================== @@ -119,7 +119,7 @@ private: int originalX, originalY, originalW, originalH; int mouseZone; - void updateMouseZone (const MouseEvent& e); + void updateMouseZone (const MouseEvent& e) throw(); ResizableBorderComponent (const ResizableBorderComponent&); const ResizableBorderComponent& operator= (const ResizableBorderComponent&); diff --git a/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp b/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp index c30e43a12e..fadaf45b4a 100644 --- a/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp +++ b/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp @@ -119,7 +119,7 @@ ScrollBar::~ScrollBar() //============================================================================== void ScrollBar::setRangeLimits (const double newMinimum, - const double newMaximum) + const double newMaximum) throw() { minimum = newMinimum; maximum = newMaximum; diff --git a/src/juce_appframework/gui/components/layout/juce_ScrollBar.h b/src/juce_appframework/gui/components/layout/juce_ScrollBar.h index 8d3a054b2d..a15b070456 100644 --- a/src/juce_appframework/gui/components/layout/juce_ScrollBar.h +++ b/src/juce_appframework/gui/components/layout/juce_ScrollBar.h @@ -125,7 +125,7 @@ public: @see setCurrentRange */ void setRangeLimits (const double minimum, - const double maximum); + const double maximum) throw(); /** Returns the lower value that the thumb can be set to. diff --git a/src/juce_appframework/gui/components/menus/juce_PopupMenu.cpp b/src/juce_appframework/gui/components/menus/juce_PopupMenu.cpp index 887077ca08..0249f4616c 100644 --- a/src/juce_appframework/gui/components/menus/juce_PopupMenu.cpp +++ b/src/juce_appframework/gui/components/menus/juce_PopupMenu.cpp @@ -292,7 +292,7 @@ class PopupMenuWindow : public Component, { public: //============================================================================== - PopupMenuWindow() + PopupMenuWindow() throw() : Component (T("menu")), owner (0), currentChild (0), @@ -356,7 +356,7 @@ public: const int itemIdThatMustBeVisible, Component* const menuBarComponent, ApplicationCommandManager** managerOfChosenCommand, - Component* const componentAttachedTo) + Component* const componentAttachedTo) throw() { if (menu.items.size() > 0) { @@ -1313,13 +1313,13 @@ private: //============================================================================== -PopupMenu::PopupMenu() +PopupMenu::PopupMenu() throw() : items (8), lookAndFeel (0) { } -PopupMenu::PopupMenu (const PopupMenu& other) +PopupMenu::PopupMenu (const PopupMenu& other) throw() : items (8), lookAndFeel (other.lookAndFeel) { @@ -1329,7 +1329,7 @@ PopupMenu::PopupMenu (const PopupMenu& other) items.add (new MenuItemInfo (*(const MenuItemInfo*) other.items.getUnchecked(i))); } -const PopupMenu& PopupMenu::operator= (const PopupMenu& other) +const PopupMenu& PopupMenu::operator= (const PopupMenu& other) throw() { if (this != &other) { @@ -1345,12 +1345,12 @@ const PopupMenu& PopupMenu::operator= (const PopupMenu& other) return *this; } -PopupMenu::~PopupMenu() +PopupMenu::~PopupMenu() throw() { clear(); } -void PopupMenu::clear() +void PopupMenu::clear() throw() { for (int i = items.size(); --i >= 0;) { @@ -1365,7 +1365,7 @@ void PopupMenu::addItem (const int itemResultId, const String& itemText, const bool isActive, const bool isTicked, - const Image* const iconToUse) + const Image* const iconToUse) throw() { jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user // didn't pick anything, so you shouldn't use it as the id @@ -1383,7 +1383,7 @@ void PopupMenu::addItem (const int itemResultId, void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager, const int commandID, - const String& displayName) + const String& displayName) throw() { jassert (commandManager != 0 && commandID != 0); @@ -1412,7 +1412,7 @@ void PopupMenu::addColouredItem (const int itemResultId, const Colour& itemTextColour, const bool isActive, const bool isTicked, - const Image* const iconToUse) + const Image* const iconToUse) throw() { jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user // didn't pick anything, so you shouldn't use it as the id @@ -1430,7 +1430,7 @@ void PopupMenu::addColouredItem (const int itemResultId, //============================================================================== void PopupMenu::addCustomItem (const int itemResultId, - PopupMenuCustomComponent* const customComponent) + PopupMenuCustomComponent* const customComponent) throw() { jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user // didn't pick anything, so you shouldn't use it as the id @@ -1486,7 +1486,7 @@ private: void PopupMenu::addCustomItem (const int itemResultId, Component* customComponent, int idealWidth, int idealHeight, - const bool triggerMenuItemAutomaticallyWhenClicked) + const bool triggerMenuItemAutomaticallyWhenClicked) throw() { addCustomItem (itemResultId, new NormalComponentWrapper (customComponent, @@ -1498,7 +1498,7 @@ void PopupMenu::addCustomItem (const int itemResultId, void PopupMenu::addSubMenu (const String& subMenuName, const PopupMenu& subMenu, const bool isActive, - Image* const iconToUse) + Image* const iconToUse) throw() { items.add (new MenuItemInfo (0, subMenuName, @@ -1512,7 +1512,7 @@ void PopupMenu::addSubMenu (const String& subMenuName, 0)); } -void PopupMenu::addSeparator() +void PopupMenu::addSeparator() throw() { items.add (new MenuItemInfo()); } @@ -1556,7 +1556,7 @@ public: juce_UseDebuggingNewOperator }; -void PopupMenu::addSectionHeader (const String& title) +void PopupMenu::addSectionHeader (const String& title) throw() { addCustomItem (0X4734a34f, new HeaderItemComponent (title)); } @@ -1570,7 +1570,7 @@ Component* PopupMenu::createMenuComponent (const int x, const int y, const int w const bool alignToRectangle, Component* menuBarComponent, ApplicationCommandManager** managerOfChosenCommand, - Component* const componentAttachedTo) + Component* const componentAttachedTo) throw() { PopupMenuWindow* const pw = PopupMenuWindow::create (*this, @@ -1599,7 +1599,7 @@ int PopupMenu::showMenu (const int x, const int y, const int w, const int h, const int maximumNumColumns, const int standardItemHeight, const bool alignToRectangle, - Component* const componentAttachedTo) + Component* const componentAttachedTo) throw() { Component* const prevFocused = Component::getCurrentlyFocusedComponent(); @@ -1728,7 +1728,7 @@ void JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() throw() } //============================================================================== -int PopupMenu::getNumItems() const +int PopupMenu::getNumItems() const throw() { int num = 0; @@ -1739,7 +1739,7 @@ int PopupMenu::getNumItems() const return num; } -bool PopupMenu::containsCommandItem (const int commandID) const +bool PopupMenu::containsCommandItem (const int commandID) const throw() { for (int i = items.size(); --i >= 0;) { @@ -1755,7 +1755,7 @@ bool PopupMenu::containsCommandItem (const int commandID) const return false; } -void PopupMenu::setLookAndFeel (LookAndFeel* const newLookAndFeel) +void PopupMenu::setLookAndFeel (LookAndFeel* const newLookAndFeel) throw() { lookAndFeel = newLookAndFeel; } diff --git a/src/juce_appframework/gui/components/menus/juce_PopupMenu.h b/src/juce_appframework/gui/components/menus/juce_PopupMenu.h index 21932ea338..24a1add5b0 100644 --- a/src/juce_appframework/gui/components/menus/juce_PopupMenu.h +++ b/src/juce_appframework/gui/components/menus/juce_PopupMenu.h @@ -89,20 +89,20 @@ class JUCE_API PopupMenu public: //============================================================================== /** Creates an empty popup menu. */ - PopupMenu(); + PopupMenu() throw(); /** Creates a copy of another menu. */ - PopupMenu (const PopupMenu& other); + PopupMenu (const PopupMenu& other) throw(); /** Destructor. */ - ~PopupMenu(); + ~PopupMenu() throw(); /** Copies this menu from another one. */ - const PopupMenu& operator= (const PopupMenu& other); + const PopupMenu& operator= (const PopupMenu& other) throw(); //============================================================================== /** Resets the menu, removing all its items. */ - void clear(); + void clear() throw(); /** Appends a new text item for this menu to show. @@ -125,7 +125,7 @@ public: const String& itemText, const bool isActive = true, const bool isTicked = false, - const Image* const iconToUse = 0); + const Image* const iconToUse = 0) throw(); /** Adds an item that represents one of the commands in a command manager object. @@ -137,7 +137,7 @@ public: */ void addCommandItem (ApplicationCommandManager* commandManager, const int commandID, - const String& displayName = String::empty); + const String& displayName = String::empty) throw(); /** Appends a text item with a special colour. @@ -151,7 +151,7 @@ public: const Colour& itemTextColour, const bool isActive = true, const bool isTicked = false, - const Image* const iconToUse = 0); + const Image* const iconToUse = 0) throw(); /** Appends a custom menu item. @@ -161,7 +161,7 @@ public: @see PopupMenuCustomComponent */ void addCustomItem (const int itemResultId, - PopupMenuCustomComponent* const customComponent); + PopupMenuCustomComponent* const customComponent) throw(); /** Appends a custom menu item that can't be used to trigger a result. @@ -181,7 +181,7 @@ public: void addCustomItem (const int itemResultId, Component* customComponent, int idealWidth, int idealHeight, - const bool triggerMenuItemAutomaticallyWhenClicked); + const bool triggerMenuItemAutomaticallyWhenClicked) throw(); /** Appends a sub-menu. @@ -190,7 +190,7 @@ public: void addSubMenu (const String& subMenuName, const PopupMenu& subMenu, const bool isActive = true, - Image* const iconToUse = 0); + Image* const iconToUse = 0) throw(); /** Appends a separator to the menu, to help break it up into sections. @@ -199,23 +199,23 @@ public: one, so your code can be quite free and easy about adding these, and it'll always look ok. */ - void addSeparator(); + void addSeparator() throw(); /** Adds a non-clickable text item to the menu. This is a bold-font items which can be used as a header to separate the items into named groups. */ - void addSectionHeader (const String& title); + void addSectionHeader (const String& title) throw(); /** Returns the number of items that the menu currently contains. (This doesn't count separators). */ - int getNumItems() const; + int getNumItems() const throw(); /** Returns true if the menu contains a command item that triggers the given command. */ - bool containsCommandItem (const int commandID) const; + bool containsCommandItem (const int commandID) const throw(); //============================================================================== @@ -294,7 +294,7 @@ public: This can be called before show() if you need a customised menu. Be careful not to delete the LookAndFeel object before the menu has been deleted. */ - void setLookAndFeel (LookAndFeel* const newLookAndFeel); + void setLookAndFeel (LookAndFeel* const newLookAndFeel) throw(); //============================================================================== /** A set of colour IDs to use to change the colour of various aspects of the menu. @@ -386,7 +386,7 @@ private: const int maximumNumColumns, const int standardItemHeight, const bool alignToRectangle, - Component* const componentAttachedTo); + Component* const componentAttachedTo) throw(); friend class MenuBarComponent; Component* createMenuComponent (const int x, const int y, const int w, const int h, @@ -397,7 +397,7 @@ private: const bool alignToRectangle, Component* menuBarComponent, ApplicationCommandManager** managerOfChosenCommand, - Component* const componentAttachedTo); + Component* const componentAttachedTo) throw(); }; #endif // __JUCE_POPUPMENU_JUCEHEADER__ diff --git a/src/juce_core/threads/juce_Thread.cpp b/src/juce_core/threads/juce_Thread.cpp index 29d6613bcd..b6ddd67adc 100644 --- a/src/juce_core/threads/juce_Thread.cpp +++ b/src/juce_core/threads/juce_Thread.cpp @@ -236,6 +236,29 @@ int Thread::getNumRunningThreads() throw() return runningThreads.size(); } +Thread* Thread::getCurrentThread() throw() +{ + const int thisId = getCurrentThreadId(); + Thread* result = 0; + + runningThreadsLock.enter(); + + for (int i = runningThreads.size(); --i >= 0;) + { + Thread* const t = (Thread*) (runningThreads.getUnchecked(i)); + + if (t->threadId_ == thisId) + { + result = t; + break; + } + } + + runningThreadsLock.exit(); + + return result; +} + void Thread::stopAllThreads (const int timeoutInMillisecs) throw() { while (getNumRunningThreads() > 0) diff --git a/src/juce_core/threads/juce_Thread.h b/src/juce_core/threads/juce_Thread.h index 91f9d65894..eb9a5ab1bc 100644 --- a/src/juce_core/threads/juce_Thread.h +++ b/src/juce_core/threads/juce_Thread.h @@ -225,6 +225,13 @@ public: */ static int getCurrentThreadId() throw(); + /** Finds the thread object that is currently running. + + Note that the main UI thread (or other non-Juce threads) don't have a Thread + object associated with them, so this will return 0. + */ + static Thread* getCurrentThread() throw(); + /** Returns the ID of this thread. That means the ID of this thread object - not of the thread that's calling the method.