Drag and drop files from FileBrowserComponent


#1

Is there a easy way to drag and drop files from FileBrowserComponent. Have tried several thongs but cant get it to work.


#2

There’s nothing in there to do that kind of thing as it stands, though I guess the list it uses could be hacked around to add that functionality.


#3

Thanks, I will do new component for that.


#4

Is this wrong code if I add those in constructor of some component in order to make customized file chooser inside application? System hang up after showing initial look…

WildcardFileFilter wildcard (String(T("*.XML")), String::empty);
addAndMakeVisible(browserComponent = new FileBrowserComponent(FileBrowserComponent::loadFileMode,
                               File::getCurrentWorkingDirectory(), &wildcard, 0));
browserComponent->addListener(&fileListener);
browserComponent->setBounds (0,0, 300, 300);

#5

No, that’s not wrong in itself, but it’s clearly causing something else to go wrong! Probably the listener is crashing.


#6

Yes, System is crashed and claim wrong signaling… when next tab window try to add new component.

What is the reason ?

So, Could you recommend correct way to avoid the hazard ?
and modified sample code if you can do…

thanks.


#7

This isn’t a juce bug, it’s a stupid c++ error - you’re passing the address of a stack object to the constructor.

No more time-wasting questions like this, please seongnam. Get a debugger or spend longer checking it before you post things like this.


#8

Thanks,

I am struggling to make an environment to use debugger. I found some clue to use debugger in Cygwin, and I will not make any more stupid questions any more in future if I get success result.


#9

Sorry to disturb you again, but I don’t know real reason why I got the problem.

According to your explaination, I have not to pass the address of a stack object to the constructor. are you saying &wildcard parameter ?

which one is the stack object ? how can I figure what is the stack object ?

In your Juce library, you also used same way in bool FileChooser::showDialog(…) API like below.
I couldn’t find any different between your code and my code. even though I successfuly setup the debugger, still I can’t find the real reason…

WildcardFileFilter wildcard (filters, String::empty);

FileBrowserComponent browserComponent (isDirectory ? FileBrowserComponent::chooseDirectoryMode : (isSave ? FileBrowserComponent::saveFileMode: FileBrowserComponent::loadFileMode),startingFile, &wildcard, previewComponent);

I have tested multiple cases, and I found some interesting thing after I move the code button handler to avoid crash in the begining of application launch.

WildcardFileFilter wildcard (String(T("*.*")), String::empty);
addAndMakeVisible(browserComponent = new FileBrowserComponent(FileBrowserComponent::loadFileMode,
                               File::getCurrentWorkingDirectory(), &wildcard, 0));
browserComponent->setBounds (0,0, 300, 300);
  1. if I use debugger, the application could successfuly correct files and show up the files in the component, but If I run the application in normal mode, the application can’t correct the information, and showing up this message on screen. sometimes I got a failure.

    10 [unknown (0x688)] XNexus 2060 _cygtls::handle_exceptions: Exception: STA
    TUS_ACCESS_VIOLATION
    7112 [unknown (0x688)] XNexus 2060 open_stackdumpfile: Dumping stack trace to
    XNexus.exe.stackdump
    1461544 [unknown (0x688)] XNexus 2060 _cygtls::handle_exceptions: Exception: STA
    TUS_ACCESS_VIOLATION
    1483701 [unknown (0x688)] XNexus 2060 _cygtls::handle_exceptions: Error while du
    mping state (probably corrupted stack)

  2. It looks like timing problem inside thread to fill up directory information in the FileBrowserComponent.
    please take a look the attached call stack
    #0 FFFFC3E8 ??() (???)
    #1 10045429 DirectoryContentsList::addFile(this=0x10d791b0, filename=@0x19acc20, isDir=true, fileSize=0, modTime=@0x19acc10, creationTime=@0x19acc00, isReadOnly=0) (D:/CodeWorks/JuceLib/Core/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.cpp:231)
    #2 10045BF2 DirectoryContentsList::checkNextFile(this=0x10d791b0, hasChanged=@0x19acc5b) (D:/CodeWorks/JuceLib/Core/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.cpp:195)
    #3 10045D09 DirectoryContentsList::useTimeSlice(this=0x10d791b0) (D:/CodeWorks/JuceLib/Core/juce_appframework/gui/components/filebrowser/juce_DirectoryContentsList.cpp:161)
    #4 10153F6D TimeSliceThread::run(this=0x10d78ea4) (D:/CodeWorks/JuceLib/Core/juce_core/threads/juce_TimeSliceThread.cpp:98 )
    #5 10151FCE Thread::threadEntryPoint(thread=0x10d78ea4) (D:/CodeWorks/JuceLib/Core/juce_core/threads/juce_Thread.cpp:37)
    #6 1017DD66 threadEntryProc(value=0x10d78ea4) (D:/CodeWorks/JuceLib/Platform/Win32/juce_linux_Threads.cpp:23)
    #7 610B03B1 pthread::thread_init_wrapper() (/cygdrive/d/CodeWorks/build/Bin/cygwin1.dll:??)
    #8 61004416 _cygtls::call2() (/cygdrive/d/CodeWorks/build/Bin/cygwin1.dll:??)
    #9 10D7FCB8 ??() (???)
    #10 019ACDF0 ??() (???)
    #11 610B0350 verifyable_object::~verifyable_object() (/cygdrive/d/CodeWorks/build/Bin/cygwin1.dll:??)
    #12 30EC8353 ??() (???)

  3. If that is the really passing stack object problem, I have to get same problem when I use list box which inherited from listBox & ListBoxModel because FileBrowserComponent also was inherited from the components.


#10

Your wildcard is being allocated on the stack, so when the method is done executing, the variable goes out of scope. But you passed in the address of that stack variable to the browserComponent. So the browserComponent still thinks there’s a WildcardFileFilter at that memory location. The browserComponent tries to access the (now invalid) memory location, and then bad stuff happens.

The reason it works in the JUCE code is because the browserComponent is used only within the scope of the method. By the time the method is done executing, the FileBrowserComponent is also gone, so it’s okay for the wildcard to go out of scope.

Okay, so this isn’t exactly how it works, but it’s essentially the problem you’re having. This is absolutely essential C++ knowledge, and it’s really not that complicated. You really should get a good book or something to help with these problems instead of posting here, because they’re C++ issues, not JUCE-specific ones (although I’m probably guilty of posting a few of those here too :oops:).


#11

broadly speaking:

if you use ‘new’ it’s on the heap, otherwise it’s on the stack, e.g:

String* s = new String(“heap string”);

is going to be on the heap, and the pointer s will remain valid until you explicitly delete it. This means it’s safe to pass to other methods as you know exactly when it is going to be removed. Conversely, it is easy to leak, 'cos unless you ever call ‘delete s’ it’s going to hang around until your app quits.

String s(“stack string”);

is going to be on the stack, and it’ll live for only as long as it is in scope. The advantage is that you don’t need to do your own garbage collection. The disadvantage is that if you pass a pointer to this object, you better make damn sure you don’t let it go out of scope until the object/process you passed it to, is done with it.

I’m going to repeat Warmonger here though: this is basic, and very fundamental pointer stuff, and C++ development is entirely dependent on a good knowledge of this.


#12

sometimes i do not understand why people post here asking for problems related to C++ rather than juce. THIS IS A JUCE FORUM, if you look up in the title we are in “General JUCE discussion”, not in comp.lang.c++ !

(…today i woke up a bit angry…)


#13

Thanks to eveybody and Sorry to kraken.

I slightly misunderstood Jules’s comment - real meaning of this sentence - “passing the address of a stack object to the constructor”.
,but currently I am clearly understood the problem. that is “life scope” problem because of different disign concept versus my use case concept.

Basically, I thought that my approaching to pass the local variable(component) address to new component contstuctor will not make any problem, and I couldn’t imagin that the Juce library will use the address in running time.

because the initial time of the new constructor can copy the information to keep the informaton inside the component. that is the encapsulation concept, forwarded information in the begining should be stored inside the component and the component should used that in running time. not passed reference. if you keep the passed reference, and if you use same way for all component in Juce library, the reference address dependency among user application and Juce library in running time will be a kind of complex web.
on the other hand, if you copy the paramethers in the constructor and if you use internal copied component, the dependency and complexity is much lower then other case. It can impact to performance, but more componentized design concept.

Anyway, currently, your design looks is taking performace effective way, but I couldn’t imagin that I have to pass “global life scope component”. then, you may need to make a notice somewhere… for new user of Juce like me.


#14

Ok, I’ll add a note about that to the file browser docs.


#15