hide random home http://www.be.com/documentation/be_book/storage/FilePanel.html (Amiga Plus Extra No. 5/97, 05/1997)


The Storage Kit: BFilePanel

Derived from: none

Declared in: be/nustorage/FilePanel.h

Library: libtracker.so


Overview

BFilePanel knows how to create and display an "Open File" or "Save File" panel, and provides the means for filtering and responding to the user's actions on the panel. The Save Panel looks like this:

The Open Panel looks pretty much the same, but without the text view in the lower left corner.


Creating and Using a BFilePanel

To create and use a BFilePanel, follow these steps:


Constructing and Fine-tuning the Panel

The BFilePanel constructor has about two thousand arguments. They all have default values, and most of the parameters that they control can be set through individual functions. The following sections list and describe the constructor arguments and tell you if there's an analogous function.

Panel Mode

Argument Default Function
file_panel_mode mode B_OPEN_PANEL (none)

There are two file panel modes: B_OPEN_PANEL and B_SAVE_PANEL. You've got to make up your mind in the constructor.

Target

Argument Default Function
BMessenger *target be_app_messenger SetTarget()

The target represents the Looper/Handler that will receive the Open, Save, and Cancel messages.

Panel Directory

Argument Default Function
entry_ref *panel_directory cwd SetPanelDirectory()

When a panel is first displayed, it has to show the contents of some directory; this is called the "panel directory." The panel directory defaults to the current working directory.

Confirmable Node Flavors

Argument Default Function
uint32 node_flavors B_FILE_NODE (none)

This parameter applies to Open panels only.

There are three node flavors: B_FILE_NODE, B_DIRECTORY_NODE, and B_SYMLINK_NODE. You combine these constants to declare the flavors that you want the user to be able to confirm. Before describing the flavor settings, keep this in mind...

Double-clicking a directory in the file list always enters the directory, regardless of the panel's flavor setting.

Understand this and you can save yourself some reading:

If your app wants to open files only, then stick with the default (B_FILE_NODE); the user will be able to confirm files and symlinks to files. If you want directories as well (for example, a compression app might want to work on files and directories) then add in B_DIRECTORY_NODE (symlinks to directories are okay, as well) . If you only want directories (unusual, but possible), then leave B_FILE_NODE out of it.

If you're not convinced, read on:

As implied by the foregoing, when the user confirms a symlink (regardless of the flavor setting), you always receive the symlink itself in the Open message--you don't get the file or directory it points to.

Multiple Selection

Argument Default Function
bool allow_multi... true (none)

This parameter determines whether the user is allowed to select more than one item at a time. Save panels should set this to false.

Notification Message

Argument Default Function
BMessage *message a default BMessage SetMessage()

By default, the format of the message that's sent to your target when the user confirms or cancels is defined by the file panel (the default formats are defined later). You can override the default by specifying your own BMessage. The BMessage is copied by the BFilePanel object.

Ref Filter

Argument Default Function
BRefFilter *filter NULL SetRefFilter()

When panel directory changes (this includes when the panel is constructed, and when the panel's Refresh() function is called), or when a new entry is added to the existing directory, the new entries are passed, one-by-one, to the panel's BRefFilter object through a BRefFilter hook function. In your implementation of the hook function, you can reject individual entries; rejected entries won't be displayed in the file list.

By default, a file panel has no BRefFilter. To supply one, you have to subclass BRefFilter (in order to implement the hook function) and pass it in.

Note that the ref filter isn't asked to "re-review" the entry list when the file panel is Show()'d after being hidden.

Is Modal?

Argument Default Function
bool *modal false (none)

A modal file panel has no window tab, so it can't be closed; to get rid of the panel, the user has to click a button. By default, file panels are not modal.

Hide When Done

Argument Default Function
bool *hide_when_done true SetHideWhenDone()

By default, a file panel is hidden when the user confirms or Cancels. If you set hide_when_done to false, the panel remains on the screen. Clicking the panel's close box always hides the panel


The Target and the Messages it Sees

When the user confirms a selection or cancels a file panel, a BMessage is constructed and sent to the target of the BFilePanel object:

By default, the target is be_app_messenger.

You can specify a different target (as a BMessenger) through the BFilePanel constructor, or through the SetTarget() function.

The format of the BMessage that the target receives depends on whether the user is opening, saving, or canceling.

Open Notification

If the target is be_app_messenger and the what field is B_REFS_RECEIVED, the BMessage shows up in the RefsReceived() function. Otherwise it's sent to the target's MessageReceived().

Keep in mind that the refs that you receive through this message point to the literal entries that the user confirmed. In other words, if the confirmed selection is a symlink to a file, you'll receive a ref for the symlink, not the file (and similarly for a link to a directory). It's Kitup to you to turn the symlink into a file (which is probably what you want).

If you want a BEntry object, all you have to do is pass true as the traverse argument to BEntry's constructor or SetTo():

   /* We'll assume that 'ref' was just plucked from an open notification. */
   BEntry entry(ref, true);

You don't even have to check to see if the ref is a symlink.

If you want to turn a symlink ref into a ref to the pointed-to file, just add this line:

   entry.GetRef(&ref);

Save Notification

Save notifications are always sent to the target's MessageReceived() function.

Note that if the user confirms a name that collides with an existing file, an alert is automatically displayed. The user can then back out of the confirmation and return to the Save Panel, or clobber the existing file:

The save notification is sent after (and only if) the user agrees to clobber the file.

Cancel Notification

A cancel notification is sent whenever the file panel is hidden. This includes the Cancel button being clicked, the panel being closed, and the panel being hidden after an open or a save (given that the panel is in hide-when-done mode).

Cancel notifications are always sent to the target's MessageReceived() function.

Keep in mind that when a file panel is closed--regardless of how it's closed--the BFilePanel object is not destroyed. It's merely hidden.


Modifying the Look of the File Panel

There are two ways you can modify the look of your BFilePanel object.

Finding Views in the Panel

Let's look at that Save Panel again:

Here's how you find the views:

   BView *background = "/view-amigaplus_n/http://www.be.com/documentation/be_book/storage/filepanel->Window()->ChildAt(0);%3C/PRE">

These last five views can be found by name:

   BView *fileList = filepanel->Window()->FindView("PoseView");

What you do with the views is your business.


The C Functions

You can also display Open and Save Panels through the global C functions run_open_panel() and run_save_panel() (which are also declared in FilePanel.h). The functions create BFilePanel objects using the default constructor settings (modulo the file_panel_mode, of course).

The C functions create a new file panel each time they're called, and delete the panel when the user is finished with it.


Hook Functions

SelectionChanged() Invoked whenever the user changes the set of selected entries.
WasHidden() Invoked just after the file panel is hidden because of the user's actions (it's not invoked if you call Hide() yourself).


Constructor and Destructor


BFilePanel()


      BFilePanel(file_panel_mode mode = B_OPEN_PANEL,
         BMessenger* target = NULL,
         entry_ref *panel_directory = NULL,
         uint32 node_flavors = 0,
         bool allow_multiple_selection = true,
         Bmessage *message = NULL,
         BRefFilter *filter = NULL,
         bool modal = false,
         bool hide_when_done = true)

The constructor creates a new BFilePanel object and initializes it according to the arguments. The panel isn't displayed until you invoke Show(). The arguments are thoroughly described in "Constructing and Fine-tuning the Panel."

You may notice that some of the default arguments shown here don't jibe with the defaults listed in "Constructing...". In particular, the node_flavors argument was described as defaulting to B_FILE_NODE, but is shown here as 0. The "Constructing..." descriptions are correct: The default values shown here are caught and converted by the BFilePanel constructor.


~BFilePanel()


      virtual ~BFilePanel(void)

Destroys the BFilePanel. The object's target and BRefFilter are not touched by this destruction. If the object is currently displaying a file panel, the panel is closed.


Member Functions


Show(), Hide(), IsShowing(), WasHidden()


      void Show(void)
      void Hide(void)
      bool IsShowing(void)

      virtual void WasHidden(void)

These functions show and hide the file panel, and tell if you the panel is currently showing.

WasHidden() is a hook function that's invoked whenever the user's actions causes the file panel to be hidden. If you call Hide() yourself, WasHidden() is not invoked.


SelectionChanged()


      virtual void SelectionChanged(void)

This hook function is invoked whenever the user changes the set of selected files. Within your implementation of this function, you iterate over GetNextSelectedRef() to retrieve refs to the currently selected files.


PanelMode()


      file_panel_mode PanelMode(void) const

Returns the object's mode, either B_OPEN_PANEL or B_SAVE_PANEL. The mode is set in the constructor and can't be changed thereafter.


Window()


      BWindow *Window(void) const

Returns a pointer to the file panel's window. If you want to mess around with the window's views, see "Modifying the Look of the File Panel."


SetTarget(), Messenger()


      void SetTarget(BMessenger bellhop)
      BMessenger Messenger(void) const

SetTarget() sets the target of the file panel's notification messages. The target can also be set through the constructor. If you don't set a target, be_app_messenger is used. See the BInvoker class (in the Application Kit) for an explanation of how a BMessenger can be used as a target.

Messenger() returns (a copy of) the messenger that's used as the file panel's target.


SetRefFilter(), RefFilter()


      void SetRefFilter(BRefFilter* filter)
      BRefFilter *RefFilter(void) const

Whenever the file panel's panel directory is changed or refreshed (Refresh()), or when a new entry is added to the current panel directory, the "new" entries are run through the panel's "ref filter." The BRefFilter class defines a single boolean hook function called Filter(). The function receives the entries, one-by-one, and can reject specific entries (because they're the wrong file type, for example). Rejected entries are not shown in the panel's file list.

The SetRefFilter() function sets the panel's ref filter. You can also set it through the constructor. Ownership of the filter is not handed to the panel. You mustn't delete the ref filter while the panel is still extant.

RefFilter() returns a pointer to the panel's ref filter.


SetPanelDirectory(), GetPanelDirectory()


      void SetPanelDirectory(BEntry *dirEntry)
      void SetPanelDirectory(BDirectory *dirObj)
      void SetPanelDirectory(entry_ref *dirRef)

      void GetPanelDirectory(entry_ref *ref) const

The SetPanelDirectory() function sets the panel's "panel directory." This is the directory whose contents are displayed in the panel's file list. You can also set the panel directory through the constructor. If you don't supply a directory, the current working directory is used.

GetPanelDirectory() initializes ref to point to the current panel directory. The argument must be allocated.


SetButtonLabel(), SetSaveText()


      void SetButtonLabel(file_panel_button which_button, const char *label)

      void SetSaveText(const char *text)

SetButtonLabel() lets you set the label that's displayed in the panel's buttons. The button that a specific invocation affects depends on the value of which_button:

SetSaveText() sets the text that's display in the Save Panel's text view (the area in which the user types and confirms a file name).


GetNextSelectedRef(), Rewind(), Refresh()


      status_t GetNextSelectedRef(entry_ref *ref)

      void Rewind(void)

GetNextSelectedRef() initializes its arguments to point to the "next" ref in the file panel's set of currently selected items. The function returns B_ENTRY_NOT_FOUND when it reaches the end of the list. Rewind() gets you back to the top of the list.

Although you can call these functions anytime you want, they're intended to be used in implementations of the SelectionChanged() hook function.


Refresh()


      void Refresh(void)

Refresh() tells the file panel to re-read the contents of the panel directory, which causes the directory's entries to be re-run through the ref filter.

You don't have to call Refresh() in order to keep the panel in synch with the directory's contents-- the directory and file panel are kept in synch automatically.





The Be Book, in lovely HTML, for the BeOS Preview Release.

Copyright © 1997 Be, Inc. All rights reserved.

Be is a registered trademark; BeOS, BeBox, BeWare, GeekPort, the Be logo, and the BeOS logo are trademarks of Be, Inc.

Last modified July 17, 1997.