From 0926af719f2e868d1f528f78ee0a7426744917b1 Mon Sep 17 00:00:00 2001 From: jules Date: Mon, 18 Jun 2007 19:10:56 +0000 Subject: [PATCH] added FileTreeComponent and DirectoryContentsDisplayComponent. --- build/linux/JUCE.make | 12 + .../juce_linux_Windowing.cpp | 4 +- build/macosx/Juce.xcodeproj/project.pbxproj | 22 +- .../juce_win32_ASIO.cpp | 6 +- build/win32/vc8/JUCE.vcproj | 16 + docs/JUCE changelist.txt | 6 +- .../macosx/jucedemo.xcodeproj/project.pbxproj | 12 +- extras/juce demo/src/BinaryData.cpp | 308 ++++---- extras/juce demo/src/BinaryData.h | 4 +- .../juce demo/src/binarydata/OpenGLDemo.cpp | 2 +- .../juce demo/src/binarydata/TreeViewDemo.cpp | 94 ++- extras/juce demo/src/demos/TreeViewDemo.cpp | 94 ++- .../src/model/jucer_JucerDocument.cpp | 2 +- src/juce_app_includes.h | 6 + .../audio/dsp/juce_AudioDataConverters.cpp | 16 +- .../events/juce_ChangeBroadcaster.cpp | 16 +- .../events/juce_ChangeBroadcaster.h | 14 +- .../events/juce_ChangeListenerList.cpp | 16 +- .../events/juce_ChangeListenerList.h | 16 +- .../components/controls/juce_TextEditor.cpp | 4 +- .../gui/components/controls/juce_TreeView.cpp | 6 + .../gui/components/controls/juce_TreeView.h | 8 +- ...juce_DirectoryContentsDisplayComponent.cpp | 590 +-------------- .../juce_DirectoryContentsDisplayComponent.h | 111 +-- .../filebrowser/juce_DirectoryContentsList.h | 5 + .../filebrowser/juce_FileBrowserComponent.cpp | 21 +- .../filebrowser/juce_FileBrowserComponent.h | 4 +- .../filebrowser/juce_FileListComponent.cpp | 179 +---- .../filebrowser/juce_FileListComponent.h | 57 +- .../juce_FileListComponentBase.cpp | 691 ------------------ .../filebrowser/juce_FileListComponentBase.h | 208 ------ .../filebrowser/juce_FileTreeComponent.cpp | 270 +++++++ .../filebrowser/juce_FileTreeComponent.h | 82 +++ .../lookandfeel/juce_LookAndFeel.cpp | 72 +- .../components/lookandfeel/juce_LookAndFeel.h | 7 + .../special/juce_MidiKeyboardComponent.h | 2 +- .../gui/graphics/contexts/juce_Graphics.h | 2 +- .../graphics/fonts/juce_GlyphArrangement.cpp | 4 +- .../imaging/image_file_formats/pnglib/png.h | 16 +- .../image_file_formats/pnglib/pngconf.h | 10 +- .../image_file_formats/pnglib/pngerror.c | 8 +- src/juce_core/basics/juce_Memory.h | 2 +- .../misc/juce_PerformanceCounter.cpp | 2 +- src/juce_core/text/juce_String.cpp | 6 +- src/juce_core/text/juce_StringArray.cpp | 4 +- src/juce_core/text/juce_XmlElement.cpp | 4 + src/juce_core/text/juce_XmlElement.h | 20 +- 47 files changed, 1031 insertions(+), 2030 deletions(-) delete mode 100644 src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.cpp delete mode 100644 src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.h create mode 100644 src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp create mode 100644 src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h diff --git a/build/linux/JUCE.make b/build/linux/JUCE.make index fe3459f989..0a3cb3c30d 100644 --- a/build/linux/JUCE.make +++ b/build/linux/JUCE.make @@ -308,6 +308,7 @@ OBJECTS := \ $(OBJDIR)/juce_ToolbarItemComponent.o \ $(OBJDIR)/juce_ToolbarItemPalette.o \ $(OBJDIR)/juce_TreeView.o \ + $(OBJDIR)/juce_DirectoryContentsDisplayComponent.o \ $(OBJDIR)/juce_DirectoryContentsList.o \ $(OBJDIR)/juce_FileBrowserComponent.o \ $(OBJDIR)/juce_FileChooser.o \ @@ -315,6 +316,7 @@ OBJECTS := \ $(OBJDIR)/juce_FileFilter.o \ $(OBJDIR)/juce_FileListComponent.o \ $(OBJDIR)/juce_FilenameComponent.o \ + $(OBJDIR)/juce_FileTreeComponent.o \ $(OBJDIR)/juce_ImagePreviewComponent.o \ $(OBJDIR)/juce_WildcardFileFilter.o \ $(OBJDIR)/juce_KeyboardFocusTraverser.o \ @@ -1795,6 +1797,11 @@ $(OBJDIR)/juce_TreeView.o: ../../src/juce_appframework/gui/components/controls/j @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o $@ -c $< +$(OBJDIR)/juce_DirectoryContentsDisplayComponent.o: ../../src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + $(OBJDIR)/juce_DirectoryContentsList.o: ../../src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) @@ -1830,6 +1837,11 @@ $(OBJDIR)/juce_FilenameComponent.o: ../../src/juce_appframework/gui/components/f @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o $@ -c $< +$(OBJDIR)/juce_FileTreeComponent.o: ../../src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + $(OBJDIR)/juce_ImagePreviewComponent.o: ../../src/juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.cpp -@$(CMD_MKOBJDIR) @echo $(notdir $<) diff --git a/build/linux/platform_specific_code/juce_linux_Windowing.cpp b/build/linux/platform_specific_code/juce_linux_Windowing.cpp index 432b5360ed..7124204378 100644 --- a/build/linux/platform_specific_code/juce_linux_Windowing.cpp +++ b/build/linux/platform_specific_code/juce_linux_Windowing.cpp @@ -1091,8 +1091,8 @@ public: { /*XWMHints* wmHints = XAllocWMHints(); wmHints->flags = IconPixmapHint | IconMaskHint; - wmHints->icon_pixmap = - wmHints->icon_mask = + wmHints->icon_pixmap = + wmHints->icon_mask = XSetWMHints (display, windowH, wmHints); XFree (wmHints); diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 934d44e058..1cd4e3a353 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -163,6 +163,10 @@ 846927DE0A49ABE600314975 /* juce_RectanglePlacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846927DC0A49ABE600314975 /* juce_RectanglePlacement.cpp */; }; 846927DF0A49ABE600314975 /* juce_RectanglePlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 846927DD0A49ABE600314975 /* juce_RectanglePlacement.h */; }; 846927E10A49ABFD00314975 /* juce_SVGParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846927E00A49ABFD00314975 /* juce_SVGParser.cpp */; }; + 847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F72D70C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp */; }; + 847F72DC0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */; }; + 847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */; }; + 847F72DE0C2702A000CBECEC /* juce_FileTreeComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 847F72DA0C2702A000CBECEC /* juce_FileTreeComponent.h */; }; 84A06BAD09CAD6A3006A43BD /* juce_AudioIODevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A06BAA09CAD6A3006A43BD /* juce_AudioIODevice.cpp */; }; 84A06BAE09CAD6A3006A43BD /* juce_AudioIODeviceType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A06BAB09CAD6A3006A43BD /* juce_AudioIODeviceType.cpp */; }; 84A06BAF09CAD6A3006A43BD /* juce_AudioIODeviceType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A06BAC09CAD6A3006A43BD /* juce_AudioIODeviceType.h */; }; @@ -803,6 +807,10 @@ 846927DC0A49ABE600314975 /* juce_RectanglePlacement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_RectanglePlacement.cpp; sourceTree = ""; }; 846927DD0A49ABE600314975 /* juce_RectanglePlacement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_RectanglePlacement.h; sourceTree = ""; }; 846927E00A49ABFD00314975 /* juce_SVGParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_SVGParser.cpp; sourceTree = ""; }; + 847F72D70C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DirectoryContentsDisplayComponent.cpp; path = filebrowser/juce_DirectoryContentsDisplayComponent.cpp; sourceTree = ""; }; + 847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_DirectoryContentsDisplayComponent.h; path = filebrowser/juce_DirectoryContentsDisplayComponent.h; sourceTree = ""; }; + 847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_FileTreeComponent.cpp; path = filebrowser/juce_FileTreeComponent.cpp; sourceTree = ""; }; + 847F72DA0C2702A000CBECEC /* juce_FileTreeComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_FileTreeComponent.h; path = filebrowser/juce_FileTreeComponent.h; sourceTree = ""; }; 84A06BAA09CAD6A3006A43BD /* juce_AudioIODevice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioIODevice.cpp; sourceTree = ""; }; 84A06BAB09CAD6A3006A43BD /* juce_AudioIODeviceType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioIODeviceType.cpp; sourceTree = ""; }; 84A06BAC09CAD6A3006A43BD /* juce_AudioIODeviceType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioIODeviceType.h; sourceTree = ""; }; @@ -1281,7 +1289,7 @@ 84FC31A909B74A5C00B75141 /* juce_WildcardFileFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_WildcardFileFilter.h; path = filebrowser/juce_WildcardFileFilter.h; sourceTree = ""; }; 84FC31BC09B74A7700B75141 /* juce_BorderSize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_BorderSize.cpp; sourceTree = ""; }; 84FC31BD09B74A7700B75141 /* juce_BorderSize.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_BorderSize.h; sourceTree = ""; }; - D2AAC046055464E500DB518D /* libjuce.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjuce.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D2AAC046055464E500DB518D /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1321,7 +1329,7 @@ 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( - D2AAC046055464E500DB518D /* libjuce.a */, + D2AAC046055464E500DB518D /* libjucedebug.a */, ); name = Products; sourceTree = ""; @@ -2390,6 +2398,8 @@ 84FC319709B74A1000B75141 /* filebrowser */ = { isa = PBXGroup; children = ( + 847F72D70C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp */, + 847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */, 84FC319809B74A5C00B75141 /* juce_DirectoryContentsList.cpp */, 84FC319909B74A5C00B75141 /* juce_DirectoryContentsList.h */, 84FC319A09B74A5C00B75141 /* juce_FileBrowserComponent.cpp */, @@ -2403,6 +2413,8 @@ 84FC31A209B74A5C00B75141 /* juce_FileFilter.h */, 84FC31A309B74A5C00B75141 /* juce_FileListComponent.cpp */, 84FC31A409B74A5C00B75141 /* juce_FileListComponent.h */, + 847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */, + 847F72DA0C2702A000CBECEC /* juce_FileTreeComponent.h */, 84F1F05B0A36CE96008CCC5E /* juce_FilenameComponent.cpp */, 84F1F05C0A36CE96008CCC5E /* juce_FilenameComponent.h */, 84FC31A509B74A5C00B75141 /* juce_FilePreviewComponent.h */, @@ -2705,6 +2717,8 @@ 84F525010B32A8D500597B73 /* juce_ApplicationProperties.h in Headers */, 84C0EA5F0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.h in Headers */, 84F6B7550C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.h in Headers */, + 847F72DC0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h in Headers */, + 847F72DE0C2702A000CBECEC /* juce_FileTreeComponent.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2725,7 +2739,7 @@ ); name = Juce; productName = Juce; - productReference = D2AAC046055464E500DB518D /* libjuce.a */; + productReference = D2AAC046055464E500DB518D /* libjucedebug.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -3098,6 +3112,8 @@ 84C0EA5E0B3DDF2400EDF9D9 /* juce_IIRFilterAudioSource.cpp in Sources */, 84F6B7540C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.cpp in Sources */, 842D3D0E0C0D7CF200E9FFE4 /* juce_MenuBarModel.cpp in Sources */, + 847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */, + 847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/win32/platform_specific_code/juce_win32_ASIO.cpp b/build/win32/platform_specific_code/juce_win32_ASIO.cpp index d57287cbdf..9e47d9b801 100644 --- a/build/win32/platform_specific_code/juce_win32_ASIO.cpp +++ b/build/win32/platform_specific_code/juce_win32_ASIO.cpp @@ -773,8 +773,8 @@ public: bool isPlaying() { - return isASIOOpen - && (isThreadRunning() || ! isUsingThread) + return isASIOOpen + && (isThreadRunning() || ! isUsingThread) && (currentCallback != 0); } @@ -1090,7 +1090,7 @@ private: } log (String ("latencies: ") - + String ((int) inputLatency) + + String ((int) inputLatency) + T(", ") + String ((int) outputLatency)); // create some dummy buffers now.. because cubase does.. diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index 981fd9828c..520b7bb900 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -4068,6 +4068,14 @@ + + + + @@ -4132,6 +4140,14 @@ RelativePath="..\..\..\src\juce_appframework\gui\components\filebrowser\juce_FilePreviewComponent.h" > + + + + diff --git a/docs/JUCE changelist.txt b/docs/JUCE changelist.txt index 8330271c23..11159ab87a 100644 --- a/docs/JUCE changelist.txt +++ b/docs/JUCE changelist.txt @@ -7,8 +7,10 @@ Changelist for version 1.44 - changed the MouseEvent structure so that it now contains a pointer to the event component and also the original component. -- added a PopupMenu::dismissAllActiveMenus() method -- added the JUCE_LOG_ASSERTIONS flag, which can automatically log assertion failures, even in release builds +- added a PopupMenu::dismissAllActiveMenus() method. +- added the JUCE_LOG_ASSERTIONS flag, which can automatically log assertion failures, even in release builds. +- new classes DirectoryContentsDisplayComponent and FileTreeComponent, allow a view of a directory as either a list or treeview. I've added a demo of the FileTreeComponent to the treeviews section of the Juce Demo. +- small change to the strictness of the way TreeViews handle their root items. Be careful now to never delete a tree's root item until either the treeview has been deleted, or until you've removed the root from the tree using setRootItem (0). Not doing this can now cause a crash in the tree's destructor, where it expects the root to still be valid. ============================================================================== diff --git a/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj b/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj index ff7c00c256..829eccdd00 100644 --- a/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj +++ b/extras/juce demo/build/macosx/jucedemo.xcodeproj/project.pbxproj @@ -32,7 +32,7 @@ 84EAE2F309DAAF0B00288D0A /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F109DAAF0B00288D0A /* AGL.framework */; }; 84EAE2F409DAAF0B00288D0A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84EAE2F209DAAF0B00288D0A /* OpenGL.framework */; }; 84F8DB0B099CA8DD00E911ED /* QuickTimeDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F8DB0A099CA8DD00E911ED /* QuickTimeDemo.cpp */; }; - 84FDB0950C15BDDD00CD0087 /* libjuce.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0940C15BDCE00CD0087 /* libjuce.a */; }; + 84FDB0950C15BDDD00CD0087 /* libjucedebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */; }; 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; /* End PBXBuildFile section */ @@ -42,7 +42,7 @@ isa = PBXContainerItemProxy; containerPortal = 84EAE2F909DAAF2F00288D0A /* Juce.xcodeproj */; proxyType = 2; - remoteGlobalIDString = D2AAC046055464E500DB518D /* libjuce.a */; + remoteGlobalIDString = D2AAC046055464E500DB518D; remoteInfo = Juce; }; /* End PBXContainerItemProxy section */ @@ -85,7 +85,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84FDB0950C15BDDD00CD0087 /* libjuce.a in Frameworks */, + 84FDB0950C15BDDD00CD0087 /* libjucedebug.a in Frameworks */, 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */, 84C49F2606C0F3200066071B /* CoreAudio.framework in Frameworks */, 84C4A41106C0F9A00066071B /* IOKit.framework in Frameworks */, @@ -181,7 +181,7 @@ 84FDB0900C15BDCE00CD0087 /* Products */ = { isa = PBXGroup; children = ( - 84FDB0940C15BDCE00CD0087 /* libjuce.a */, + 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */, ); name = Products; sourceTree = ""; @@ -244,10 +244,10 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 84FDB0940C15BDCE00CD0087 /* libjuce.a */ = { + 84FDB0940C15BDCE00CD0087 /* libjucedebug.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libjuce.a; + path = libjucedebug.a; remoteRef = 84FDB0930C15BDCE00CD0087 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/extras/juce demo/src/BinaryData.cpp b/extras/juce demo/src/BinaryData.cpp index 4e36402723..34a5efd981 100644 --- a/extras/juce demo/src/BinaryData.cpp +++ b/extras/juce demo/src/BinaryData.cpp @@ -5228,107 +5228,107 @@ static const unsigned char temp9[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61, 116,114,105,120,77,111,100,101,40,71,76,95,80,82,79,74,69,67,84,73,79,78,41,59,13,10,32,32,32,32,32,32,32,32,103,108,76,111,97,100, 73,100,101,110,116,105,116,121,40,41,59,13,10,32,32,32,32,32,32,32,32,103,108,79,114,116,104,111,32,40,48,46,48,44,32,103,101,116,87,105, 100,116,104,40,41,44,32,48,46,48,44,32,103,101,116,72,101,105,103,104,116,40,41,44,32,48,44,32,49,41,59,13,10,13,10,32,32,32,32,32, - 32,32,32,103,108,67,111,108,111,114,52,102,32,40,49,46,48,102,44,32,49,46,48,102,44,32,49,46,48,102,44,32,102,97,98,115,102,32,40,115, - 105,110,102,32,40,114,111,116,97,116,105,111,110,32,47,32,49,48,48,46,48,102,41,41,41,59,13,10,32,32,32,32,32,32,32,32,103,108,66,101, - 103,105,110,40,71,76,95,81,85,65,68,83,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,105, - 32,40,48,44,32,48,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,53,48,46,48,102,44,32,103,101,116,72,101,105,103,104,116,40,41,32, - 45,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,105,32,40,49,44,32, - 48,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,53,48,46,48,102,44,32,103,101,116,72, - 101,105,103,104,116,40,41,32,45,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114, - 100,50,105,32,40,49,44,32,49,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,53,48,46, - 48,102,44,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,105,32,40,48, - 44,32,49,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,53,48,46,48,102,44,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32, - 32,32,103,108,69,110,100,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,103,108,77,97,116,114,105,120,77,111,100,101,32,40,71,76,95,80, - 82,79,74,69,67,84,73,79,78,41,59,13,10,32,32,32,32,32,32,32,32,103,108,76,111,97,100,73,100,101,110,116,105,116,121,40,41,59,13,10, - 13,10,32,32,32,32,32,32,32,32,103,108,67,108,101,97,114,32,40,71,76,95,68,69,80,84,72,95,66,85,70,70,69,82,95,66,73,84,41,59, - 13,10,32,32,32,32,32,32,32,32,103,108,117,80,101,114,115,112,101,99,116,105,118,101,32,40,52,53,46,48,102,44,13,10,32,32,32,32,32,32, - 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,101,116,87,105,100,116,104,40,41,32,47,32,40,71,76,102,108,111,97,116,41, - 32,103,101,116,72,101,105,103,104,116,40,41,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,48, - 46,49,102,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,49,48,48,46,48,102,41,59,13,10, - 13,10,32,32,32,32,32,32,32,32,103,108,77,97,116,114,105,120,77,111,100,101,32,40,71,76,95,77,79,68,69,76,86,73,69,87,41,59,13,10, - 13,10,32,32,32,32,32,32,32,32,103,108,76,111,97,100,73,100,101,110,116,105,116,121,40,41,59,13,10,32,32,32,32,32,32,32,32,103,108,80, - 117,115,104,77,97,116,114,105,120,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,114,97,110,115,108,97,116,101,102, - 32,40,48,46,48,102,44,32,48,46,48,102,44,32,45,53,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,82,111,116, - 97,116,101,102,32,40,114,111,116,97,116,105,111,110,44,32,48,46,53,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10,32,32, - 32,32,32,32,32,32,32,32,32,32,103,108,66,101,103,105,110,32,40,71,76,95,81,85,65,68,83,41,59,13,10,13,10,32,32,32,32,32,32,32, - 32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,48,46,48,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59,13,10, - 13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48, - 102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32, - 32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32, - 103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,45,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32, - 32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101, - 114,116,101,120,51,102,40,32,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32, - 32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120, - 51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32, - 32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,49,46,48,102,44,32,48,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10,32,32,32, - 32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103, - 108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32, - 32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114, - 116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32, - 32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51, - 102,40,32,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, - 32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49, - 46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103, - 108,67,111,108,111,114,51,102,32,40,48,46,48,102,44,32,48,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32, - 32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116, - 101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32, - 32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102, - 40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, - 103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46, - 48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101, - 120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32, - 32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111, - 114,51,102,32,40,49,46,48,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32, - 32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40, - 45,49,46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103, - 108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48, - 102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120, - 67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,45, - 49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114, - 100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102, - 44,32,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40, - 48,46,48,102,44,32,49,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108, - 84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102, - 44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67, - 111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,32,49, - 46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100, - 50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,32,49,46,48,102,44, - 32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49, - 46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,45,49,46,48,102,44,32,32,49,46, - 48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,49,46,48,102,44, - 32,48,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111, - 111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46, - 48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50, - 102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32, - 32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46, - 48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48, - 102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32, - 48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13, - 10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,69,110,100,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,103,108,80,111,112, - 77,97,116,114,105,120,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,116,105,109,101,114,67,97,108,108,98,97, - 99,107,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,114,111,116,97,116,105,111,110,32,43,61,32,100,101,108,116,97,59,13, - 10,13,10,32,32,32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,47,47,61,61, + 32,32,32,103,108,67,111,108,111,114,52,102,32,40,49,46,48,102,44,32,49,46,48,102,44,32,49,46,48,102,44,32,102,97,98,115,102,32,40,58, + 58,115,105,110,102,32,40,114,111,116,97,116,105,111,110,32,47,32,49,48,48,46,48,102,41,41,41,59,13,10,32,32,32,32,32,32,32,32,103,108, + 66,101,103,105,110,40,71,76,95,81,85,65,68,83,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100, + 50,105,32,40,48,44,32,48,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,53,48,46,48,102,44,32,103,101,116,72,101,105,103,104,116,40, + 41,32,45,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,105,32,40,49, + 44,32,48,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,53,48,46,48,102,44,32,103,101, + 116,72,101,105,103,104,116,40,41,32,45,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111, + 111,114,100,50,105,32,40,49,44,32,49,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,103,101,116,87,105,100,116,104,40,41,32,45,32,53, + 48,46,48,102,44,32,53,48,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,105,32, + 40,48,44,32,49,41,59,32,103,108,86,101,114,116,101,120,50,102,32,40,53,48,46,48,102,44,32,53,48,46,48,102,41,59,13,10,32,32,32,32, + 32,32,32,32,103,108,69,110,100,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,103,108,77,97,116,114,105,120,77,111,100,101,32,40,71,76, + 95,80,82,79,74,69,67,84,73,79,78,41,59,13,10,32,32,32,32,32,32,32,32,103,108,76,111,97,100,73,100,101,110,116,105,116,121,40,41,59, + 13,10,13,10,32,32,32,32,32,32,32,32,103,108,67,108,101,97,114,32,40,71,76,95,68,69,80,84,72,95,66,85,70,70,69,82,95,66,73,84, + 41,59,13,10,32,32,32,32,32,32,32,32,103,108,117,80,101,114,115,112,101,99,116,105,118,101,32,40,52,53,46,48,102,44,13,10,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,101,116,87,105,100,116,104,40,41,32,47,32,40,71,76,102,108,111,97, + 116,41,32,103,101,116,72,101,105,103,104,116,40,41,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, + 32,48,46,49,102,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,49,48,48,46,48,102,41,59, + 13,10,13,10,32,32,32,32,32,32,32,32,103,108,77,97,116,114,105,120,77,111,100,101,32,40,71,76,95,77,79,68,69,76,86,73,69,87,41,59, + 13,10,13,10,32,32,32,32,32,32,32,32,103,108,76,111,97,100,73,100,101,110,116,105,116,121,40,41,59,13,10,32,32,32,32,32,32,32,32,103, + 108,80,117,115,104,77,97,116,114,105,120,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,114,97,110,115,108,97,116, + 101,102,32,40,48,46,48,102,44,32,48,46,48,102,44,32,45,53,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,82, + 111,116,97,116,101,102,32,40,114,111,116,97,116,105,111,110,44,32,48,46,53,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10, + 32,32,32,32,32,32,32,32,32,32,32,32,103,108,66,101,103,105,110,32,40,71,76,95,81,85,65,68,83,41,59,13,10,13,10,32,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,48,46,48,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59, + 13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48, + 46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10, + 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41, + 59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,45,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108, + 86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32, + 32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116, + 101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32, + 32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,49,46,48,102,44,32,48,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10,32, + 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59, + 32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86, + 101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32, + 32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101, + 120,51,102,40,32,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32, + 32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40, + 32,49,46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, + 32,103,108,67,111,108,111,114,51,102,32,40,48,46,48,102,44,32,48,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101, + 114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32, + 32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120, + 51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, + 32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32, + 49,46,48,102,44,32,32,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108, + 84,101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102, + 44,32,32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111, + 108,111,114,51,102,32,40,49,46,48,102,44,32,49,46,48,102,44,32,48,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32, + 32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51, + 102,40,45,49,46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, + 32,103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49, + 46,48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84, + 101,120,67,111,111,114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44, + 32,45,49,46,48,102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111, + 111,114,100,50,102,40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46, + 48,102,44,32,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102, + 32,40,48,46,48,102,44,32,49,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, + 103,108,84,101,120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46, + 48,102,44,32,45,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101, + 120,67,111,111,114,100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32, + 32,49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111, + 114,100,50,102,40,49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,32,49,46,48, + 102,44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102, + 40,49,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,32,49,46,48,102,44,32,45,49,46,48,102,44,32,32, + 49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,67,111,108,111,114,51,102,32,40,49,46,48, + 102,44,32,48,46,48,102,44,32,49,46,48,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120, + 67,111,111,114,100,50,102,40,48,46,48,102,44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45, + 49,46,48,102,44,32,45,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114, + 100,50,102,40,48,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,45,49,46,48,102, + 44,32,32,49,46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40, + 49,46,48,102,44,32,49,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,32,49, + 46,48,102,41,59,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,103,108,84,101,120,67,111,111,114,100,50,102,40,49,46,48,102, + 44,32,48,46,48,102,41,59,32,103,108,86,101,114,116,101,120,51,102,40,45,49,46,48,102,44,32,32,49,46,48,102,44,32,45,49,46,48,102,41, + 59,13,10,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,108,69,110,100,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,103,108,80, + 111,112,77,97,116,114,105,120,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,116,105,109,101,114,67,97,108,108, + 98,97,99,107,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,114,111,116,97,116,105,111,110,32,43,61,32,100,101,108,116,97, + 59,13,10,13,10,32,32,32,32,32,32,32,32,114,101,112,97,105,110,116,40,41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,47,47, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,99,108, - 97,115,115,32,79,112,101,110,71,76,68,101,109,111,32,32,58,32,112,117,98,108,105,99,32,67,111,109,112,111,110,101,110,116,13,10,123,13,10,32, - 32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, + 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10, + 99,108,97,115,115,32,79,112,101,110,71,76,68,101,109,111,32,32,58,32,112,117,98,108,105,99,32,67,111,109,112,111,110,101,110,116,13,10,123,13, + 10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,13,10,32,32,32,32,68,101,109,111,79,112,101,110,71,76,67,97,110,118,97,115,42,32,99,97,110,118,97,115,59,13,10,13,10,112,117, - 98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, + 61,61,61,61,61,13,10,32,32,32,32,68,101,109,111,79,112,101,110,71,76,67,97,110,118,97,115,42,32,99,97,110,118,97,115,59,13,10,13,10, + 112,117,98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,79,112,101,110,71,76,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32, - 32,32,32,32,32,32,115,101,116,78,97,109,101,32,40,84,40,34,79,112,101,110,71,76,34,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32, - 99,97,110,118,97,115,32,61,32,110,101,119,32,68,101,109,111,79,112,101,110,71,76,67,97,110,118,97,115,40,41,59,13,10,32,32,32,32,32,32, - 32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,99,97,110,118,97,115,41,59,13,10,32,32,32,32,125,13,10,13,10, - 32,32,32,32,126,79,112,101,110,71,76,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116,101, - 65,108,108,67,104,105,108,100,114,101,110,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,114,101,115,105,122,101, - 100,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,99,97,110,118,97,115,45,62,115,101,116,66,111,117,110,100,115,32,40,49, - 48,44,32,49,48,44,32,103,101,116,87,105,100,116,104,40,41,32,45,32,50,48,44,32,103,101,116,72,101,105,103,104,116,40,41,32,45,32,53,48, - 41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, + 61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,79,112,101,110,71,76,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10, + 32,32,32,32,32,32,32,32,115,101,116,78,97,109,101,32,40,84,40,34,79,112,101,110,71,76,34,41,41,59,13,10,13,10,32,32,32,32,32,32, + 32,32,99,97,110,118,97,115,32,61,32,110,101,119,32,68,101,109,111,79,112,101,110,71,76,67,97,110,118,97,115,40,41,59,13,10,32,32,32,32, + 32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,99,97,110,118,97,115,41,59,13,10,32,32,32,32,125,13,10, + 13,10,32,32,32,32,126,79,112,101,110,71,76,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,100,101,108,101, + 116,101,65,108,108,67,104,105,108,100,114,101,110,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,114,101,115,105, + 122,101,100,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,99,97,110,118,97,115,45,62,115,101,116,66,111,117,110,100,115,32, + 40,49,48,44,32,49,48,44,32,103,101,116,87,105,100,116,104,40,41,32,45,32,50,48,44,32,103,101,116,72,101,105,103,104,116,40,41,32,45,32, + 53,48,41,59,13,10,32,32,32,32,125,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67,111,109,112,111,110,101,110,116,42,32,99,114,101,97,116,101,79,112, - 101,110,71,76,68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,79,112,101,110,71,76,68,101,109,111, - 40,41,59,13,10,125,13,10,13,10,35,101,110,100,105,102,13,10,0,0}; + 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67,111,109,112,111,110,101,110,116,42,32,99,114,101,97,116,101, + 79,112,101,110,71,76,68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,79,112,101,110,71,76,68,101, + 109,111,40,41,59,13,10,125,13,10,13,10,35,101,110,100,105,102,13,10,0,0}; const char* BinaryData::opengldemo_cpp = (const char*) temp9; static const unsigned char temp10[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, @@ -6514,39 +6514,91 @@ static const unsigned char temp16[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10, 99,108,97,115,115,32,84,114,101,101,86,105,101,119,68,101,109,111,32,32,58,32,112,117,98,108,105,99,32,67,111,109,112,111,110,101,110,116,44,13, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,117,98,108,105,99,32,68,114,97,103,65,110,100,68,114,111, - 112,67,111,110,116,97,105,110,101,114,13,10,123,13,10,32,32,32,32,88,109,108,69,108,101,109,101,110,116,42,32,116,114,101,101,88,109,108,59,13, - 10,13,10,32,32,32,32,84,114,101,101,86,105,101,119,73,116,101,109,42,32,114,111,111,116,73,116,101,109,59,13,10,32,32,32,32,84,114,101,101, - 86,105,101,119,42,32,116,114,101,101,86,105,101,119,59,13,10,13,10,112,117,98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,61,61,61,61, + 112,67,111,110,116,97,105,110,101,114,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,112,117,98,108,105, + 99,32,66,117,116,116,111,110,76,105,115,116,101,110,101,114,13,10,123,13,10,32,32,32,32,88,109,108,69,108,101,109,101,110,116,42,32,116,114,101, + 101,88,109,108,59,13,10,13,10,32,32,32,32,84,114,101,101,86,105,101,119,73,116,101,109,42,32,114,111,111,116,73,116,101,109,59,13,10,32,32, + 32,32,84,114,101,101,86,105,101,119,42,32,116,114,101,101,86,105,101,119,59,13,10,13,10,32,32,32,32,70,105,108,101,84,114,101,101,67,111,109, + 112,111,110,101,110,116,42,32,102,105,108,101,84,114,101,101,67,111,109,112,59,13,10,32,32,32,32,68,105,114,101,99,116,111,114,121,67,111,110,116, + 101,110,116,115,76,105,115,116,42,32,100,105,114,101,99,116,111,114,121,76,105,115,116,59,13,10,32,32,32,32,84,105,109,101,83,108,105,99,101,84, + 104,114,101,97,100,32,116,104,114,101,97,100,59,13,10,13,10,32,32,32,32,84,101,120,116,66,117,116,116,111,110,42,32,116,121,112,101,66,117,116, + 116,111,110,59,13,10,13,10,112,117,98,108,105,99,58,13,10,32,32,32,32,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,84,114, - 101,101,86,105,101,119,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,115,101,116,78,97,109,101,32,40,84,40, - 34,84,114,101,101,32,86,105,101,119,115,34,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32,99,111,110,115,116,32,83,116,114,105,110,103,32, - 116,114,101,101,88,109,108,83,116,114,105,110,103,32,40,66,105,110,97,114,121,68,97,116,97,58,58,116,114,101,101,100,101,109,111,95,120,109,108,41, - 59,13,10,13,10,32,32,32,32,32,32,32,32,88,109,108,68,111,99,117,109,101,110,116,32,112,97,114,115,101,114,32,40,116,114,101,101,88,109,108, - 83,116,114,105,110,103,41,59,13,10,13,10,32,32,32,32,32,32,32,32,116,114,101,101,88,109,108,32,61,32,112,97,114,115,101,114,46,103,101,116, - 68,111,99,117,109,101,110,116,69,108,101,109,101,110,116,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,114,111,111,116,73,116,101,109,32,61, - 32,110,101,119,32,84,114,101,101,86,105,101,119,68,101,109,111,73,116,101,109,32,40,116,114,101,101,88,109,108,41,59,13,10,32,32,32,32,32,32, - 32,32,114,111,111,116,73,116,101,109,45,62,115,101,116,79,112,101,110,32,40,116,114,117,101,41,59,13,10,13,10,32,32,32,32,32,32,32,32,97, - 100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,116,114,101,101,86,105,101,119,32,61,32,110,101,119,32,84,114,101,101,86,105,101, - 119,40,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32,116,114,101,101,86,105,101,119,45,62,115,101,116,82,111,111,116,73,116,101,109,32,40, - 114,111,111,116,73,116,101,109,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,126,84,114,101,101,86,105,101,119,68,101,109,111,40,41, - 13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116,101,65,108,108,67,104,105,108,100,114,101,110,40,41,59,13,10,13, - 10,32,32,32,32,32,32,32,32,105,102,32,40,114,111,111,116,73,116,101,109,32,33,61,32,48,41,13,10,32,32,32,32,32,32,32,32,32,32,32, - 32,100,101,108,101,116,101,32,114,111,111,116,73,116,101,109,59,13,10,13,10,32,32,32,32,32,32,32,32,105,102,32,40,116,114,101,101,88,109,108, - 32,33,61,32,48,41,13,10,32,32,32,32,32,32,32,32,32,32,32,32,100,101,108,101,116,101,32,116,114,101,101,88,109,108,59,13,10,32,32,32, - 32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,112,97,105,110,116,32,40,71,114,97,112,104,105,99,115,38,32,103,41,13,10,32,32,32,32, - 123,13,10,32,32,32,32,32,32,32,32,103,46,115,101,116,67,111,108,111,117,114,32,40,67,111,108,111,117,114,115,58,58,103,114,101,121,41,59,13, - 10,32,32,32,32,32,32,32,32,103,46,100,114,97,119,82,101,99,116,32,40,116,114,101,101,86,105,101,119,45,62,103,101,116,88,40,41,44,32,116, - 114,101,101,86,105,101,119,45,62,103,101,116,89,40,41,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,114, - 101,101,86,105,101,119,45,62,103,101,116,87,105,100,116,104,40,41,44,32,116,114,101,101,86,105,101,119,45,62,103,101,116,72,101,105,103,104,116,40, - 41,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,114,101,115,105,122,101,100,40,41,13,10,32,32,32,32,123,13, - 10,32,32,32,32,32,32,32,32,116,114,101,101,86,105,101,119,45,62,115,101,116,66,111,117,110,100,115,82,101,108,97,116,105,118,101,32,40,48,46, - 48,53,102,44,32,48,46,48,53,102,44,32,48,46,57,102,44,32,48,46,57,102,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,106, - 117,99,101,95,85,115,101,68,101,98,117,103,103,105,110,103,78,101,119,79,112,101,114,97,116,111,114,13,10,125,59,13,10,13,10,13,10,47,47,61, + 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,32,32,32,32,84,114,101,101,86,105,101,119,68,101,109,111,40, + 41,13,10,32,32,32,32,32,32,32,32,58,32,116,114,101,101,86,105,101,119,32,40,48,41,44,13,10,32,32,32,32,32,32,32,32,32,32,114,111, + 111,116,73,116,101,109,32,40,48,41,44,13,10,32,32,32,32,32,32,32,32,32,32,102,105,108,101,84,114,101,101,67,111,109,112,32,40,48,41,44, + 13,10,32,32,32,32,32,32,32,32,32,32,100,105,114,101,99,116,111,114,121,76,105,115,116,32,40,48,41,44,13,10,32,32,32,32,32,32,32,32, + 32,32,116,104,114,101,97,100,32,40,34,68,101,109,111,32,102,105,108,101,32,116,114,101,101,32,116,104,114,101,97,100,34,41,13,10,32,32,32,32, + 123,13,10,32,32,32,32,32,32,32,32,115,101,116,78,97,109,101,32,40,84,40,34,84,114,101,101,32,86,105,101,119,115,34,41,41,59,13,10,13, + 10,32,32,32,32,32,32,32,32,99,111,110,115,116,32,83,116,114,105,110,103,32,116,114,101,101,88,109,108,83,116,114,105,110,103,32,40,66,105,110, + 97,114,121,68,97,116,97,58,58,116,114,101,101,100,101,109,111,95,120,109,108,41,59,13,10,32,32,32,32,32,32,32,32,88,109,108,68,111,99,117, + 109,101,110,116,32,112,97,114,115,101,114,32,40,116,114,101,101,88,109,108,83,116,114,105,110,103,41,59,13,10,32,32,32,32,32,32,32,32,116,114, + 101,101,88,109,108,32,61,32,112,97,114,115,101,114,46,103,101,116,68,111,99,117,109,101,110,116,69,108,101,109,101,110,116,40,41,59,13,10,13,10, + 32,32,32,32,32,32,32,32,114,111,111,116,73,116,101,109,32,61,32,110,101,119,32,84,114,101,101,86,105,101,119,68,101,109,111,73,116,101,109,32, + 40,116,114,101,101,88,109,108,41,59,13,10,32,32,32,32,32,32,32,32,114,111,111,116,73,116,101,109,45,62,115,101,116,79,112,101,110,32,40,116, + 114,117,101,41,59,13,10,13,10,32,32,32,32,32,32,32,32,79,119,110,101,100,65,114,114,97,121,32,60,70,105,108,101,62,32,114,111,111,116,115, + 59,13,10,32,32,32,32,32,32,32,32,70,105,108,101,58,58,102,105,110,100,70,105,108,101,83,121,115,116,101,109,82,111,111,116,115,32,40,114,111, + 111,116,115,41,59,13,10,32,32,32,32,32,32,32,32,100,105,114,101,99,116,111,114,121,76,105,115,116,32,61,32,110,101,119,32,68,105,114,101,99, + 116,111,114,121,67,111,110,116,101,110,116,115,76,105,115,116,32,40,48,44,32,116,104,114,101,97,100,41,59,13,10,32,32,32,32,32,32,32,32,100, + 105,114,101,99,116,111,114,121,76,105,115,116,45,62,115,101,116,68,105,114,101,99,116,111,114,121,32,40,42,114,111,111,116,115,91,48,93,44,32,116, + 114,117,101,44,32,116,114,117,101,41,59,13,10,32,32,32,32,32,32,32,32,116,104,114,101,97,100,46,115,116,97,114,116,84,104,114,101,97,100,32, + 40,51,41,59,13,10,13,10,32,32,32,32,32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,116,121,112,101,66, + 117,116,116,111,110,32,61,32,110,101,119,32,84,101,120,116,66,117,116,116,111,110,32,40,84,40,34,84,121,112,101,32,111,102,32,116,114,101,101,118, + 105,101,119,46,46,46,34,41,41,41,59,13,10,32,32,32,32,32,32,32,32,116,121,112,101,66,117,116,116,111,110,45,62,97,100,100,66,117,116,116, + 111,110,76,105,115,116,101,110,101,114,32,40,116,104,105,115,41,59,13,10,32,32,32,32,32,32,32,32,116,121,112,101,66,117,116,116,111,110,45,62, + 115,101,116,65,108,119,97,121,115,79,110,84,111,112,32,40,116,114,117,101,41,59,13,10,32,32,32,32,32,32,32,32,116,121,112,101,66,117,116,116, + 111,110,45,62,115,101,116,84,114,105,103,103,101,114,101,100,79,110,77,111,117,115,101,68,111,119,110,32,40,116,114,117,101,41,59,13,10,13,10,32, + 32,32,32,32,32,32,32,115,104,111,119,67,117,115,116,111,109,84,114,101,101,86,105,101,119,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32, + 32,32,32,126,84,114,101,101,86,105,101,119,68,101,109,111,40,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116, + 101,65,108,108,67,104,105,108,100,114,101,110,40,41,59,13,10,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116,101,32,114,111,111,116,73,116, + 101,109,59,13,10,32,32,32,32,32,32,32,32,100,101,108,101,116,101,32,116,114,101,101,88,109,108,59,13,10,32,32,32,32,32,32,32,32,100,101, + 108,101,116,101,32,100,105,114,101,99,116,111,114,121,76,105,115,116,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,112, + 97,105,110,116,32,40,71,114,97,112,104,105,99,115,38,32,103,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32,32,103,46,115,101,116, + 67,111,108,111,117,114,32,40,67,111,108,111,117,114,115,58,58,103,114,101,121,41,59,13,10,13,10,32,32,32,32,32,32,32,32,105,102,32,40,116, + 114,101,101,86,105,101,119,32,33,61,32,48,41,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,46,100,114,97,119,82,101,99,116,32,40,116, + 114,101,101,86,105,101,119,45,62,103,101,116,88,40,41,44,32,116,114,101,101,86,105,101,119,45,62,103,101,116,89,40,41,44,13,10,32,32,32,32, + 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,114,101,101,86,105,101,119,45,62,103,101,116,87,105,100,116,104,40,41, + 44,32,116,114,101,101,86,105,101,119,45,62,103,101,116,72,101,105,103,104,116,40,41,41,59,13,10,13,10,32,32,32,32,32,32,32,32,105,102,32, + 40,102,105,108,101,84,114,101,101,67,111,109,112,32,33,61,32,48,41,13,10,32,32,32,32,32,32,32,32,32,32,32,32,103,46,100,114,97,119,82, + 101,99,116,32,40,102,105,108,101,84,114,101,101,67,111,109,112,45,62,103,101,116,88,40,41,44,32,102,105,108,101,84,114,101,101,67,111,109,112,45, + 62,103,101,116,89,40,41,44,13,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,102,105,108,101,84,114, + 101,101,67,111,109,112,45,62,103,101,116,87,105,100,116,104,40,41,44,32,102,105,108,101,84,114,101,101,67,111,109,112,45,62,103,101,116,72,101,105, + 103,104,116,40,41,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100,32,114,101,115,105,122,101,100,40,41,13,10,32,32, + 32,32,123,13,10,32,32,32,32,32,32,32,32,105,102,32,40,116,114,101,101,86,105,101,119,32,33,61,32,48,41,13,10,32,32,32,32,32,32,32, + 32,32,32,32,32,116,114,101,101,86,105,101,119,45,62,115,101,116,66,111,117,110,100,115,82,101,108,97,116,105,118,101,32,40,48,46,48,53,102,44, + 32,48,46,48,55,102,44,32,48,46,57,102,44,32,48,46,57,102,41,59,13,10,32,32,32,32,32,32,32,32,101,108,115,101,32,105,102,32,40,102, + 105,108,101,84,114,101,101,67,111,109,112,32,33,61,32,48,41,13,10,32,32,32,32,32,32,32,32,32,32,32,32,102,105,108,101,84,114,101,101,67, + 111,109,112,45,62,115,101,116,66,111,117,110,100,115,82,101,108,97,116,105,118,101,32,40,48,46,48,53,102,44,32,48,46,48,55,102,44,32,48,46, + 57,102,44,32,48,46,57,102,41,59,13,10,13,10,32,32,32,32,32,32,32,32,116,121,112,101,66,117,116,116,111,110,45,62,99,104,97,110,103,101, + 87,105,100,116,104,84,111,70,105,116,84,101,120,116,32,40,50,48,41,59,13,10,32,32,32,32,32,32,32,32,116,121,112,101,66,117,116,116,111,110, + 45,62,115,101,116,84,111,112,76,101,102,116,80,111,115,105,116,105,111,110,32,40,52,48,44,32,49,48,41,59,13,10,32,32,32,32,125,13,10,13, + 10,32,32,32,32,118,111,105,100,32,115,104,111,119,67,117,115,116,111,109,84,114,101,101,86,105,101,119,40,41,13,10,32,32,32,32,123,13,10,32, + 32,32,32,32,32,32,32,100,101,108,101,116,101,65,110,100,90,101,114,111,32,40,116,114,101,101,86,105,101,119,41,59,13,10,32,32,32,32,32,32, + 32,32,100,101,108,101,116,101,65,110,100,90,101,114,111,32,40,102,105,108,101,84,114,101,101,67,111,109,112,41,59,13,10,13,10,32,32,32,32,32, + 32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,116,114,101,101,86,105,101,119,32,61,32,110,101,119,32,84,114,101, + 101,86,105,101,119,40,41,41,59,13,10,32,32,32,32,32,32,32,32,116,114,101,101,86,105,101,119,45,62,115,101,116,82,111,111,116,73,116,101,109, + 32,40,114,111,111,116,73,116,101,109,41,59,13,10,13,10,32,32,32,32,32,32,32,32,114,101,115,105,122,101,100,40,41,59,13,10,32,32,32,32, + 125,13,10,13,10,32,32,32,32,118,111,105,100,32,115,104,111,119,70,105,108,101,84,114,101,101,67,111,109,112,40,41,13,10,32,32,32,32,123,13, + 10,32,32,32,32,32,32,32,32,100,101,108,101,116,101,65,110,100,90,101,114,111,32,40,116,114,101,101,86,105,101,119,41,59,13,10,32,32,32,32, + 32,32,32,32,100,101,108,101,116,101,65,110,100,90,101,114,111,32,40,102,105,108,101,84,114,101,101,67,111,109,112,41,59,13,10,13,10,32,32,32, + 32,32,32,32,32,97,100,100,65,110,100,77,97,107,101,86,105,115,105,98,108,101,32,40,102,105,108,101,84,114,101,101,67,111,109,112,32,61,32,110, + 101,119,32,70,105,108,101,84,114,101,101,67,111,109,112,111,110,101,110,116,32,40,42,100,105,114,101,99,116,111,114,121,76,105,115,116,41,41,59,13, + 10,13,10,32,32,32,32,32,32,32,32,114,101,115,105,122,101,100,40,41,59,13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,118,111,105,100, + 32,98,117,116,116,111,110,67,108,105,99,107,101,100,32,40,66,117,116,116,111,110,42,41,13,10,32,32,32,32,123,13,10,32,32,32,32,32,32,32, + 32,80,111,112,117,112,77,101,110,117,32,109,59,13,10,32,32,32,32,32,32,32,32,109,46,97,100,100,73,116,101,109,32,40,49,44,32,84,40,34, + 67,117,115,116,111,109,32,116,114,101,101,118,105,101,119,32,115,104,111,119,105,110,103,32,97,110,32,88,77,76,32,116,114,101,101,34,41,41,59,13, + 10,32,32,32,32,32,32,32,32,109,46,97,100,100,73,116,101,109,32,40,50,44,32,84,40,34,70,105,108,101,84,114,101,101,67,111,109,112,111,110, + 101,110,116,32,115,104,111,119,105,110,103,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101,109,34,41,41,59,13,10,13,10,32,32,32,32,32, + 32,32,32,99,111,110,115,116,32,105,110,116,32,114,32,61,32,109,46,115,104,111,119,65,116,32,40,116,121,112,101,66,117,116,116,111,110,41,59,13, + 10,13,10,32,32,32,32,32,32,32,32,105,102,32,40,114,32,61,61,32,49,41,13,10,32,32,32,32,32,32,32,32,123,13,10,32,32,32,32,32, + 32,32,32,32,32,32,32,115,104,111,119,67,117,115,116,111,109,84,114,101,101,86,105,101,119,40,41,59,13,10,32,32,32,32,32,32,32,32,125,13, + 10,32,32,32,32,32,32,32,32,101,108,115,101,32,105,102,32,40,114,32,61,61,32,50,41,13,10,32,32,32,32,32,32,32,32,123,13,10,32,32, + 32,32,32,32,32,32,32,32,32,32,115,104,111,119,70,105,108,101,84,114,101,101,67,111,109,112,40,41,59,13,10,32,32,32,32,32,32,32,32,125, + 13,10,32,32,32,32,125,13,10,13,10,32,32,32,32,106,117,99,101,95,85,115,101,68,101,98,117,103,103,105,110,103,78,101,119,79,112,101,114,97, + 116,111,114,13,10,125,59,13,10,13,10,13,10,47,47,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, - 61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67, - 111,109,112,111,110,101,110,116,42,32,99,114,101,97,116,101,84,114,101,101,86,105,101,119,68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114, - 101,116,117,114,110,32,110,101,119,32,84,114,101,101,86,105,101,119,68,101,109,111,40,41,59,13,10,125,13,10,0,0}; + 61,61,61,61,61,61,61,61,61,61,61,61,61,13,10,67,111,109,112,111,110,101,110,116,42,32,99,114,101,97,116,101,84,114,101,101,86,105,101,119, + 68,101,109,111,40,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,84,114,101,101,86,105,101,119,68,101,109,111,40,41, + 59,13,10,125,13,10,0,0}; const char* BinaryData::treeviewdemo_cpp = (const char*) temp16; static const unsigned char temp17[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, diff --git a/extras/juce demo/src/BinaryData.h b/extras/juce demo/src/BinaryData.h index f7c1a3f9c0..a2bf497466 100644 --- a/extras/juce demo/src/BinaryData.h +++ b/extras/juce demo/src/BinaryData.h @@ -30,7 +30,7 @@ namespace BinaryData const int juce_pngSize = 15290; extern const char* opengldemo_cpp; - const int opengldemo_cppSize = 8538; + const int opengldemo_cppSize = 8540; extern const char* pathsandtransformsdemo_cpp; const int pathsandtransformsdemo_cppSize = 14232; @@ -51,7 +51,7 @@ namespace BinaryData const int treedemo_xmlSize = 1126; extern const char* treeviewdemo_cpp; - const int treeviewdemo_cppSize = 5430; + const int treeviewdemo_cppSize = 7486; extern const char* widgetsdemo_cpp; const int widgetsdemo_cppSize = 50519; diff --git a/extras/juce demo/src/binarydata/OpenGLDemo.cpp b/extras/juce demo/src/binarydata/OpenGLDemo.cpp index 7dadef9e06..d98dd70f14 100644 --- a/extras/juce demo/src/binarydata/OpenGLDemo.cpp +++ b/extras/juce demo/src/binarydata/OpenGLDemo.cpp @@ -138,7 +138,7 @@ public: glLoadIdentity(); glOrtho (0.0, getWidth(), 0.0, getHeight(), 0, 1); - glColor4f (1.0f, 1.0f, 1.0f, fabsf (sinf (rotation / 100.0f))); + glColor4f (1.0f, 1.0f, 1.0f, fabsf (::sinf (rotation / 100.0f))); glBegin(GL_QUADS); glTexCoord2i (0, 0); glVertex2f (50.0f, getHeight() - 50.0f); glTexCoord2i (1, 0); glVertex2f (getWidth() - 50.0f, getHeight() - 50.0f); diff --git a/extras/juce demo/src/binarydata/TreeViewDemo.cpp b/extras/juce demo/src/binarydata/TreeViewDemo.cpp index d0b53a9373..fd1443d3bb 100644 --- a/extras/juce demo/src/binarydata/TreeViewDemo.cpp +++ b/extras/juce demo/src/binarydata/TreeViewDemo.cpp @@ -123,54 +123,122 @@ public: //============================================================================== class TreeViewDemo : public Component, - public DragAndDropContainer + public DragAndDropContainer, + public ButtonListener { XmlElement* treeXml; TreeViewItem* rootItem; TreeView* treeView; + FileTreeComponent* fileTreeComp; + DirectoryContentsList* directoryList; + TimeSliceThread thread; + + TextButton* typeButton; + public: //============================================================================== TreeViewDemo() + : treeView (0), + rootItem (0), + fileTreeComp (0), + directoryList (0), + thread ("Demo file tree thread") { setName (T("Tree Views")); const String treeXmlString (BinaryData::treedemo_xml); - XmlDocument parser (treeXmlString); - treeXml = parser.getDocumentElement(); rootItem = new TreeViewDemoItem (treeXml); rootItem->setOpen (true); - addAndMakeVisible (treeView = new TreeView()); + OwnedArray roots; + File::findFileSystemRoots (roots); + directoryList = new DirectoryContentsList (0, thread); + directoryList->setDirectory (*roots[0], true, true); + thread.startThread (3); - treeView->setRootItem (rootItem); + addAndMakeVisible (typeButton = new TextButton (T("Type of treeview..."))); + typeButton->addButtonListener (this); + typeButton->setAlwaysOnTop (true); + typeButton->setTriggeredOnMouseDown (true); + + showCustomTreeView(); } ~TreeViewDemo() { deleteAllChildren(); - if (rootItem != 0) - delete rootItem; - - if (treeXml != 0) - delete treeXml; + delete rootItem; + delete treeXml; + delete directoryList; } void paint (Graphics& g) { g.setColour (Colours::grey); - g.drawRect (treeView->getX(), treeView->getY(), - treeView->getWidth(), treeView->getHeight()); + + if (treeView != 0) + g.drawRect (treeView->getX(), treeView->getY(), + treeView->getWidth(), treeView->getHeight()); + + if (fileTreeComp != 0) + g.drawRect (fileTreeComp->getX(), fileTreeComp->getY(), + fileTreeComp->getWidth(), fileTreeComp->getHeight()); } void resized() { - treeView->setBoundsRelative (0.05f, 0.05f, 0.9f, 0.9f); + if (treeView != 0) + treeView->setBoundsRelative (0.05f, 0.07f, 0.9f, 0.9f); + else if (fileTreeComp != 0) + fileTreeComp->setBoundsRelative (0.05f, 0.07f, 0.9f, 0.9f); + + typeButton->changeWidthToFitText (20); + typeButton->setTopLeftPosition (40, 10); + } + + void showCustomTreeView() + { + deleteAndZero (treeView); + deleteAndZero (fileTreeComp); + + addAndMakeVisible (treeView = new TreeView()); + treeView->setRootItem (rootItem); + + resized(); + } + + void showFileTreeComp() + { + deleteAndZero (treeView); + deleteAndZero (fileTreeComp); + + addAndMakeVisible (fileTreeComp = new FileTreeComponent (*directoryList)); + + resized(); + } + + void buttonClicked (Button*) + { + PopupMenu m; + m.addItem (1, T("Custom treeview showing an XML tree")); + m.addItem (2, T("FileTreeComponent showing the file system")); + + const int r = m.showAt (typeButton); + + if (r == 1) + { + showCustomTreeView(); + } + else if (r == 2) + { + showFileTreeComp(); + } } juce_UseDebuggingNewOperator diff --git a/extras/juce demo/src/demos/TreeViewDemo.cpp b/extras/juce demo/src/demos/TreeViewDemo.cpp index d0b53a9373..fd1443d3bb 100644 --- a/extras/juce demo/src/demos/TreeViewDemo.cpp +++ b/extras/juce demo/src/demos/TreeViewDemo.cpp @@ -123,54 +123,122 @@ public: //============================================================================== class TreeViewDemo : public Component, - public DragAndDropContainer + public DragAndDropContainer, + public ButtonListener { XmlElement* treeXml; TreeViewItem* rootItem; TreeView* treeView; + FileTreeComponent* fileTreeComp; + DirectoryContentsList* directoryList; + TimeSliceThread thread; + + TextButton* typeButton; + public: //============================================================================== TreeViewDemo() + : treeView (0), + rootItem (0), + fileTreeComp (0), + directoryList (0), + thread ("Demo file tree thread") { setName (T("Tree Views")); const String treeXmlString (BinaryData::treedemo_xml); - XmlDocument parser (treeXmlString); - treeXml = parser.getDocumentElement(); rootItem = new TreeViewDemoItem (treeXml); rootItem->setOpen (true); - addAndMakeVisible (treeView = new TreeView()); + OwnedArray roots; + File::findFileSystemRoots (roots); + directoryList = new DirectoryContentsList (0, thread); + directoryList->setDirectory (*roots[0], true, true); + thread.startThread (3); - treeView->setRootItem (rootItem); + addAndMakeVisible (typeButton = new TextButton (T("Type of treeview..."))); + typeButton->addButtonListener (this); + typeButton->setAlwaysOnTop (true); + typeButton->setTriggeredOnMouseDown (true); + + showCustomTreeView(); } ~TreeViewDemo() { deleteAllChildren(); - if (rootItem != 0) - delete rootItem; - - if (treeXml != 0) - delete treeXml; + delete rootItem; + delete treeXml; + delete directoryList; } void paint (Graphics& g) { g.setColour (Colours::grey); - g.drawRect (treeView->getX(), treeView->getY(), - treeView->getWidth(), treeView->getHeight()); + + if (treeView != 0) + g.drawRect (treeView->getX(), treeView->getY(), + treeView->getWidth(), treeView->getHeight()); + + if (fileTreeComp != 0) + g.drawRect (fileTreeComp->getX(), fileTreeComp->getY(), + fileTreeComp->getWidth(), fileTreeComp->getHeight()); } void resized() { - treeView->setBoundsRelative (0.05f, 0.05f, 0.9f, 0.9f); + if (treeView != 0) + treeView->setBoundsRelative (0.05f, 0.07f, 0.9f, 0.9f); + else if (fileTreeComp != 0) + fileTreeComp->setBoundsRelative (0.05f, 0.07f, 0.9f, 0.9f); + + typeButton->changeWidthToFitText (20); + typeButton->setTopLeftPosition (40, 10); + } + + void showCustomTreeView() + { + deleteAndZero (treeView); + deleteAndZero (fileTreeComp); + + addAndMakeVisible (treeView = new TreeView()); + treeView->setRootItem (rootItem); + + resized(); + } + + void showFileTreeComp() + { + deleteAndZero (treeView); + deleteAndZero (fileTreeComp); + + addAndMakeVisible (fileTreeComp = new FileTreeComponent (*directoryList)); + + resized(); + } + + void buttonClicked (Button*) + { + PopupMenu m; + m.addItem (1, T("Custom treeview showing an XML tree")); + m.addItem (2, T("FileTreeComponent showing the file system")); + + const int r = m.showAt (typeButton); + + if (r == 1) + { + showCustomTreeView(); + } + else if (r == 2) + { + showFileTreeComp(); + } } juce_UseDebuggingNewOperator diff --git a/extras/the jucer/src/model/jucer_JucerDocument.cpp b/extras/the jucer/src/model/jucer_JucerDocument.cpp index 0cb1f92073..9bd8051fce 100644 --- a/extras/the jucer/src/model/jucer_JucerDocument.cpp +++ b/extras/the jucer/src/model/jucer_JucerDocument.cpp @@ -508,7 +508,7 @@ void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const // call these now, just to make sure they're the first two methods in the list. code.getCallbackCode (String::empty, T("void"), T("paint (Graphics& g)"), false) - << "//[UserPrePaint] Add your own custom painting code here..\n//[/UserPrePaint]"; + << "//[UserPrePaint] Add your own custom painting code here..\n//[/UserPrePaint]\n\n"; code.getCallbackCode (String::empty, T("void"), T("resized()"), false); diff --git a/src/juce_app_includes.h b/src/juce_app_includes.h index 0775385dce..6f29457438 100644 --- a/src/juce_app_includes.h +++ b/src/juce_app_includes.h @@ -539,6 +539,9 @@ #ifndef __JUCE_VIEWPORT_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_Viewport.h" #endif +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h" +#endif #ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ #include "juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.h" #endif @@ -566,6 +569,9 @@ #ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/filebrowser/juce_FilePreviewComponent.h" #endif +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h" +#endif #ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.h" #endif diff --git a/src/juce_appframework/audio/dsp/juce_AudioDataConverters.cpp b/src/juce_appframework/audio/dsp/juce_AudioDataConverters.cpp index dfee6fea19..5a2155ff6b 100644 --- a/src/juce_appframework/audio/dsp/juce_AudioDataConverters.cpp +++ b/src/juce_appframework/audio/dsp/juce_AudioDataConverters.cpp @@ -190,8 +190,8 @@ void AudioDataConverters::convertFloat32BEToFloat (const void* const source, flo //============================================================================== void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat, - const float* const source, - void* const dest, + const float* const source, + void* const dest, const int numSamples) { switch (destFormat) @@ -235,8 +235,8 @@ void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat, } void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat, - const void* const source, - float* const dest, + const void* const source, + float* const dest, const int numSamples) { switch (sourceFormat) @@ -280,9 +280,9 @@ void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat, } //============================================================================== -void AudioDataConverters::interleaveSamples (const float** const source, +void AudioDataConverters::interleaveSamples (const float** const source, float* const dest, - const int numSamples, + const int numSamples, const int numChannels) { for (int chan = 0; chan < numChannels; ++chan) @@ -298,9 +298,9 @@ void AudioDataConverters::interleaveSamples (const float** const source, } } -void AudioDataConverters::deinterleaveSamples (const float* const source, +void AudioDataConverters::deinterleaveSamples (const float* const source, float** const dest, - const int numSamples, + const int numSamples, const int numChannels) { for (int chan = 0; chan < numChannels; ++chan) diff --git a/src/juce_appframework/events/juce_ChangeBroadcaster.cpp b/src/juce_appframework/events/juce_ChangeBroadcaster.cpp index 44bf0cc0a0..efba8869c1 100644 --- a/src/juce_appframework/events/juce_ChangeBroadcaster.cpp +++ b/src/juce_appframework/events/juce_ChangeBroadcaster.cpp @@ -38,24 +38,24 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -ChangeBroadcaster::ChangeBroadcaster() throw() +JUCE_CALLTYPE ChangeBroadcaster::ChangeBroadcaster() throw() { // are you trying to create this object before or after juce has been intialised?? jassert (MessageManager::instance != 0); } -ChangeBroadcaster::~ChangeBroadcaster() +JUCE_CALLTYPE ChangeBroadcaster::~ChangeBroadcaster() { // all event-based objects must be deleted BEFORE juce is shut down! jassert (MessageManager::instance != 0); } -void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) throw() +void JUCE_CALLTYPE ChangeBroadcaster::addChangeListener (ChangeListener* const listener) throw() { changeListenerList.addChangeListener (listener); } -void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) throw() +void JUCE_CALLTYPE ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) throw() { jassert (changeListenerList.isValidMessageListener()); @@ -63,22 +63,22 @@ void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) th changeListenerList.removeChangeListener (listener); } -void ChangeBroadcaster::removeAllChangeListeners() throw() +void JUCE_CALLTYPE ChangeBroadcaster::removeAllChangeListeners() throw() { changeListenerList.removeAllChangeListeners(); } -void ChangeBroadcaster::sendChangeMessage (void* objectThatHasChanged) throw() +void JUCE_CALLTYPE ChangeBroadcaster::sendChangeMessage (void* objectThatHasChanged) throw() { changeListenerList.sendChangeMessage (objectThatHasChanged); } -void ChangeBroadcaster::sendSynchronousChangeMessage (void* objectThatHasChanged) +void JUCE_CALLTYPE ChangeBroadcaster::sendSynchronousChangeMessage (void* objectThatHasChanged) { changeListenerList.sendSynchronousChangeMessage (objectThatHasChanged); } -void ChangeBroadcaster::dispatchPendingMessages() +void JUCE_CALLTYPE ChangeBroadcaster::dispatchPendingMessages() { changeListenerList.dispatchPendingMessages(); } diff --git a/src/juce_appframework/events/juce_ChangeBroadcaster.h b/src/juce_appframework/events/juce_ChangeBroadcaster.h index 44919d7484..b7d978d0c7 100644 --- a/src/juce_appframework/events/juce_ChangeBroadcaster.h +++ b/src/juce_appframework/events/juce_ChangeBroadcaster.h @@ -48,7 +48,7 @@ class JUCE_API ChangeBroadcaster public: //============================================================================== /** Creates an ChangeBroadcaster. */ - ChangeBroadcaster() throw(); + JUCE_CALLTYPE ChangeBroadcaster() throw(); /** Destructor. */ virtual ~ChangeBroadcaster(); @@ -58,16 +58,16 @@ public: (Trying to add a listener that's already on the list will have no effect). */ - void addChangeListener (ChangeListener* const listener) throw(); + void JUCE_CALLTYPE addChangeListener (ChangeListener* const listener) throw(); /** Removes a listener from the list. If the listener isn't on the list, this won't have any effect. */ - void removeChangeListener (ChangeListener* const listener) throw(); + void JUCE_CALLTYPE removeChangeListener (ChangeListener* const listener) throw(); /** Removes all listeners from the list. */ - void removeAllChangeListeners() throw(); + void JUCE_CALLTYPE removeAllChangeListeners() throw(); //============================================================================== /** Broadcasts a change message to all the registered listeners. @@ -78,18 +78,18 @@ public: @see ChangeListenerList::sendActionMessage */ - void sendChangeMessage (void* objectThatHasChanged) throw(); + void JUCE_CALLTYPE sendChangeMessage (void* objectThatHasChanged) throw(); /** Sends a synchronous change message to all the registered listeners. @see ChangeListenerList::sendSynchronousChangeMessage */ - void sendSynchronousChangeMessage (void* objectThatHasChanged); + void JUCE_CALLTYPE sendSynchronousChangeMessage (void* objectThatHasChanged); /** If a change message has been sent but not yet dispatched, this will use sendSynchronousChangeMessage() to make the callback immediately. */ - void dispatchPendingMessages(); + void JUCE_CALLTYPE dispatchPendingMessages(); private: diff --git a/src/juce_appframework/events/juce_ChangeListenerList.cpp b/src/juce_appframework/events/juce_ChangeListenerList.cpp index 9d32a470ef..7126ee4c4e 100644 --- a/src/juce_appframework/events/juce_ChangeListenerList.cpp +++ b/src/juce_appframework/events/juce_ChangeListenerList.cpp @@ -37,17 +37,17 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -ChangeListenerList::ChangeListenerList() throw() +JUCE_CALLTYPE ChangeListenerList::ChangeListenerList() throw() : lastChangedObject (0), messagePending (false) { } -ChangeListenerList::~ChangeListenerList() throw() +JUCE_CALLTYPE ChangeListenerList::~ChangeListenerList() throw() { } -void ChangeListenerList::addChangeListener (ChangeListener* const listener) throw() +void JUCE_CALLTYPE ChangeListenerList::addChangeListener (ChangeListener* const listener) throw() { const ScopedLock sl (lock); @@ -57,19 +57,19 @@ void ChangeListenerList::addChangeListener (ChangeListener* const listener) thro listeners.add (listener); } -void ChangeListenerList::removeChangeListener (ChangeListener* const listener) throw() +void JUCE_CALLTYPE ChangeListenerList::removeChangeListener (ChangeListener* const listener) throw() { const ScopedLock sl (lock); listeners.removeValue (listener); } -void ChangeListenerList::removeAllChangeListeners() throw() +void JUCE_CALLTYPE ChangeListenerList::removeAllChangeListeners() throw() { const ScopedLock sl (lock); listeners.clear(); } -void ChangeListenerList::sendChangeMessage (void* objectThatHasChanged) throw() +void JUCE_CALLTYPE ChangeListenerList::sendChangeMessage (void* objectThatHasChanged) throw() { const ScopedLock sl (lock); @@ -86,7 +86,7 @@ void ChangeListenerList::handleMessage (const Message& message) sendSynchronousChangeMessage (message.pointerParameter); } -void ChangeListenerList::sendSynchronousChangeMessage (void* objectThatHasChanged) +void JUCE_CALLTYPE ChangeListenerList::sendSynchronousChangeMessage (void* objectThatHasChanged) { const ScopedLock sl (lock); messagePending = false; @@ -104,7 +104,7 @@ void ChangeListenerList::sendSynchronousChangeMessage (void* objectThatHasChange } } -void ChangeListenerList::dispatchPendingMessages() +void JUCE_CALLTYPE ChangeListenerList::dispatchPendingMessages() { if (messagePending) sendSynchronousChangeMessage (lastChangedObject); diff --git a/src/juce_appframework/events/juce_ChangeListenerList.h b/src/juce_appframework/events/juce_ChangeListenerList.h index bb64130fc6..b881037447 100644 --- a/src/juce_appframework/events/juce_ChangeListenerList.h +++ b/src/juce_appframework/events/juce_ChangeListenerList.h @@ -52,26 +52,26 @@ class JUCE_API ChangeListenerList : public MessageListener public: //============================================================================== /** Creates an empty list. */ - ChangeListenerList() throw(); + JUCE_CALLTYPE ChangeListenerList() throw(); /** Destructor. */ - ~ChangeListenerList() throw(); + JUCE_CALLTYPE ~ChangeListenerList() throw(); //============================================================================== /** Adds a listener to the list. (Trying to add a listener that's already on the list will have no effect). */ - void addChangeListener (ChangeListener* const listener) throw(); + void JUCE_CALLTYPE addChangeListener (ChangeListener* const listener) throw(); /** Removes a listener from the list. If the listener isn't on the list, this won't have any effect. */ - void removeChangeListener (ChangeListener* const listener) throw(); + void JUCE_CALLTYPE removeChangeListener (ChangeListener* const listener) throw(); /** Removes all listeners from the list. */ - void removeAllChangeListeners() throw(); + void JUCE_CALLTYPE removeAllChangeListeners() throw(); //============================================================================== /** Posts an asynchronous change message to all the listeners. @@ -91,19 +91,19 @@ public: and can be any value the application needs @see sendSynchronousChangeMessage */ - void sendChangeMessage (void* objectThatHasChanged) throw(); + void JUCE_CALLTYPE sendChangeMessage (void* objectThatHasChanged) throw(); /** This will synchronously callback all the ChangeListeners. Use this if you need to synchronously force a call to all the listeners' ChangeListener::changeListenerCallback() methods. */ - void sendSynchronousChangeMessage (void* objectThatHasChanged); + void JUCE_CALLTYPE sendSynchronousChangeMessage (void* objectThatHasChanged); /** If a change message has been sent but not yet dispatched, this will use sendSynchronousChangeMessage() to make the callback immediately. */ - void dispatchPendingMessages(); + void JUCE_CALLTYPE dispatchPendingMessages(); //============================================================================== /** @internal */ diff --git a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp index 828fbe852c..e3c41feedc 100644 --- a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp @@ -160,7 +160,7 @@ public: } } - UniformTextSection* split (const int indexToBreakAt, + UniformTextSection* split (const int indexToBreakAt, const tchar passwordCharacter) throw() { UniformTextSection* const section2 = new UniformTextSection (String::empty, @@ -271,7 +271,7 @@ private: VoidArray atoms; //============================================================================== - void initialiseAtoms (const String& textToParse, + void initialiseAtoms (const String& textToParse, const tchar passwordCharacter) throw() { int i = 0; diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp index 4fdd63d8f0..eed60ee63a 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp @@ -311,6 +311,9 @@ TreeView::TreeView (const String& componentName) TreeView::~TreeView() { + if (rootItem != 0) + rootItem->setOwnerView (0); + deleteAllChildren(); } @@ -326,6 +329,9 @@ void TreeView::setRootItem (TreeViewItem* const newRootItem) newRootItem->ownerView->setRootItem (0); } + if (rootItem != 0) + rootItem->setOwnerView (0); + rootItem = newRootItem; if (newRootItem != 0) diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.h b/src/juce_appframework/gui/components/controls/juce_TreeView.h index 4b4eb9e6a1..56825ade08 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.h +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.h @@ -394,10 +394,12 @@ public: you want the tree to contain a number of root items, you should still use a single root item above these, but hide it using setRootItemVisible(). - The object passed in will not be deleted by the treeview, it's up to the caller - to delete it when no longer needed. + You can pass in 0 to this method to clear the tree and remove its current root item. - You can pass in 0 to this method to clear the tree. + The object passed in will not be deleted by the treeview, it's up to the caller + to delete it when no longer needed. BUT make absolutely sure that you don't delete + this item until you've removed it from the tree, either by calling setRootItem (0), + or by deleting the tree first. */ void setRootItem (TreeViewItem* const newRootItem); diff --git a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp index 5af4e3d90d..ff030855c6 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp @@ -33,21 +33,18 @@ BEGIN_JUCE_NAMESPACE -#include "juce_FileListComponent.h" -#include "../lookandfeel/juce_LookAndFeel.h" -#include "../../graphics/imaging/juce_ImageCache.h" -#include "../../../events/juce_AsyncUpdater.h" +#include "juce_DirectoryContentsDisplayComponent.h" +#include "../juce_ComponentDeletionWatcher.h" -Image* juce_createIconForFile (const File& file); //============================================================================== -FileListComponentBase::FileListComponentBase (DirectoryContentsList& listToShow) +DirectoryContentsDisplayComponent::DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow) : fileList (listToShow), listeners (2) { } -FileListComponentBase::~FileListComponentBase() +DirectoryContentsDisplayComponent::~DirectoryContentsDisplayComponent() { } @@ -56,19 +53,20 @@ FileBrowserListener::~FileBrowserListener() { } -void FileListComponentBase::addListener (FileBrowserListener* const listener) throw() +void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) throw() { jassert (listener != 0); + if (listener != 0) listeners.add (listener); } -void FileListComponentBase::removeListener (FileBrowserListener* const listener) throw() +void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) throw() { listeners.removeValue (listener); } -void FileListComponentBase::sendSelectionChangeMessage() +void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() { const ComponentDeletionWatcher deletionWatcher (dynamic_cast (this)); @@ -83,7 +81,7 @@ void FileListComponentBase::sendSelectionChangeMessage() } } -void FileListComponentBase::sendMouseClickMessage (const File& file, const MouseEvent& e) +void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) { if (fileList.getDirectory().exists()) { @@ -101,7 +99,7 @@ void FileListComponentBase::sendMouseClickMessage (const File& file, const Mouse } } -void FileListComponentBase::sendDoubleClickMessage (const File& file) +void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file) { if (fileList.getDirectory().exists()) { @@ -119,573 +117,5 @@ void FileListComponentBase::sendDoubleClickMessage (const File& file) } } -//============================================================================== -FileListComponent::FileListComponent (DirectoryContentsList& listToShow) - : FileListComponentBase (listToShow), - ListBox (String::empty, 0) -{ - setModel (this); - fileList.addChangeListener (this); -} - -FileListComponent::~FileListComponent() -{ - fileList.removeChangeListener (this); - deleteAllChildren(); -} - -const File FileListComponent::getSelectedFile() const -{ - return fileList.getFile (getSelectedRow()); -} - -void FileListComponent::scrollToTop() -{ - getVerticalScrollBar()->setCurrentRangeStart (0); -} - -//============================================================================== -void FileListComponent::changeListenerCallback (void*) -{ - updateContent(); -} - -//============================================================================== -class FileListItemComponent : public Component, - public TimeSliceClient, - public AsyncUpdater -{ -public: - JUCE_CALLTYPE FileListItemComponent (FileListComponent& owner_, - TimeSliceThread& thread_) throw() - : owner (owner_), - thread (thread_), - icon (0), - defaultFileIcon (0), - defaultFolderIcon (0) - { - } - - JUCE_CALLTYPE ~FileListItemComponent() throw() - { - thread.removeTimeSliceClient (this); - - clearIcon(); - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - } - - void paint (Graphics& g) - { - if (highlighted) - g.fillAll (owner.findColour (FileListComponent::highlightColourId)); - - g.setColour (owner.findColour (FileListComponent::textColourId)); - g.setFont (getHeight() * 0.7f); - - const int x = 32; - - Image* im = icon; - - if (im == 0) - { - if (defaultFileIcon == 0) - lookAndFeelChanged(); - - im = isDirectory ? defaultFolderIcon : defaultFileIcon; - } - - if (im != 0) - { - g.drawImageWithin (im, 2, 2, x - 4, getHeight() - 4, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, - false); - } - - if (getWidth() > 450 && ! isDirectory) - { - const int sizeX = proportionOfWidth (0.7f); - const int dateX = proportionOfWidth (0.8f); - - g.drawFittedText (file.getFileName(), - x, 0, sizeX - x, getHeight(), - Justification::centredLeft, 1); - - g.setFont (getHeight() * 0.5f); - g.setColour (Colours::darkgrey); - - if (! isDirectory) - { - g.drawFittedText (fileSize, - sizeX, 0, dateX - sizeX - 8, getHeight(), - Justification::centredRight, 1); - - g.drawFittedText (modTime, - dateX, 0, getWidth() - 8 - dateX, getHeight(), - Justification::centredRight, 1); - } - } - else - { - g.drawFittedText (file.getFileName(), - x, 0, getWidth() - x, getHeight(), - Justification::centredLeft, 1); - - } - } - - void resized() - { - } - - void lookAndFeelChanged() - { - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - defaultFileIcon = getLookAndFeel().getDefaultDocumentFileImage(); - defaultFolderIcon = getLookAndFeel().getDefaultFolderImage(); - } - - void mouseDown (const MouseEvent& e) - { - owner.selectRowsBasedOnModifierKeys (index, e.mods); - owner.sendMouseClickMessage (file, e); - } - - void mouseDoubleClick (const MouseEvent&) - { - owner.sendDoubleClickMessage (file); - } - - void update (const File& root, - const DirectoryContentsList::FileInfo* fileInfo, - const int index_, - const bool highlighted_) - { - thread.removeTimeSliceClient (this); - - if (highlighted_ != highlighted - || index_ != index) - { - index = index_; - highlighted = highlighted_; - repaint(); - } - - File newFile; - String newFileSize; - String newModTime; - - if (fileInfo != 0) - { - newFile = root.getChildFile (fileInfo->filename); - newFileSize = File::descriptionOfSizeInBytes (fileInfo->fileSize); - newModTime = fileInfo->modificationTime.formatted (T("%d %b '%y %H:%M")); - } - - if (newFile != file - || fileSize != newFileSize - || modTime != newModTime) - { - file = newFile; - fileSize = newFileSize; - modTime = newModTime; - - isDirectory = fileInfo != 0 && fileInfo->isDirectory; - repaint(); - - clearIcon(); - } - - if (file != File::nonexistent - && icon == 0 && ! isDirectory) - { - updateIcon (true); - - if (icon == 0) - thread.addTimeSliceClient (this); - } - } - - bool useTimeSlice() - { - updateIcon (false); - return false; - } - - void handleAsyncUpdate() - { - repaint(); - } - -private: - FileListComponent& owner; - TimeSliceThread& thread; - bool highlighted; - int index; - File file; - String fileSize; - String modTime; - Image* icon; - bool isDirectory; - Image* defaultFileIcon; - Image* defaultFolderIcon; - - void JUCE_CALLTYPE clearIcon() throw() - { - ImageCache::release (icon); - icon = 0; - } - - void JUCE_CALLTYPE updateIcon (const bool onlyUpdateIfCached) - { - if (icon == 0) - { - const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode(); - Image* im = ImageCache::getFromHashCode (hashCode); - - if (im == 0 && ! onlyUpdateIfCached) - { - im = juce_createIconForFile (file); - - if (im != 0) - ImageCache::addImageToCache (im, hashCode); - } - - if (im != 0) - { - icon = im; - triggerAsyncUpdate(); - } - } - } -}; - -int FileListComponent::getNumRows() -{ - return fileList.getNumFiles(); -} - -void FileListComponent::paintListBoxItem (int, Graphics&, int, int, bool) -{ -} - -Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, Component* existingComponentToUpdate) -{ - FileListItemComponent* comp = dynamic_cast (existingComponentToUpdate); - - if (comp == 0) - { - delete existingComponentToUpdate; - existingComponentToUpdate = comp = new FileListItemComponent (*this, fileList.getTimeSliceThread()); - } - - DirectoryContentsList::FileInfo fileInfo; - - if (fileList.getFileInfo (row, fileInfo)) - comp->update (fileList.getDirectory(), &fileInfo, row, isSelected); - else - comp->update (fileList.getDirectory(), 0, row, isSelected); - - return comp; -} - -void FileListComponent::selectedRowsChanged (int /*lastRowSelected*/) -{ - sendSelectionChangeMessage(); -} - -void FileListComponent::deleteKeyPressed (int /*currentSelectedRow*/) -{ -} - -void FileListComponent::returnKeyPressed (int currentSelectedRow) -{ - sendDoubleClickMessage (fileList.getFile (currentSelectedRow)); -} - -//============================================================================== -class FileListTreeItem : public TreeViewItem, - public TimeSliceClient, - public AsyncUpdater, - public ChangeListener -{ -public: - JUCE_CALLTYPE FileListTreeItem (FileTreeComponent& owner_, - DirectoryContentsList* const parentContentsList_, - const int indexInContentsList_, - const File& file_, - TimeSliceThread& thread_) throw() - : owner (owner_), - parentContentsList (parentContentsList_), - indexInContentsList (indexInContentsList_), - subContentsList (0), - canDeleteSubContentsList (false), - file (file_), - thread (thread_), - icon (0), - defaultFileIcon (0), - defaultFolderIcon (0) - { - DirectoryContentsList::FileInfo fileInfo; - - if (parentContentsList_ != 0 - && parentContentsList_->getFileInfo (indexInContentsList_, fileInfo)) - { - fileSize = File::descriptionOfSizeInBytes (fileInfo.fileSize); - modTime = fileInfo.modificationTime.formatted (T("%d %b '%y %H:%M")); - isDirectory = fileInfo.isDirectory; - } - else - { - isDirectory = true; - } - - if (file != File::nonexistent && ! isDirectory) - { - updateIcon (true); - - if (icon == 0) - thread.addTimeSliceClient (this); - } - } - - JUCE_CALLTYPE ~FileListTreeItem() throw() - { - thread.removeTimeSliceClient (this); - - clearIcon(); - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - delete subContentsList; - } - - bool mightContainSubItems() { return isDirectory; } - const String getUniqueName() const { return file.getFullPathName(); } - - void itemOpennessChanged (bool isNowOpen) - { - if (isNowOpen) - { - clearSubItems(); - - isDirectory = file.isDirectory(); - - if (isDirectory) - { - if (subContentsList == 0) - { - jassert (parentContentsList != 0); - - DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); - l->setDirectory (file, true, true); - - setSubContentsList (l); - canDeleteSubContentsList = true; - } - - changeListenerCallback (0); - } - } - } - - void JUCE_CALLTYPE setSubContentsList (DirectoryContentsList* newList) throw() - { - jassert (subContentsList == 0); - subContentsList = newList; - newList->addChangeListener (this); - } - - void changeListenerCallback (void*) - { - clearSubItems(); - - if (isOpen() && subContentsList != 0) - { - for (int i = 0; i < subContentsList->getNumFiles(); ++i) - { - FileListTreeItem* const item - = new FileListTreeItem (owner, subContentsList, i, subContentsList->getFile(i), thread); - - addSubItem (item); - } - } - } - - void paintItem (Graphics& g, int width, int height) - { - if (isSelected()) - g.fillAll (owner.findColour (FileTreeComponent::highlightColourId)); - - g.setColour (owner.findColour (FileTreeComponent::textColourId)); - g.setFont (height * 0.7f); - - const int x = 32; - - Image* im = icon; - - if (im == 0) - { - if (defaultFileIcon == 0) - reloadIcons(); - - im = isDirectory ? defaultFolderIcon : defaultFileIcon; - } - - if (im != 0) - { - g.drawImageWithin (im, 2, 2, x - 4, height - 4, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, - false); - } - - if (width > 450 && ! isDirectory) - { - const int sizeX = roundFloatToInt (width * 0.7f); - const int dateX = roundFloatToInt (width * 0.8f); - - g.drawFittedText (file.getFileName(), - x, 0, sizeX - x, height, - Justification::centredLeft, 1); - - g.setFont (height * 0.5f); - g.setColour (Colours::darkgrey); - - if (! isDirectory) - { - g.drawFittedText (fileSize, - sizeX, 0, dateX - sizeX - 8, height, - Justification::centredRight, 1); - - g.drawFittedText (modTime, - dateX, 0, width - 8 - dateX, height, - Justification::centredRight, 1); - } - } - else - { - g.drawFittedText (file.getFileName(), - x, 0, width - x, height, - Justification::centredLeft, 1); - - } - } - - void itemClicked (const MouseEvent& e) - { - owner.sendMouseClickMessage (file, e); - } - - void itemDoubleClicked (const MouseEvent&) - { - owner.sendDoubleClickMessage (file); - } - - void itemSelectionChanged (bool) - { - owner.sendSelectionChangeMessage(); - } - - bool useTimeSlice() - { - updateIcon (false); - thread.removeTimeSliceClient (this); - return false; - } - - void handleAsyncUpdate() - { - owner.repaint(); - } - - const File& getFile() const throw() { return file; } - -private: - FileTreeComponent& owner; - DirectoryContentsList* parentContentsList; - int indexInContentsList; - DirectoryContentsList* subContentsList; - bool isDirectory, canDeleteSubContentsList; - TimeSliceThread& thread; - const File file; - String fileSize; - String modTime; - Image* icon; - Image* defaultFileIcon; - Image* defaultFolderIcon; - - void clearIcon() throw() - { - ImageCache::release (icon); - icon = 0; - } - - void reloadIcons() throw() - { - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - defaultFileIcon = owner.getLookAndFeel().getDefaultDocumentFileImage(); - defaultFolderIcon = owner.getLookAndFeel().getDefaultFolderImage(); - } - - void updateIcon (const bool onlyUpdateIfCached) - { - if (icon == 0) - { - const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode(); - Image* im = ImageCache::getFromHashCode (hashCode); - - if (im == 0 && ! onlyUpdateIfCached) - { - im = juce_createIconForFile (file); - - if (im != 0) - ImageCache::addImageToCache (im, hashCode); - } - - if (im != 0) - { - icon = im; - triggerAsyncUpdate(); - } - } - } -}; - -//============================================================================== -FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow) - : FileListComponentBase (listToShow) -{ - FileListTreeItem* const root - = new FileListTreeItem (*this, 0, 0, File::nonexistent, listToShow.getTimeSliceThread()); - - root->setSubContentsList (&listToShow); - setRootItemVisible (false); - setRootItem (root); -} - -FileTreeComponent::~FileTreeComponent() -{ - setRootItem (0); -} - -//============================================================================== -const File FileTreeComponent::getSelectedFile() const -{ - FileListTreeItem* item = dynamic_cast (getSelectedItem (0)); - - if (item != 0) - return item->getFile(); - - return File::nonexistent; -} - -void FileTreeComponent::scrollToTop() -{ - getViewport()->getVerticalScrollBar()->setCurrentRangeStart (0); -} END_JUCE_NAMESPACE diff --git a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h index 5acc8f8ff6..773f0e3538 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h +++ b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h @@ -29,8 +29,8 @@ ============================================================================== */ -#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__x -#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__x +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +#define __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ #include "juce_DirectoryContentsList.h" #include "juce_FileBrowserListener.h" @@ -42,16 +42,16 @@ @see DirectoryContentsList */ -class JUCE_API FileListComponentBase +class JUCE_API DirectoryContentsDisplayComponent { public: //============================================================================== - /** + /** */ - FileListComponentBase (DirectoryContentsList& listToShow); + DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow); /** Destructor. */ - virtual ~FileListComponentBase(); + virtual ~DirectoryContentsDisplayComponent(); //============================================================================== /** Returns the file that the user has currently selected. @@ -60,6 +60,7 @@ public: */ virtual const File getSelectedFile() const = 0; + /** Scrolls this view to the top. */ virtual void scrollToTop() = 0; //============================================================================== @@ -108,101 +109,9 @@ protected: DirectoryContentsList& fileList; SortedSet listeners; - FileListComponentBase (const FileListComponentBase&); - const FileListComponentBase& operator= (const FileListComponentBase&); + DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); + const DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); }; -//============================================================================== -/** - A listbox showing the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API FileListComponent : public FileListComponentBase, - public ListBox, - private ListBoxModel, - private ChangeListener -{ -public: - //============================================================================== - /** Creates a listbox to show the contents of a specified directory. - */ - FileListComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileListComponent(); - - //============================================================================== - /** Returns the file that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile() const; - - void scrollToTop(); - - //============================================================================== - /** @internal */ - void changeListenerCallback (void*); - /** @internal */ - int getNumRows(); - /** @internal */ - void paintListBoxItem (int, Graphics&, int, int, bool); - /** @internal */ - Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); - /** @internal */ - void selectedRowsChanged (int lastRowSelected); - /** @internal */ - void deleteKeyPressed (int currentSelectedRow); - /** @internal */ - void returnKeyPressed (int currentSelectedRow); - - //============================================================================== - juce_UseDebuggingNewOperator - -private: - FileListComponent (const FileListComponent&); - const FileListComponent& operator= (const FileListComponent&); -}; - - - - -//============================================================================== -/** - A listbox showing the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API FileTreeComponent : public FileListComponentBase, - public TreeView -{ -public: - //============================================================================== - /** Creates a listbox to show the contents of a specified directory. - */ - FileTreeComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileTreeComponent(); - - //============================================================================== - /** Returns the file that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile() const; - - void scrollToTop(); - - //============================================================================== - juce_UseDebuggingNewOperator - -private: - FileTreeComponent (const FileTreeComponent&); - const FileTreeComponent& operator= (const FileTreeComponent&); -}; - - -#endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__ +#endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ diff --git a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.h b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.h index 37aaa416a4..35cff1fcad 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.h +++ b/src/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.h @@ -178,6 +178,11 @@ public: */ const File getFile (const int index) const; + /** Returns the file filter being used. + + The filter is specified in the constructor. + */ + const FileFilter* getFilter() const throw() { return fileFilter; } //============================================================================== /** @internal */ diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp index 5d12e2435c..edee962eb5 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.cpp @@ -38,6 +38,7 @@ BEGIN_JUCE_NAMESPACE #include "../../graphics/drawables/juce_DrawablePath.h" #include "../../../../juce_core/text/juce_LocalisedStrings.h" #include "../../../../juce_core/basics/juce_SystemStats.h" +#include "juce_FileListComponent.h" //============================================================================== @@ -83,9 +84,13 @@ FileBrowserComponent::FileBrowserComponent (FileChooserMode mode_, fileList = new DirectoryContentsList (fileFilter, thread); - addAndMakeVisible (fileListComponent = new FileListComponent (*fileList)); - fileListComponent->addListener (this); - fileListComponent->setOutlineThickness (1); + // this component could alternatively be a FileTreeComponent + FileListComponent* const list = new FileListComponent (*fileList); + list->setOutlineThickness (1); + + fileListComponent = list; + addAndMakeVisible (list); + list->addListener (this); addAndMakeVisible (currentPathBox = new ComboBox (T("path"))); currentPathBox->setEditableText (true); @@ -190,7 +195,7 @@ void FileBrowserComponent::setRoot (const File& newRootDirectory) { if (currentRoot != newRootDirectory) { - fileListComponent->getVerticalScrollBar()->setCurrentRangeStart (0); + fileListComponent->scrollToTop(); if (mode == chooseDirectoryMode) filenameBox->setText (String::empty, false); @@ -279,9 +284,11 @@ void FileBrowserComponent::resized() goUpButton->setBounds (x + w - upButtonWidth, y, upButtonWidth, controlsHeight); y += controlsHeight + 4; - fileListComponent->setBounds (x, y, w, getHeight() - y - bottomSectionHeight); - y = fileListComponent->getBottom() + 4; + Component* const listAsComp = dynamic_cast (fileListComponent); + listAsComp->setBounds (x, y, w, getHeight() - y - bottomSectionHeight); + + y = listAsComp->getBottom() + 4; filenameBox->setBounds (x + 50, y, w - 50, controlsHeight); } @@ -313,7 +320,7 @@ void FileBrowserComponent::selectionChanged() if ((mode == chooseDirectoryMode && selected.isDirectory()) || selected.existsAsFile()) { - filenameBox->setText (selected.getFileName(), false); + filenameBox->setText (selected.getRelativePathFrom (getRoot()), false); } sendListenerChangeMessage(); diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h index 2527ada175..44ff25dcd1 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileBrowserComponent.h @@ -32,7 +32,7 @@ #ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ #define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -#include "juce_FileListComponent.h" +#include "juce_DirectoryContentsDisplayComponent.h" #include "juce_FilePreviewComponent.h" #include "../../../../juce_core/io/files/juce_File.h" #include "../../../../juce_core/containers/juce_BitArray.h" @@ -190,7 +190,7 @@ private: File currentRoot; SortedSet listeners; - FileListComponent* fileListComponent; + DirectoryContentsDisplayComponent* fileListComponent; FilePreviewComponent* previewComp; ComboBox* currentPathBox; TextEditor* filenameBox; diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp index 7a9807ba86..6342f638e7 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp @@ -43,9 +43,8 @@ Image* juce_createIconForFile (const File& file); //============================================================================== FileListComponent::FileListComponent (DirectoryContentsList& listToShow) - : ListBox (String::empty, 0), - fileList (listToShow), - listeners (2) + : DirectoryContentsDisplayComponent (listToShow), + ListBox (String::empty, 0) { setModel (this); fileList.addChangeListener (this); @@ -62,29 +61,12 @@ const File FileListComponent::getSelectedFile() const return fileList.getFile (getSelectedRow()); } -//============================================================================== -FileBrowserListener::~FileBrowserListener() +void FileListComponent::scrollToTop() { -} - -void FileListComponent::addListener (FileBrowserListener* const listener) throw() -{ - jassert (listener != 0); - if (listener != 0) - listeners.add (listener); -} - -void FileListComponent::removeListener (FileBrowserListener* const listener) throw() -{ - listeners.removeValue (listener); + getVerticalScrollBar()->setCurrentRangeStart (0); } //============================================================================== -void FileListComponent::resized() -{ - ListBox::resized(); -} - void FileListComponent::changeListenerCallback (void*) { updateContent(); @@ -96,95 +78,30 @@ class FileListItemComponent : public Component, public AsyncUpdater { public: - FileListItemComponent (FileListComponent& owner_, - TimeSliceThread& thread_) + //============================================================================== + JUCE_CALLTYPE FileListItemComponent (FileListComponent& owner_, + TimeSliceThread& thread_) throw() : owner (owner_), thread (thread_), - icon (0), - defaultFileIcon (0), - defaultFolderIcon (0) + icon (0) { } - ~FileListItemComponent() + JUCE_CALLTYPE ~FileListItemComponent() throw() { thread.removeTimeSliceClient (this); clearIcon(); - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); } + //============================================================================== void paint (Graphics& g) { - if (highlighted) - g.fillAll (owner.findColour (FileListComponent::highlightColourId)); - - g.setColour (owner.findColour (FileListComponent::textColourId)); - g.setFont (getHeight() * 0.7f); - - const int x = 32; - - Image* im = icon; - - if (im == 0) - { - if (defaultFileIcon == 0) - lookAndFeelChanged(); - - im = isDirectory ? defaultFolderIcon : defaultFileIcon; - } - - if (im != 0) - { - g.drawImageWithin (im, 2, 2, x - 4, getHeight() - 4, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, - false); - } - - if (getWidth() > 450 && ! isDirectory) - { - const int sizeX = proportionOfWidth (0.7f); - const int dateX = proportionOfWidth (0.8f); - - g.drawFittedText (file.getFileName(), - x, 0, sizeX - x, getHeight(), - Justification::centredLeft, 1); - - g.setFont (getHeight() * 0.5f); - g.setColour (Colours::darkgrey); - - if (! isDirectory) - { - g.drawFittedText (fileSize, - sizeX, 0, dateX - sizeX - 8, getHeight(), - Justification::centredRight, 1); - - g.drawFittedText (modTime, - dateX, 0, getWidth() - 8 - dateX, getHeight(), - Justification::centredRight, 1); - } - } - else - { - g.drawFittedText (file.getFileName(), - x, 0, getWidth() - x, getHeight(), - Justification::centredLeft, 1); - - } - } - - void resized() - { - } - - void lookAndFeelChanged() - { - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - defaultFileIcon = getLookAndFeel().getDefaultDocumentFileImage(); - defaultFolderIcon = getLookAndFeel().getDefaultFolderImage(); + getLookAndFeel().drawFileBrowserRow (g, getWidth(), getHeight(), + file.getFileName(), + icon, + fileSize, modTime, + isDirectory, highlighted); } void mouseDown (const MouseEvent& e) @@ -198,10 +115,10 @@ public: owner.sendDoubleClickMessage (file); } - void update (const File& root, - const DirectoryContentsList::FileInfo* fileInfo, - const int index_, - const bool highlighted_) + void JUCE_CALLTYPE update (const File& root, + const DirectoryContentsList::FileInfo* const fileInfo, + const int index_, + const bool highlighted_) throw() { thread.removeTimeSliceClient (this); @@ -259,6 +176,9 @@ public: repaint(); } + //============================================================================== + juce_UseDebuggingNewOperator + private: FileListComponent& owner; TimeSliceThread& thread; @@ -269,16 +189,14 @@ private: String modTime; Image* icon; bool isDirectory; - Image* defaultFileIcon; - Image* defaultFolderIcon; - void clearIcon() + void JUCE_CALLTYPE clearIcon() throw() { ImageCache::release (icon); icon = 0; } - void updateIcon (const bool onlyUpdateIfCached) + void JUCE_CALLTYPE updateIcon (const bool onlyUpdateIfCached) throw() { if (icon == 0) { @@ -302,6 +220,7 @@ private: } }; +//============================================================================== int FileListComponent::getNumRows() { return fileList.getNumFiles(); @@ -333,17 +252,7 @@ Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, void FileListComponent::selectedRowsChanged (int /*lastRowSelected*/) { - ComponentDeletionWatcher deletionWatcher (this); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged(); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } + sendSelectionChangeMessage(); } void FileListComponent::deleteKeyPressed (int /*currentSelectedRow*/) @@ -355,41 +264,5 @@ void FileListComponent::returnKeyPressed (int currentSelectedRow) sendDoubleClickMessage (fileList.getFile (currentSelectedRow)); } -void FileListComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) -{ - if (file.exists()) - { - ComponentDeletionWatcher deletionWatcher (this); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (file, e); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } - } -} - -void FileListComponent::sendDoubleClickMessage (const File& file) -{ - if (file.exists()) - { - ComponentDeletionWatcher deletionWatcher (this); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (file); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } - } -} - END_JUCE_NAMESPACE diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.h b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.h index a9e6be177d..4ff90f5ab3 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.h +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.h @@ -32,18 +32,26 @@ #ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ #define __JUCE_FILELISTCOMPONENT_JUCEHEADER__ -#include "juce_DirectoryContentsList.h" +#include "juce_DirectoryContentsDisplayComponent.h" #include "juce_FileBrowserListener.h" #include "../controls/juce_ListBox.h" +#include "../controls/juce_TreeView.h" //============================================================================== /** - A listbox showing the files in a directory. + A component that displays the files in a directory as a listbox. - @see DirectoryContentsList + This implements the DirectoryContentsDisplayComponent base class so that + it can be used in a FileBrowserComponent. + + To attach a listener to it, use its DirectoryContentsDisplayComponent base + class and the FileBrowserListener class. + + @see DirectoryContentsList, FileTreeComponent */ -class JUCE_API FileListComponent : public ListBox, +class JUCE_API FileListComponent : public DirectoryContentsDisplayComponent, + public ListBox, private ListBoxModel, private ChangeListener { @@ -63,40 +71,10 @@ public: */ const File getSelectedFile() const; - //============================================================================== - /** Adds a listener to be told when files are selected or clicked. - - @see removeListener - */ - void addListener (FileBrowserListener* const listener) throw(); - - /** Removes a listener. - - @see addListener - */ - void removeListener (FileBrowserListener* const listener) throw(); - + /** Scrolls to the top of the list. */ + void scrollToTop(); //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - Note that you can also use the constants from TextEditor::ColourIds to change the - colour of the text editor that is opened when a label is editable. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */ - textColourId = 0x1000541, /**< The colour for the text. */ - }; - - //============================================================================== - /** @internal */ - void resized(); /** @internal */ void changeListenerCallback (void*); /** @internal */ @@ -111,18 +89,11 @@ public: void deleteKeyPressed (int currentSelectedRow); /** @internal */ void returnKeyPressed (int currentSelectedRow); - /** @internal */ - void sendDoubleClickMessage (const File& file); - /** @internal */ - void sendMouseClickMessage (const File& file, const MouseEvent& e); //============================================================================== juce_UseDebuggingNewOperator private: - DirectoryContentsList& fileList; - SortedSet listeners; - FileListComponent (const FileListComponent&); const FileListComponent& operator= (const FileListComponent&); }; diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.cpp deleted file mode 100644 index 5af4e3d90d..0000000000 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-7 by Raw Material Software ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the - GNU General Public License, as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any later version. - - JUCE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with JUCE; if not, visit www.gnu.org/licenses or write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - ------------------------------------------------------------------------------ - - If you'd like to release a closed-source product which uses JUCE, commercial - licenses are also available: visit www.rawmaterialsoftware.com/juce for - more information. - - ============================================================================== -*/ - -#include "../../../../juce_core/basics/juce_StandardHeader.h" - -BEGIN_JUCE_NAMESPACE - -#include "juce_FileListComponent.h" -#include "../lookandfeel/juce_LookAndFeel.h" -#include "../../graphics/imaging/juce_ImageCache.h" -#include "../../../events/juce_AsyncUpdater.h" - -Image* juce_createIconForFile (const File& file); - -//============================================================================== -FileListComponentBase::FileListComponentBase (DirectoryContentsList& listToShow) - : fileList (listToShow), - listeners (2) -{ -} - -FileListComponentBase::~FileListComponentBase() -{ -} - -//============================================================================== -FileBrowserListener::~FileBrowserListener() -{ -} - -void FileListComponentBase::addListener (FileBrowserListener* const listener) throw() -{ - jassert (listener != 0); - if (listener != 0) - listeners.add (listener); -} - -void FileListComponentBase::removeListener (FileBrowserListener* const listener) throw() -{ - listeners.removeValue (listener); -} - -void FileListComponentBase::sendSelectionChangeMessage() -{ - const ComponentDeletionWatcher deletionWatcher (dynamic_cast (this)); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged(); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } -} - -void FileListComponentBase::sendMouseClickMessage (const File& file, const MouseEvent& e) -{ - if (fileList.getDirectory().exists()) - { - const ComponentDeletionWatcher deletionWatcher (dynamic_cast (this)); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (file, e); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } - } -} - -void FileListComponentBase::sendDoubleClickMessage (const File& file) -{ - if (fileList.getDirectory().exists()) - { - const ComponentDeletionWatcher deletionWatcher (dynamic_cast (this)); - - for (int i = listeners.size(); --i >= 0;) - { - ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (file); - - if (deletionWatcher.hasBeenDeleted()) - return; - - i = jmin (i, listeners.size() - 1); - } - } -} - -//============================================================================== -FileListComponent::FileListComponent (DirectoryContentsList& listToShow) - : FileListComponentBase (listToShow), - ListBox (String::empty, 0) -{ - setModel (this); - fileList.addChangeListener (this); -} - -FileListComponent::~FileListComponent() -{ - fileList.removeChangeListener (this); - deleteAllChildren(); -} - -const File FileListComponent::getSelectedFile() const -{ - return fileList.getFile (getSelectedRow()); -} - -void FileListComponent::scrollToTop() -{ - getVerticalScrollBar()->setCurrentRangeStart (0); -} - -//============================================================================== -void FileListComponent::changeListenerCallback (void*) -{ - updateContent(); -} - -//============================================================================== -class FileListItemComponent : public Component, - public TimeSliceClient, - public AsyncUpdater -{ -public: - JUCE_CALLTYPE FileListItemComponent (FileListComponent& owner_, - TimeSliceThread& thread_) throw() - : owner (owner_), - thread (thread_), - icon (0), - defaultFileIcon (0), - defaultFolderIcon (0) - { - } - - JUCE_CALLTYPE ~FileListItemComponent() throw() - { - thread.removeTimeSliceClient (this); - - clearIcon(); - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - } - - void paint (Graphics& g) - { - if (highlighted) - g.fillAll (owner.findColour (FileListComponent::highlightColourId)); - - g.setColour (owner.findColour (FileListComponent::textColourId)); - g.setFont (getHeight() * 0.7f); - - const int x = 32; - - Image* im = icon; - - if (im == 0) - { - if (defaultFileIcon == 0) - lookAndFeelChanged(); - - im = isDirectory ? defaultFolderIcon : defaultFileIcon; - } - - if (im != 0) - { - g.drawImageWithin (im, 2, 2, x - 4, getHeight() - 4, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, - false); - } - - if (getWidth() > 450 && ! isDirectory) - { - const int sizeX = proportionOfWidth (0.7f); - const int dateX = proportionOfWidth (0.8f); - - g.drawFittedText (file.getFileName(), - x, 0, sizeX - x, getHeight(), - Justification::centredLeft, 1); - - g.setFont (getHeight() * 0.5f); - g.setColour (Colours::darkgrey); - - if (! isDirectory) - { - g.drawFittedText (fileSize, - sizeX, 0, dateX - sizeX - 8, getHeight(), - Justification::centredRight, 1); - - g.drawFittedText (modTime, - dateX, 0, getWidth() - 8 - dateX, getHeight(), - Justification::centredRight, 1); - } - } - else - { - g.drawFittedText (file.getFileName(), - x, 0, getWidth() - x, getHeight(), - Justification::centredLeft, 1); - - } - } - - void resized() - { - } - - void lookAndFeelChanged() - { - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - defaultFileIcon = getLookAndFeel().getDefaultDocumentFileImage(); - defaultFolderIcon = getLookAndFeel().getDefaultFolderImage(); - } - - void mouseDown (const MouseEvent& e) - { - owner.selectRowsBasedOnModifierKeys (index, e.mods); - owner.sendMouseClickMessage (file, e); - } - - void mouseDoubleClick (const MouseEvent&) - { - owner.sendDoubleClickMessage (file); - } - - void update (const File& root, - const DirectoryContentsList::FileInfo* fileInfo, - const int index_, - const bool highlighted_) - { - thread.removeTimeSliceClient (this); - - if (highlighted_ != highlighted - || index_ != index) - { - index = index_; - highlighted = highlighted_; - repaint(); - } - - File newFile; - String newFileSize; - String newModTime; - - if (fileInfo != 0) - { - newFile = root.getChildFile (fileInfo->filename); - newFileSize = File::descriptionOfSizeInBytes (fileInfo->fileSize); - newModTime = fileInfo->modificationTime.formatted (T("%d %b '%y %H:%M")); - } - - if (newFile != file - || fileSize != newFileSize - || modTime != newModTime) - { - file = newFile; - fileSize = newFileSize; - modTime = newModTime; - - isDirectory = fileInfo != 0 && fileInfo->isDirectory; - repaint(); - - clearIcon(); - } - - if (file != File::nonexistent - && icon == 0 && ! isDirectory) - { - updateIcon (true); - - if (icon == 0) - thread.addTimeSliceClient (this); - } - } - - bool useTimeSlice() - { - updateIcon (false); - return false; - } - - void handleAsyncUpdate() - { - repaint(); - } - -private: - FileListComponent& owner; - TimeSliceThread& thread; - bool highlighted; - int index; - File file; - String fileSize; - String modTime; - Image* icon; - bool isDirectory; - Image* defaultFileIcon; - Image* defaultFolderIcon; - - void JUCE_CALLTYPE clearIcon() throw() - { - ImageCache::release (icon); - icon = 0; - } - - void JUCE_CALLTYPE updateIcon (const bool onlyUpdateIfCached) - { - if (icon == 0) - { - const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode(); - Image* im = ImageCache::getFromHashCode (hashCode); - - if (im == 0 && ! onlyUpdateIfCached) - { - im = juce_createIconForFile (file); - - if (im != 0) - ImageCache::addImageToCache (im, hashCode); - } - - if (im != 0) - { - icon = im; - triggerAsyncUpdate(); - } - } - } -}; - -int FileListComponent::getNumRows() -{ - return fileList.getNumFiles(); -} - -void FileListComponent::paintListBoxItem (int, Graphics&, int, int, bool) -{ -} - -Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, Component* existingComponentToUpdate) -{ - FileListItemComponent* comp = dynamic_cast (existingComponentToUpdate); - - if (comp == 0) - { - delete existingComponentToUpdate; - existingComponentToUpdate = comp = new FileListItemComponent (*this, fileList.getTimeSliceThread()); - } - - DirectoryContentsList::FileInfo fileInfo; - - if (fileList.getFileInfo (row, fileInfo)) - comp->update (fileList.getDirectory(), &fileInfo, row, isSelected); - else - comp->update (fileList.getDirectory(), 0, row, isSelected); - - return comp; -} - -void FileListComponent::selectedRowsChanged (int /*lastRowSelected*/) -{ - sendSelectionChangeMessage(); -} - -void FileListComponent::deleteKeyPressed (int /*currentSelectedRow*/) -{ -} - -void FileListComponent::returnKeyPressed (int currentSelectedRow) -{ - sendDoubleClickMessage (fileList.getFile (currentSelectedRow)); -} - -//============================================================================== -class FileListTreeItem : public TreeViewItem, - public TimeSliceClient, - public AsyncUpdater, - public ChangeListener -{ -public: - JUCE_CALLTYPE FileListTreeItem (FileTreeComponent& owner_, - DirectoryContentsList* const parentContentsList_, - const int indexInContentsList_, - const File& file_, - TimeSliceThread& thread_) throw() - : owner (owner_), - parentContentsList (parentContentsList_), - indexInContentsList (indexInContentsList_), - subContentsList (0), - canDeleteSubContentsList (false), - file (file_), - thread (thread_), - icon (0), - defaultFileIcon (0), - defaultFolderIcon (0) - { - DirectoryContentsList::FileInfo fileInfo; - - if (parentContentsList_ != 0 - && parentContentsList_->getFileInfo (indexInContentsList_, fileInfo)) - { - fileSize = File::descriptionOfSizeInBytes (fileInfo.fileSize); - modTime = fileInfo.modificationTime.formatted (T("%d %b '%y %H:%M")); - isDirectory = fileInfo.isDirectory; - } - else - { - isDirectory = true; - } - - if (file != File::nonexistent && ! isDirectory) - { - updateIcon (true); - - if (icon == 0) - thread.addTimeSliceClient (this); - } - } - - JUCE_CALLTYPE ~FileListTreeItem() throw() - { - thread.removeTimeSliceClient (this); - - clearIcon(); - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - delete subContentsList; - } - - bool mightContainSubItems() { return isDirectory; } - const String getUniqueName() const { return file.getFullPathName(); } - - void itemOpennessChanged (bool isNowOpen) - { - if (isNowOpen) - { - clearSubItems(); - - isDirectory = file.isDirectory(); - - if (isDirectory) - { - if (subContentsList == 0) - { - jassert (parentContentsList != 0); - - DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); - l->setDirectory (file, true, true); - - setSubContentsList (l); - canDeleteSubContentsList = true; - } - - changeListenerCallback (0); - } - } - } - - void JUCE_CALLTYPE setSubContentsList (DirectoryContentsList* newList) throw() - { - jassert (subContentsList == 0); - subContentsList = newList; - newList->addChangeListener (this); - } - - void changeListenerCallback (void*) - { - clearSubItems(); - - if (isOpen() && subContentsList != 0) - { - for (int i = 0; i < subContentsList->getNumFiles(); ++i) - { - FileListTreeItem* const item - = new FileListTreeItem (owner, subContentsList, i, subContentsList->getFile(i), thread); - - addSubItem (item); - } - } - } - - void paintItem (Graphics& g, int width, int height) - { - if (isSelected()) - g.fillAll (owner.findColour (FileTreeComponent::highlightColourId)); - - g.setColour (owner.findColour (FileTreeComponent::textColourId)); - g.setFont (height * 0.7f); - - const int x = 32; - - Image* im = icon; - - if (im == 0) - { - if (defaultFileIcon == 0) - reloadIcons(); - - im = isDirectory ? defaultFolderIcon : defaultFileIcon; - } - - if (im != 0) - { - g.drawImageWithin (im, 2, 2, x - 4, height - 4, - RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, - false); - } - - if (width > 450 && ! isDirectory) - { - const int sizeX = roundFloatToInt (width * 0.7f); - const int dateX = roundFloatToInt (width * 0.8f); - - g.drawFittedText (file.getFileName(), - x, 0, sizeX - x, height, - Justification::centredLeft, 1); - - g.setFont (height * 0.5f); - g.setColour (Colours::darkgrey); - - if (! isDirectory) - { - g.drawFittedText (fileSize, - sizeX, 0, dateX - sizeX - 8, height, - Justification::centredRight, 1); - - g.drawFittedText (modTime, - dateX, 0, width - 8 - dateX, height, - Justification::centredRight, 1); - } - } - else - { - g.drawFittedText (file.getFileName(), - x, 0, width - x, height, - Justification::centredLeft, 1); - - } - } - - void itemClicked (const MouseEvent& e) - { - owner.sendMouseClickMessage (file, e); - } - - void itemDoubleClicked (const MouseEvent&) - { - owner.sendDoubleClickMessage (file); - } - - void itemSelectionChanged (bool) - { - owner.sendSelectionChangeMessage(); - } - - bool useTimeSlice() - { - updateIcon (false); - thread.removeTimeSliceClient (this); - return false; - } - - void handleAsyncUpdate() - { - owner.repaint(); - } - - const File& getFile() const throw() { return file; } - -private: - FileTreeComponent& owner; - DirectoryContentsList* parentContentsList; - int indexInContentsList; - DirectoryContentsList* subContentsList; - bool isDirectory, canDeleteSubContentsList; - TimeSliceThread& thread; - const File file; - String fileSize; - String modTime; - Image* icon; - Image* defaultFileIcon; - Image* defaultFolderIcon; - - void clearIcon() throw() - { - ImageCache::release (icon); - icon = 0; - } - - void reloadIcons() throw() - { - ImageCache::release (defaultFileIcon); - ImageCache::release (defaultFolderIcon); - - defaultFileIcon = owner.getLookAndFeel().getDefaultDocumentFileImage(); - defaultFolderIcon = owner.getLookAndFeel().getDefaultFolderImage(); - } - - void updateIcon (const bool onlyUpdateIfCached) - { - if (icon == 0) - { - const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode(); - Image* im = ImageCache::getFromHashCode (hashCode); - - if (im == 0 && ! onlyUpdateIfCached) - { - im = juce_createIconForFile (file); - - if (im != 0) - ImageCache::addImageToCache (im, hashCode); - } - - if (im != 0) - { - icon = im; - triggerAsyncUpdate(); - } - } - } -}; - -//============================================================================== -FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow) - : FileListComponentBase (listToShow) -{ - FileListTreeItem* const root - = new FileListTreeItem (*this, 0, 0, File::nonexistent, listToShow.getTimeSliceThread()); - - root->setSubContentsList (&listToShow); - setRootItemVisible (false); - setRootItem (root); -} - -FileTreeComponent::~FileTreeComponent() -{ - setRootItem (0); -} - -//============================================================================== -const File FileTreeComponent::getSelectedFile() const -{ - FileListTreeItem* item = dynamic_cast (getSelectedItem (0)); - - if (item != 0) - return item->getFile(); - - return File::nonexistent; -} - -void FileTreeComponent::scrollToTop() -{ - getViewport()->getVerticalScrollBar()->setCurrentRangeStart (0); -} - -END_JUCE_NAMESPACE diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.h b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.h deleted file mode 100644 index 5acc8f8ff6..0000000000 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponentBase.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-7 by Raw Material Software ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the - GNU General Public License, as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any later version. - - JUCE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with JUCE; if not, visit www.gnu.org/licenses or write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - ------------------------------------------------------------------------------ - - If you'd like to release a closed-source product which uses JUCE, commercial - licenses are also available: visit www.rawmaterialsoftware.com/juce for - more information. - - ============================================================================== -*/ - -#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__x -#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__x - -#include "juce_DirectoryContentsList.h" -#include "juce_FileBrowserListener.h" - - -//============================================================================== -/** - A base class for components that display a list of the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API FileListComponentBase -{ -public: - //============================================================================== - /** - */ - FileListComponentBase (DirectoryContentsList& listToShow); - - /** Destructor. */ - virtual ~FileListComponentBase(); - - //============================================================================== - /** Returns the file that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - virtual const File getSelectedFile() const = 0; - - virtual void scrollToTop() = 0; - - //============================================================================== - /** Adds a listener to be told when files are selected or clicked. - - @see removeListener - */ - void addListener (FileBrowserListener* const listener) throw(); - - /** Removes a listener. - - @see addListener - */ - void removeListener (FileBrowserListener* const listener) throw(); - - - //============================================================================== - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - Note that you can also use the constants from TextEditor::ColourIds to change the - colour of the text editor that is opened when a label is editable. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */ - textColourId = 0x1000541, /**< The colour for the text. */ - }; - - //============================================================================== - /** @internal */ - void sendSelectionChangeMessage(); - /** @internal */ - void sendDoubleClickMessage (const File& file); - /** @internal */ - void sendMouseClickMessage (const File& file, const MouseEvent& e); - - //============================================================================== - juce_UseDebuggingNewOperator - -protected: - DirectoryContentsList& fileList; - SortedSet listeners; - - FileListComponentBase (const FileListComponentBase&); - const FileListComponentBase& operator= (const FileListComponentBase&); -}; - - -//============================================================================== -/** - A listbox showing the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API FileListComponent : public FileListComponentBase, - public ListBox, - private ListBoxModel, - private ChangeListener -{ -public: - //============================================================================== - /** Creates a listbox to show the contents of a specified directory. - */ - FileListComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileListComponent(); - - //============================================================================== - /** Returns the file that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile() const; - - void scrollToTop(); - - //============================================================================== - /** @internal */ - void changeListenerCallback (void*); - /** @internal */ - int getNumRows(); - /** @internal */ - void paintListBoxItem (int, Graphics&, int, int, bool); - /** @internal */ - Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); - /** @internal */ - void selectedRowsChanged (int lastRowSelected); - /** @internal */ - void deleteKeyPressed (int currentSelectedRow); - /** @internal */ - void returnKeyPressed (int currentSelectedRow); - - //============================================================================== - juce_UseDebuggingNewOperator - -private: - FileListComponent (const FileListComponent&); - const FileListComponent& operator= (const FileListComponent&); -}; - - - - -//============================================================================== -/** - A listbox showing the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API FileTreeComponent : public FileListComponentBase, - public TreeView -{ -public: - //============================================================================== - /** Creates a listbox to show the contents of a specified directory. - */ - FileTreeComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileTreeComponent(); - - //============================================================================== - /** Returns the file that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile() const; - - void scrollToTop(); - - //============================================================================== - juce_UseDebuggingNewOperator - -private: - FileTreeComponent (const FileTreeComponent&); - const FileTreeComponent& operator= (const FileTreeComponent&); -}; - - -#endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__ diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp new file mode 100644 index 0000000000..82368ad314 --- /dev/null +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp @@ -0,0 +1,270 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../../../juce_core/basics/juce_StandardHeader.h" + +BEGIN_JUCE_NAMESPACE + +#include "juce_FileTreeComponent.h" +#include "../lookandfeel/juce_LookAndFeel.h" +#include "../../graphics/imaging/juce_ImageCache.h" +#include "../../../events/juce_AsyncUpdater.h" + +Image* juce_createIconForFile (const File& file); + + +//============================================================================== +class FileListTreeItem : public TreeViewItem, + public TimeSliceClient, + public AsyncUpdater, + public ChangeListener +{ +public: + //============================================================================== + JUCE_CALLTYPE FileListTreeItem (FileTreeComponent& owner_, + DirectoryContentsList* const parentContentsList_, + const int indexInContentsList_, + const File& file_, + TimeSliceThread& thread_) throw() + : file (file_), + owner (owner_), + parentContentsList (parentContentsList_), + indexInContentsList (indexInContentsList_), + subContentsList (0), + canDeleteSubContentsList (false), + thread (thread_), + icon (0) + { + DirectoryContentsList::FileInfo fileInfo; + + if (parentContentsList_ != 0 + && parentContentsList_->getFileInfo (indexInContentsList_, fileInfo)) + { + fileSize = File::descriptionOfSizeInBytes (fileInfo.fileSize); + modTime = fileInfo.modificationTime.formatted (T("%d %b '%y %H:%M")); + isDirectory = fileInfo.isDirectory; + } + else + { + isDirectory = true; + } + } + + ~FileListTreeItem() throw() + { + thread.removeTimeSliceClient (this); + + clearSubItems(); + ImageCache::release (icon); + + if (canDeleteSubContentsList) + delete subContentsList; + } + + //============================================================================== + bool mightContainSubItems() { return isDirectory; } + const String getUniqueName() const { return file.getFullPathName(); } + int getItemHeight() { return 22; } + + void itemOpennessChanged (bool isNowOpen) + { + if (isNowOpen) + { + clearSubItems(); + + isDirectory = file.isDirectory(); + + if (isDirectory) + { + if (subContentsList == 0) + { + jassert (parentContentsList != 0); + + DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); + l->setDirectory (file, true, true); + + setSubContentsList (l); + canDeleteSubContentsList = true; + } + + changeListenerCallback (0); + } + } + } + + void JUCE_CALLTYPE setSubContentsList (DirectoryContentsList* newList) throw() + { + jassert (subContentsList == 0); + subContentsList = newList; + newList->addChangeListener (this); + } + + void changeListenerCallback (void*) + { + clearSubItems(); + + if (isOpen() && subContentsList != 0) + { + for (int i = 0; i < subContentsList->getNumFiles(); ++i) + { + FileListTreeItem* const item + = new FileListTreeItem (owner, subContentsList, i, subContentsList->getFile(i), thread); + + addSubItem (item); + } + } + } + + void paintItem (Graphics& g, int width, int height) + { + if (file != File::nonexistent && ! isDirectory) + { + updateIcon (true); + + if (icon == 0) + thread.addTimeSliceClient (this); + } + + owner.getLookAndFeel() + .drawFileBrowserRow (g, width, height, + file.getFileName(), + icon, + fileSize, modTime, + isDirectory, isSelected()); + } + + void itemClicked (const MouseEvent& e) + { + owner.sendMouseClickMessage (file, e); + } + + void itemDoubleClicked (const MouseEvent& e) + { + TreeViewItem::itemDoubleClicked (e); + + owner.sendDoubleClickMessage (file); + } + + void itemSelectionChanged (bool) + { + owner.sendSelectionChangeMessage(); + } + + bool useTimeSlice() + { + updateIcon (false); + thread.removeTimeSliceClient (this); + return false; + } + + void handleAsyncUpdate() + { + owner.repaint(); + } + + const File file; + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + FileTreeComponent& owner; + DirectoryContentsList* parentContentsList; + int indexInContentsList; + DirectoryContentsList* subContentsList; + bool isDirectory, canDeleteSubContentsList; + TimeSliceThread& thread; + Image* icon; + String fileSize; + String modTime; + + void JUCE_CALLTYPE updateIcon (const bool onlyUpdateIfCached) throw() + { + if (icon == 0) + { + const int hashCode = (file.getFullPathName() + T("_iconCacheSalt")).hashCode(); + Image* im = ImageCache::getFromHashCode (hashCode); + + if (im == 0 && ! onlyUpdateIfCached) + { + im = juce_createIconForFile (file); + + if (im != 0) + ImageCache::addImageToCache (im, hashCode); + } + + if (im != 0) + { + icon = im; + triggerAsyncUpdate(); + } + } + } +}; + +//============================================================================== +FileTreeComponent::FileTreeComponent (DirectoryContentsList& listToShow) + : DirectoryContentsDisplayComponent (listToShow) +{ + FileListTreeItem* const root + = new FileListTreeItem (*this, 0, 0, listToShow.getDirectory(), + listToShow.getTimeSliceThread()); + + root->setSubContentsList (&listToShow); + setRootItemVisible (false); + setRootItem (root); +} + +FileTreeComponent::~FileTreeComponent() +{ + TreeViewItem* const root = getRootItem(); + setRootItem (0); + delete root; +} + +//============================================================================== +const File FileTreeComponent::getSelectedFile() const +{ + const FileListTreeItem* const item = dynamic_cast (getSelectedItem (0)); + + if (item != 0) + return item->file; + + return File::nonexistent; +} + +void FileTreeComponent::scrollToTop() +{ + getViewport()->getVerticalScrollBar()->setCurrentRangeStart (0); +} + + +END_JUCE_NAMESPACE diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h new file mode 100644 index 0000000000..f87049b2b2 --- /dev/null +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h @@ -0,0 +1,82 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ +#define __JUCE_FILETREECOMPONENT_JUCEHEADER__ + +#include "juce_DirectoryContentsDisplayComponent.h" +#include "../controls/juce_TreeView.h" + + +//============================================================================== +/** + A component that displays the files in a directory as a treeview. + + This implements the DirectoryContentsDisplayComponent base class so that + it can be used in a FileBrowserComponent. + + To attach a listener to it, use its DirectoryContentsDisplayComponent base + class and the FileBrowserListener class. + + @see DirectoryContentsList, FileListComponent +*/ +class JUCE_API FileTreeComponent : public DirectoryContentsDisplayComponent, + public TreeView +{ +public: + //============================================================================== + /** Creates a listbox to show the contents of a specified directory. + */ + FileTreeComponent (DirectoryContentsList& listToShow); + + /** Destructor. */ + ~FileTreeComponent(); + + //============================================================================== + /** Returns the file that the user has currently selected. + + Returns File::nonexistent if none is selected. + */ + const File getSelectedFile() const; + + /** Scrolls the list to the top. */ + void scrollToTop(); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + FileTreeComponent (const FileTreeComponent&); + const FileTreeComponent& operator= (const FileTreeComponent&); +}; + + +#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__ diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp index d07f547068..b8474683f5 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp @@ -55,7 +55,7 @@ BEGIN_JUCE_NAMESPACE #include "../controls/juce_ProgressBar.h" #include "../controls/juce_TreeView.h" #include "../filebrowser/juce_FilenameComponent.h" -#include "../filebrowser/juce_FileListComponent.h" +#include "../filebrowser/juce_DirectoryContentsDisplayComponent.h" #include "../layout/juce_GroupComponent.h" #include "../properties/juce_PropertyComponent.h" #include "../juce_Desktop.h" @@ -151,8 +151,8 @@ LookAndFeel::LookAndFeel() setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.4f)); setColour (GroupComponent::textColourId, Colours::black); - setColour (FileListComponent::highlightColourId, findColour (TextEditor::highlightColourId)); - setColour (FileListComponent::textColourId, Colours::black); + setColour (DirectoryContentsDisplayComponent::highlightColourId, findColour (TextEditor::highlightColourId)); + setColour (DirectoryContentsDisplayComponent::textColourId, Colours::black); setColour (0x1000440, /*LassoComponent::lassoFillColourId*/ Colour (0x66dddddd)); setColour (0x1000441, /*LassoComponent::lassoOutlineColourId*/ Colour (0x99111111)); @@ -1993,6 +1993,71 @@ void LookAndFeel::createFileChooserHeaderText (const String& title, Justification::centred); } +void LookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height, + const String& filename, Image* icon, + const String& fileSizeDescription, + const String& fileTimeDescription, + const bool isDirectory, + const bool isItemSelected) +{ + if (isItemSelected) + g.fillAll (findColour (DirectoryContentsDisplayComponent::highlightColourId)); + + g.setColour (findColour (DirectoryContentsDisplayComponent::textColourId)); + g.setFont (height * 0.7f); + + Image* im = icon; + Image* toRelease = 0; + + if (im == 0) + { + toRelease = im = (isDirectory ? getDefaultFolderImage() + : getDefaultDocumentFileImage()); + } + + const int x = 32; + + if (im != 0) + { + g.drawImageWithin (im, 2, 2, x - 4, height - 4, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, + false); + + ImageCache::release (toRelease); + } + + if (width > 450 && ! isDirectory) + { + const int sizeX = roundFloatToInt (width * 0.7f); + const int dateX = roundFloatToInt (width * 0.8f); + + g.drawFittedText (filename, + x, 0, sizeX - x, height, + Justification::centredLeft, 1); + + g.setFont (height * 0.5f); + g.setColour (Colours::darkgrey); + + if (! isDirectory) + { + g.drawFittedText (fileSizeDescription, + sizeX, 0, dateX - sizeX - 8, height, + Justification::centredRight, 1); + + g.drawFittedText (fileTimeDescription, + dateX, 0, width - 8 - dateX, height, + Justification::centredRight, 1); + } + } + else + { + g.drawFittedText (filename, + x, 0, width - x, height, + Justification::centredLeft, 1); + + } +} + Image* LookAndFeel::getDefaultFolderImage() { const unsigned char foldericon_png[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,28,8,6,0,0,0,0,194,189,34,0,0,0,9,112,72,89, @@ -2101,5 +2166,4 @@ Image* LookAndFeel::getDefaultDocumentFileImage() } - END_JUCE_NAMESPACE diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h index f2f6d0b2de..8f529a1802 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h @@ -249,6 +249,13 @@ public: GlyphArrangement& destArrangement, int width); + virtual void drawFileBrowserRow (Graphics& g, int width, int height, + const String& filename, Image* icon, + const String& fileSizeDescription, + const String& fileTimeDescription, + const bool isDirectory, + const bool isItemSelected); + //============================================================================== virtual void drawBubble (Graphics& g, float tipX, float tipY, diff --git a/src/juce_appframework/gui/components/special/juce_MidiKeyboardComponent.h b/src/juce_appframework/gui/components/special/juce_MidiKeyboardComponent.h index d09137b3f4..0091bfa4a1 100644 --- a/src/juce_appframework/gui/components/special/juce_MidiKeyboardComponent.h +++ b/src/juce_appframework/gui/components/special/juce_MidiKeyboardComponent.h @@ -379,7 +379,7 @@ protected: always works in terms of a horizontal keyboard) @param w the width of the key */ - virtual void getKeyPosition (int midiNoteNumber, float keyWidth, + virtual void getKeyPosition (int midiNoteNumber, float keyWidth, int& x, int& w) const; private: diff --git a/src/juce_appframework/gui/graphics/contexts/juce_Graphics.h b/src/juce_appframework/gui/graphics/contexts/juce_Graphics.h index 56face63bd..74a5fb98dc 100644 --- a/src/juce_appframework/gui/graphics/contexts/juce_Graphics.h +++ b/src/juce_appframework/gui/graphics/contexts/juce_Graphics.h @@ -325,7 +325,7 @@ public: const Colour& topLeftColour = Colours::white, const Colour& bottomRightColour = Colours::black, const bool useGradient = true) const throw(); - + /** Draws a pixel using the current colour or brush. */ void JUCE_CALLTYPE setPixel (int x, int y) const throw(); diff --git a/src/juce_appframework/gui/graphics/fonts/juce_GlyphArrangement.cpp b/src/juce_appframework/gui/graphics/fonts/juce_GlyphArrangement.cpp index 9ae2aca5ec..5eeaf0fbcb 100644 --- a/src/juce_appframework/gui/graphics/fonts/juce_GlyphArrangement.cpp +++ b/src/juce_appframework/gui/graphics/fonts/juce_GlyphArrangement.cpp @@ -1050,8 +1050,8 @@ void GlyphArrangement::justifyGlyphs (const int startIndex, if (numGlyphs > 0 && num > 0) { float left, top, right, bottom; - getBoundingBox (startIndex, num, left, top, right, bottom, - ! justification.testFlags (Justification::horizontallyJustified + getBoundingBox (startIndex, num, left, top, right, bottom, + ! justification.testFlags (Justification::horizontallyJustified | Justification::horizontallyCentred)); float deltaX = 0.0f; diff --git a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/png.h b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/png.h index 6b0796512a..2acad5f04a 100644 --- a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/png.h +++ b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/png.h @@ -1993,21 +1993,29 @@ extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, #endif /* USE_FAR_KEYWORD */ /* Fatal error in PNG image of libpng - can't continue */ -extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, +extern PNG_EXPORT(void,png_error_nostring) PNGARG((png_structp png_ptr, png_const_charp error_message)); +#define png_error(a, b) png_error_nostring (a, 0) + /* The same, but the chunk name is prepended to the error string. */ -extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, +extern PNG_EXPORT(void,png_chunk_error_nostring) PNGARG((png_structp png_ptr, png_const_charp error_message)); +#define png_chunk_error(a, b) png_chunk_error_nostring (a, 0) + /* Non-fatal error in libpng. Can continue, but may have a problem. */ -extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, +extern PNG_EXPORT(void,png_warning_nostring) PNGARG((png_structp png_ptr, png_const_charp warning_message)); +#define png_warning(a, b) png_warning_nostring (a, 0) + /* Non-fatal error in libpng, chunk name is prepended to message. */ -extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, +extern PNG_EXPORT(void,png_chunk_warning_nostring) PNGARG((png_structp png_ptr, png_const_charp warning_message)); +#define png_chunk_warning(a, b) png_chunk_warning_nostring (a, 0) + /* The png_set_ functions are for storing values in the png_info_struct. * Similarly, the png_get_ calls are used to read values from the * png_info_struct, either storing the parameters in the passed variables, or diff --git a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngconf.h b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngconf.h index 214ff0a154..0eccf389ad 100644 --- a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngconf.h +++ b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngconf.h @@ -21,7 +21,15 @@ #pragma warning (disable: 4996 4267) #endif -#define PNG_iTXt_SUPPORTED 1 // (this define is added for the Juce build) +#define PNG_NO_CONSOLE_IO 1 // (these defines added for the Juce build, to keep the size down) +//#define PNG_iTXt_SUPPORTED 1 +#define PNG_NO_READ_iTXt 1 +#define PNG_NO_WRITE_iTXt 1 +#define PNG_NO_ERROR_NUMBERS 1 +#define PNG_NO_STDIO 1 +#define PNG_NO_READ_zTXt 1 +#define PNG_NO_WRITE_zTXt 1 +#define PNG_NO_READ_iCCP 1 #define PNG_1_2_X diff --git a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngerror.c b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngerror.c index 6a8f2fe4e5..641b614879 100644 --- a/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngerror.c +++ b/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngerror.c @@ -29,7 +29,7 @@ png_default_warning PNGARG((png_structp png_ptr, * to replace the error function at run-time. */ void PNGAPI -png_error(png_structp png_ptr, png_const_charp error_message) +png_error_nostring(png_structp png_ptr, png_const_charp error_message) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED char msg[16]; @@ -77,7 +77,7 @@ png_error(png_structp png_ptr, png_const_charp error_message) * png_set_error_fn() to replace the warning function at run-time. */ void PNGAPI -png_warning(png_structp png_ptr, png_const_charp warning_message) +png_warning_nostring(png_structp png_ptr, png_const_charp warning_message) { int offset = 0; #ifdef PNG_ERROR_NUMBERS_SUPPORTED @@ -143,7 +143,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp } void PNGAPI -png_chunk_error(png_structp png_ptr, png_const_charp error_message) +png_chunk_error_nostring(png_structp png_ptr, png_const_charp error_message) { char msg[18+64]; png_format_buffer(png_ptr, msg, error_message); @@ -151,7 +151,7 @@ png_chunk_error(png_structp png_ptr, png_const_charp error_message) } void PNGAPI -png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) +png_chunk_warning_nostring(png_structp png_ptr, png_const_charp warning_message) { char msg[18+64]; png_format_buffer(png_ptr, msg, warning_message); diff --git a/src/juce_core/basics/juce_Memory.h b/src/juce_core/basics/juce_Memory.h index b13583569a..d0e1088a48 100644 --- a/src/juce_core/basics/juce_Memory.h +++ b/src/juce_core/basics/juce_Memory.h @@ -144,7 +144,7 @@ #if JUCE_MSVC /** This is a compiler-indenpendent way of declaring a variable as being thread-local. - E.g. + E.g. @code juce_ThreadLocal int myVariable; @endcode diff --git a/src/juce_core/misc/juce_PerformanceCounter.cpp b/src/juce_core/misc/juce_PerformanceCounter.cpp index a16caf0793..07ccc0c462 100644 --- a/src/juce_core/misc/juce_PerformanceCounter.cpp +++ b/src/juce_core/misc/juce_PerformanceCounter.cpp @@ -52,7 +52,7 @@ PerformanceCounter::PerformanceCounter (const String& name_, { String s ("**** Counter for \""); s << name_ << "\" started at: " - << Time::getCurrentTime().toString (true, true) + << Time::getCurrentTime().toString (true, true) << "\r\n"; outputFile.appendText (s, false, false); diff --git a/src/juce_core/text/juce_String.cpp b/src/juce_core/text/juce_String.cpp index ff8ff2df03..79d9d08052 100644 --- a/src/juce_core/text/juce_String.cpp +++ b/src/juce_core/text/juce_String.cpp @@ -1164,8 +1164,8 @@ bool JUCE_CALLTYPE String::containsWholeWordIgnoreCase (const tchar* const wordT } //============================================================================== -static int indexOfMatch (const tchar* const wildcard, - const tchar* const test, +static int indexOfMatch (const tchar* const wildcard, + const tchar* const test, const bool ignoreCase) throw() { int start = 0; @@ -1631,7 +1631,7 @@ const String JUCE_CALLTYPE String::unquoted() const throw() const int lastCharIndex = s.length() - 1; - if (lastCharIndex >= 0 + if (lastCharIndex >= 0 && (s [lastCharIndex] == T('"') || s[lastCharIndex] == T('\''))) s [lastCharIndex] = 0; diff --git a/src/juce_core/text/juce_StringArray.cpp b/src/juce_core/text/juce_StringArray.cpp index 52119187d9..dffab0fdff 100644 --- a/src/juce_core/text/juce_StringArray.cpp +++ b/src/juce_core/text/juce_StringArray.cpp @@ -314,12 +314,12 @@ void StringArray::sort (const bool ignoreCase) throw() { if (ignoreCase) { - const InsensitiveInternalStringArrayComparator comp; + InsensitiveInternalStringArrayComparator comp; strings.sort (comp); } else { - const InternalStringArrayComparator comp; + InternalStringArrayComparator comp; strings.sort (comp); } } diff --git a/src/juce_core/text/juce_XmlElement.cpp b/src/juce_core/text/juce_XmlElement.cpp index 5da8a5faf8..177e2ea778 100644 --- a/src/juce_core/text/juce_XmlElement.cpp +++ b/src/juce_core/text/juce_XmlElement.cpp @@ -1096,6 +1096,10 @@ static const tchar* const juce_xmltextContentAttributeName = T("text"); const String XmlElement::getText() const throw() { + jassert (isTextElement()); // you're trying to get the text from an element that + // isn't actually a text element.. If this contains text sub-nodes, you + // can use getAllSubText instead to + return getStringAttribute (juce_xmltextContentAttributeName); } diff --git a/src/juce_core/text/juce_XmlElement.h b/src/juce_core/text/juce_XmlElement.h index fdf926cda5..6eaaf554fe 100644 --- a/src/juce_core/text/juce_XmlElement.h +++ b/src/juce_core/text/juce_XmlElement.h @@ -589,7 +589,16 @@ public: /** Returns the text for a text element. - @see isTextElement + Note that if you have an element like this: + + @codehello@endcode + + then calling getText on the "xyz" element won't return "hello", because that is + actually stored in a special text sub-element inside the xyz element. To get the + "hello" string, you could either call getText on the (unnamed) sub-element, or + use getAllSubText() to do this automatically. + + @see isTextElement, getAllSubText, getChildElementAllSubText */ const String getText() const throw(); @@ -605,15 +614,20 @@ public: This iterates all the child elements and when it finds text elements, it concatenates their text into a big string which it returns. - @see isTextElement, getText, addTextElement + E.g. @code hello there @endcode + if you called getAllSubText on the "xyz" element, it'd return "hello there". + + @see isTextElement, getChildElementAllSubText, getText, addTextElement */ const String getAllSubText() const throw(); /** Returns all the sub-text of a named child element. If there is a child element with the given tag name, this will return - all of its sub-text (using the getAllSubText() method). If there is + all of its sub-text (by calling getAllSubText() on it). If there is no such child element, this will return the default string passed-in. + + @see getAllSubText */ const String getChildElementAllSubText (const tchar* const childTagName, const String& defaultReturnValue) const throw();