]> git.sesse.net Git - vlc/blobdiff - modules/gui/beos/InterfaceWindow.cpp
beos/*: fixed fullscreen shortcuts
[vlc] / modules / gui / beos / InterfaceWindow.cpp
index c6c8a19f23b66ce68ccce1aaf20203f1cb8aa782..60352ad479f28b1a17ec6697b83ecaea80c72498 100644 (file)
@@ -2,7 +2,7 @@
  * InterfaceWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: InterfaceWindow.cpp,v 1.25 2003/01/31 06:45:00 titer Exp $
+ * $Id: InterfaceWindow.cpp,v 1.33 2003/04/18 16:10:28 titer Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #include "InterfaceWindow.h"
 
 #define INTERFACE_UPDATE_TIMEOUT 80000 // 2 frames if at 25 fps
+#define INTERFACE_LOCKING_TIMEOUT 5000
+#define USE_VLC_CONFIG_FILE 0
+
+// make_sure_frame_is_on_screen
+bool
+make_sure_frame_is_on_screen( BRect& frame )
+{
+       BScreen screen( B_MAIN_SCREEN_ID );
+       if (frame.IsValid() && screen.IsValid()) {
+               if (!screen.Frame().Contains(frame)) {
+                       // make sure frame fits in the screen
+                       if (frame.Width() > screen.Frame().Width())
+                               frame.right -= frame.Width() - screen.Frame().Width() + 10.0;
+                       if (frame.Height() > screen.Frame().Height())
+                               frame.bottom -= frame.Height() - screen.Frame().Height() + 30.0;
+                       // frame is now at the most the size of the screen
+                       if (frame.right > screen.Frame().right)
+                               frame.OffsetBy(-(frame.right - screen.Frame().right), 0.0);
+                       if (frame.bottom > screen.Frame().bottom)
+                               frame.OffsetBy(0.0, -(frame.bottom - screen.Frame().bottom));
+                       if (frame.left < screen.Frame().left)
+                               frame.OffsetBy((screen.Frame().left - frame.left), 0.0);
+                       if (frame.top < screen.Frame().top)
+                               frame.OffsetBy(0.0, (screen.Frame().top - frame.top));
+               }
+               return true;
+       }
+       return false;
+}
+
+// make_sure_frame_is_within_limits
+void
+make_sure_frame_is_within_limits( BRect& frame, float minWidth, float minHeight,
+                                  float maxWidth, float maxHeight )
+{
+    if ( frame.Width() < minWidth )
+        frame.right = frame.left + minWidth;
+    if ( frame.Height() < minHeight )
+        frame.bottom = frame.top + minHeight;
+    if ( frame.Width() > maxWidth )
+        frame.right = frame.left + maxWidth;
+    if ( frame.Height() > maxHeight )
+        frame.bottom = frame.top + maxHeight;
+}
+
+// get_volume_info
+bool
+get_volume_info( BVolume& volume, BString& volumeName, bool& isCDROM, BString& deviceName )
+{
+       bool success = false;
+       isCDROM = false;
+       deviceName = "";
+       volumeName = "";
+       char name[B_FILE_NAME_LENGTH];
+       if ( volume.GetName( name ) >= B_OK )   // disk is currently mounted
+       {
+               volumeName = name;
+               dev_t dev = volume.Device();
+               fs_info info;
+               if ( fs_stat_dev( dev, &info ) == B_OK )
+               {
+                       success = true;
+                       deviceName = info.device_name;
+                       if ( volume.IsReadOnly() )
+                       {
+                               int i_dev = open( info.device_name, O_RDONLY );
+                               if ( i_dev >= 0 )
+                               {
+                                       device_geometry g;
+                                       if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 )
+                                               isCDROM = ( g.device_type == B_CD );
+                                       close( i_dev );
+                               }
+                       }
+               }
+       }
+       return success;
+}
+
+// collect_folder_contents
+void
+collect_folder_contents( BDirectory& dir, BList& list, bool& deep, bool& asked, BEntry& entry )
+{
+       while ( dir.GetNextEntry( &entry, true ) == B_OK )
+       {
+               if ( !entry.IsDirectory() )
+               {
+                       BPath path;
+                       // since the directory will give us the entries in reverse order,
+                       // we put them each at the same index, effectively reversing the
+                       // items while adding them
+                       if ( entry.GetPath( &path ) == B_OK )
+                       {
+                               BString* string = new BString( path.Path() );
+                               if ( !list.AddItem( string, 0 ) )
+                                       delete string;  // at least don't leak
+                       }
+               }
+               else
+               {
+                       if ( !asked )
+                       {
+                               // ask user if we should parse sub-folders as well
+                               BAlert* alert = new BAlert( "sub-folders?",
+                                                                                       "Open files from all sub-folders as well?",
+                                                                                       "No", "Yes", NULL, B_WIDTH_AS_USUAL,
+                                                                                       B_IDEA_ALERT );
+                               int32 buttonIndex = alert->Go();
+                               deep = buttonIndex == 1;
+                               asked = true;
+                               // never delete BAlerts!!
+                       }
+                       if ( deep )
+                       {
+                               BDirectory subDir( &entry );
+                               if ( subDir.InitCheck() == B_OK )
+                                       collect_folder_contents( subDir, list,
+                                                                                        deep, asked, entry );
+                       }
+               }
+       }
+}
 
 
 /*****************************************************************************
  * InterfaceWindow
  *****************************************************************************/
 
-InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
-                                  intf_thread_t  *p_interface )
+InterfaceWindow::InterfaceWindow( BRect frame, const charname,
+                                  intf_thread_tp_interface )
     : BWindow( frame, name, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
                B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS ),
       p_intf( p_interface ),
       fFilePanel( NULL ),
-      fSubtitlesPanel( NULL ),
-      fLastUpdateTime( system_time() )
+      fLastUpdateTime( system_time() ),
+         fSettings( new BMessage( 'sett' ) ),
+         p_wrapper( p_intf->p_sys->p_wrapper )
 {
-    p_intf = p_interface;
-    p_wrapper = p_intf->p_sys->p_wrapper;
+       // TODO: ?!? what about user settings?
     p_intf->p_sys->b_dvdmenus = false;
     
     fPlaylistIsEmpty = !( p_wrapper->PlaylistSize() > 0 );
     
-    BScreen *p_screen = new BScreen();
-    BRect screen_rect = p_screen->Frame();
-    delete p_screen;
+    BScreen screen;
+    BRect screen_rect = screen.Frame();
     BRect window_rect;
     window_rect.Set( ( screen_rect.right - PREFS_WINDOW_WIDTH ) / 2,
                      ( screen_rect.bottom - PREFS_WINDOW_HEIGHT ) / 2,
                      ( screen_rect.right + PREFS_WINDOW_WIDTH ) / 2,
                      ( screen_rect.bottom + PREFS_WINDOW_HEIGHT ) / 2 );
-    fPreferencesWindow = new PreferencesWindow( p_intf, window_rect, "Preferences" );
+    fPreferencesWindow = new PreferencesWindow( p_intf, window_rect, "Settings" );
     window_rect.Set( screen_rect.right - 500,
                      screen_rect.top + 50,
                      screen_rect.right - 150,
@@ -93,10 +214,6 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
                      screen_rect.top + 600 );
     fMessagesWindow = new MessagesWindow( p_intf, window_rect, "Messages" );
 
-    // set the title bar
-    SetName( "interface" );
-    SetTitle( VOUT_TITLE );
-
     // the media control view
     p_mediaControl = new MediaControlView( BRect( 0.0, 0.0, 250.0, 50.0 ),
                                            p_intf );
@@ -122,14 +239,14 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     AddChild( p_mediaControl );
 
     // Add the file Menu
-    BMenu* fileMenu = new BMenu( "File" );
+    BMenu* fileMenu = new BMenu( _("File") );
     fMenuBar->AddItem( fileMenu );
     fileMenu->AddItem( new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
                                       new BMessage( OPEN_FILE ), 'O') );
     
     fileMenu->AddItem( new CDMenu( "Open Disc" ) );
 
-    fileMenu->AddItem( new BMenuItem( "Load a subtitle file" B_UTF8_ELLIPSIS,
+    fileMenu->AddItem( new BMenuItem( "Open Subtitles" B_UTF8_ELLIPSIS,
                                       new BMessage( LOAD_SUBFILE ) ) );
     
     fileMenu->AddSeparatorItem();
@@ -143,7 +260,7 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     fSubtitlesMenu = new LanguageMenu("Subtitles", SPU_ES, p_wrapper);
 
     /* Add the Audio menu */
-    fAudioMenu = new BMenu( "Audio" );
+    fAudioMenu = new BMenu( _("Audio") );
     fMenuBar->AddItem ( fAudioMenu );
     fAudioMenu->AddItem( fLanguageMenu );
     fAudioMenu->AddItem( fSubtitlesMenu );
@@ -152,10 +269,13 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     fNextTitleMI = new BMenuItem( "Next Title", new BMessage( NEXT_TITLE ) );
     fPrevChapterMI = new BMenuItem( "Prev Chapter", new BMessage( PREV_CHAPTER ) );
     fNextChapterMI = new BMenuItem( "Next Chapter", new BMessage( NEXT_CHAPTER ) );
+    fGotoMenuMI = new BMenuItem( "Goto Menu", new BMessage( NAVIGATE_MENU ) );
 
     /* Add the Navigation menu */
-    fNavigationMenu = new BMenu( "Navigation" );
+    fNavigationMenu = new BMenu( _("Navigation") );
     fMenuBar->AddItem( fNavigationMenu );
+    fNavigationMenu->AddItem( fGotoMenuMI );
+    fNavigationMenu->AddSeparatorItem();
     fNavigationMenu->AddItem( fPrevTitleMI );
     fNavigationMenu->AddItem( fNextTitleMI );
     fNavigationMenu->AddItem( fTitleMenu = new TitleMenu( "Go to Title", p_intf ) );
@@ -165,7 +285,7 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     fNavigationMenu->AddItem( fChapterMenu = new ChapterMenu( "Go to Chapter", p_intf ) );
 
     /* Add the Speed menu */
-    fSpeedMenu = new BMenu( "Speed" );
+    fSpeedMenu = new BMenu( _("Speed") );
     fSpeedMenu->SetRadioMode( true );
     fSpeedMenu->AddItem( fSlowerMI = new BMenuItem( "Slower", new BMessage( SLOWER_PLAY ) ) );
     fNormalMI = new BMenuItem( "Normal", new BMessage( NORMAL_PLAY ) );
@@ -176,7 +296,7 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     fMenuBar->AddItem( fSpeedMenu );
 
     /* Add the Show menu */
-    fShowMenu = new BMenu( "Show" );
+    fShowMenu = new BMenu( _("Window") );
     fShowMenu->AddItem( new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
                                        new BMessage( OPEN_PLAYLIST ), 'P') );
     fShowMenu->AddItem( new BMenuItem( "Messages" B_UTF8_ELLIPSIS,
@@ -188,57 +308,9 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     /* Prepare fow showing */
     _SetMenusEnabled( false );
     p_mediaControl->SetEnabled( false );
-    
-    /* Restore interface settings */
-    int i_width = config_GetInt( p_intf, "beos-intf-width" ),
-        i_height = config_GetInt( p_intf, "beos-intf-height" ),
-        i_xpos = config_GetInt( p_intf, "beos-intf-xpos" ),
-        i_ypos = config_GetInt( p_intf, "beos-intf-ypos" );
-    if( i_width && i_height && i_xpos && i_ypos )
-    {
-        /* main window size and position */
-        ResizeTo( i_width, i_height );
-        MoveTo( i_xpos, i_ypos );
-    }
-    i_width = config_GetInt( p_intf, "beos-playlist-width" ),
-    i_height = config_GetInt( p_intf, "beos-playlist-height" ),
-    i_xpos = config_GetInt( p_intf, "beos-playlist-xpos" ),
-    i_ypos = config_GetInt( p_intf, "beos-playlist-ypos" );
-    if( i_width && i_height && i_xpos && i_ypos )
-    {
-        /* playlist window size and position */
-        fPlaylistWindow->ResizeTo( i_width, i_height );
-        fPlaylistWindow->MoveTo( i_xpos, i_ypos );
-    }
-    i_width = config_GetInt( p_intf, "beos-messages-width" ),
-    i_height = config_GetInt( p_intf, "beos-messages-height" ),
-    i_xpos = config_GetInt( p_intf, "beos-messages-xpos" ),
-    i_ypos = config_GetInt( p_intf, "beos-messages-ypos" );
-    if( i_width && i_height && i_xpos && i_ypos )
-    {
-        /* messages window size and position */
-        fMessagesWindow->ResizeTo( i_width, i_height );
-        fMessagesWindow->MoveTo( i_xpos, i_ypos );
-    }
-    if( config_GetInt( p_intf, "beos-playlist-show" ) )
-    {
-        /* playlist showing */
-        if( fPlaylistWindow->Lock() )
-        {
-            fPlaylistWindow->Show();
-            fPlaylistWindow->Unlock();
-        }
-    }
-    if( config_GetInt( p_intf, "beos-messages-show" ) )
-    {
-        /* messages showing */
-        if( fMessagesWindow->Lock() )
-        {
-            fMessagesWindow->Show();
-            fMessagesWindow->Unlock();
-        }
-    }
-    
+
+       _RestoreSettings();    
+
     Show();
 }
 
@@ -246,8 +318,15 @@ InterfaceWindow::~InterfaceWindow()
 {
     if( fPlaylistWindow )
         fPlaylistWindow->ReallyQuit();
+    fPlaylistWindow = NULL;
     if( fMessagesWindow )
         fMessagesWindow->ReallyQuit();
+    fMessagesWindow = NULL;
+    if( fPreferencesWindow )
+        fPreferencesWindow->ReallyQuit();
+    fPreferencesWindow = NULL;
+       delete fFilePanel;
+       delete fSettings;
 }
 
 /*****************************************************************************
@@ -276,8 +355,9 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
     {
         case B_ABOUT_REQUESTED:
         {
-            BAlert* alert = new BAlert( VOUT_TITLE,
-                                        "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
+            BAlert* alert = new BAlert( "VLC " PACKAGE_VERSION,
+                                        "VLC " PACKAGE_VERSION " for BeOS\n\n"
+                                        "<www.videolan.org>", "OK");
             alert->Go();
             break;
         }
@@ -285,16 +365,13 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             break;
             
         case OPEN_FILE:
-            if( fFilePanel )
-            {
-                fFilePanel->Show();
-                break;
-            }
-            fFilePanel = new BFilePanel();
-            fFilePanel->SetTarget( this );
-            fFilePanel->Show();
+               _ShowFilePanel( B_REFS_RECEIVED, "VideoLAN Client: Open Media Files" );
             break;
-    
+
+        case LOAD_SUBFILE:
+               _ShowFilePanel( SUBFILE_RECEIVED, "VideoLAN Client: Open Subtitle File" );
+            break;
+
         case OPEN_PLAYLIST:
             if (fPlaylistWindow->Lock())
             {
@@ -318,18 +395,6 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             }
             break;
         
-        case LOAD_SUBFILE:
-            if( fSubtitlesPanel )
-            {
-                fSubtitlesPanel->Show();
-                break;
-            }
-            fSubtitlesPanel = new BFilePanel();
-            fSubtitlesPanel->SetTarget( this );
-            fSubtitlesPanel->SetMessage( new BMessage( SUBFILE_RECEIVED ) );
-            fSubtitlesPanel->Show();
-            break;
-
         case SUBFILE_RECEIVED:
         {
             entry_ref ref;
@@ -337,7 +402,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             {
                 BPath path( &ref );
                 if ( path.InitCheck() == B_OK )
-                    p_wrapper->LoadSubFile( (char*)path.Path() );
+                    p_wrapper->LoadSubFile( path.Path() );
             }
             break;
         }
@@ -346,7 +411,6 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             // this currently stops playback not nicely
             if (playback_status > UNDEF_S)
             {
-                snooze( 400000 );
                 p_wrapper->PlaylistStop();
                 p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
             }
@@ -453,6 +517,9 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             p_wrapper->NextTitle();
             break;
         }
+        case NAVIGATE_MENU:
+               p_wrapper->ToggleTitle( 0 );
+               break;
         case TOGGLE_TITLE:
             if ( playback_status > UNDEF_S )
             {
@@ -493,6 +560,19 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             p_wrapper->NavigateNext();
             break;
         // drag'n'drop and system messages
+        case MSG_SOUNDPLAY:
+               // convert soundplay drag'n'drop message (containing paths)
+               // to normal message (containing refs)
+               {
+                       const char* path;
+                       for ( int32 i = 0; p_message->FindString( "path", i, &path ) == B_OK; i++ )
+                       {
+                               entry_ref ref;
+                               if ( get_ref_for_path( path, &ref ) == B_OK )
+                                       p_message->AddRef( "refs", &ref );
+                       }
+               }
+               // fall through
         case B_REFS_RECEIVED:
         case B_SIMPLE_DATA:
             {
@@ -500,86 +580,96 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
                  * file(s) opened by drag & drop -> replace playlist;
                  * file(s) opened by 'shift' + drag & drop -> append */
                 bool replace = false;
+                bool reverse = false;
                 if ( p_message->WasDropped() )
+                {
                     replace = !( modifiers() & B_SHIFT_KEY );
+                    reverse = true;
+                }
                     
                 // build list of files to be played from message contents
                 entry_ref ref;
                 BList files;
-                for ( int i = 0; p_message->FindRef( "refs", i, &ref ) == B_OK; i++ )
-                {
-                    BPath path( &ref );
-                    if ( path.InitCheck() == B_OK )
-                    {
-                        bool add = true;
-                        // has the user dropped a dvd disk icon?
-                        BDirectory dir( &ref );
-                        if ( dir.InitCheck() == B_OK && dir.IsRootDirectory() )
-                        {
-                            BVolumeRoster volRoster;
-                            BVolume vol;
-                            BDirectory volumeRoot;
-                            status_t status = volRoster.GetNextVolume( &vol );
-                            while( status == B_NO_ERROR )
-                            {
-                                if( vol.GetRootDirectory( &volumeRoot ) == B_OK
-                                    && dir == volumeRoot )
-                                {
-                                    BString volumeName;
-                                    BString deviceName;
-                                    bool isCDROM = false;
-                                    bool success = false;
-                                    deviceName = "";
-                                    volumeName = "";
-                                    char name[B_FILE_NAME_LENGTH];
-                                    if ( vol.GetName( name ) >= B_OK )    // disk is currently mounted
-                                    {
-                                        volumeName = name;
-                                        dev_t dev = vol.Device();
-                                        fs_info info;
-                                        if ( fs_stat_dev( dev, &info ) == B_OK )
-                                        {
-                                            success = true;
-                                            deviceName = info.device_name;
-                                            if ( vol.IsReadOnly() )
-                                            {
-                                                int i_dev = open( info.device_name, O_RDONLY );
-                                                if ( i_dev >= 0 )
-                                                {
-                                                    device_geometry g;
-                                                    if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 )
-                                                    isCDROM = ( g.device_type == B_CD );
-                                                    close( i_dev );
-                                                }
-                                            }
-                                        }
-                                     }
-                                    
-                                    if( success && isCDROM )
-                                    {
-                                        BMessage msg( OPEN_DVD );
-                                        msg.AddString( "device", deviceName.String() );
-                                        PostMessage( &msg );
-                                        add = false;
-                                    }
-                                     break;
-                                }
-                                else
-                                {
-                                     vol.Unset();
-                                    status = volRoster.GetNextVolume( &vol );
-                                }
-                            }
-                        }
-                        if( add )
-                        {
-                            files.AddItem( new BString( (char*)path.Path() ) );
-                        }
-                    }
-                }
-                // give the list to VLC
-                p_wrapper->OpenFiles(&files, replace);
-                _UpdatePlaylist();
+                
+                // if we should parse sub-folders as well
+                       bool askedAlready = false;
+                       bool parseSubFolders = askedAlready;
+                       // traverse refs in reverse order
+                       int32 count;
+                       type_code dummy;
+                       if ( p_message->GetInfo( "refs", &dummy, &count ) == B_OK && count > 0 )
+                       {
+                               int32 i = reverse ? count - 1 : 0;
+                               int32 increment = reverse ? -1 : 1;
+                       for ( ; p_message->FindRef( "refs", i, &ref ) == B_OK; i += increment )
+                       {
+                           BPath path( &ref );
+                           if ( path.InitCheck() == B_OK )
+                           {
+                               bool add = true;
+                               // has the user dropped a folder?
+                               BDirectory dir( &ref );
+                               if ( dir.InitCheck() == B_OK)
+                               {
+                                       // has the user dropped a dvd disk icon?
+                                                               if ( dir.IsRootDirectory() )
+                                                               {
+                                                                       BVolumeRoster volRoster;
+                                                                       BVolume vol;
+                                                                       BDirectory volumeRoot;
+                                                                       status_t status = volRoster.GetNextVolume( &vol );
+                                                                       while ( status == B_NO_ERROR )
+                                                                       {
+                                                                               if ( vol.GetRootDirectory( &volumeRoot ) == B_OK
+                                                                                        && dir == volumeRoot )
+                                                                               {
+                                                                                       BString volumeName;
+                                                                                       BString deviceName;
+                                                                                       bool isCDROM;
+                                                                                       if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
+                                                                                                && isCDROM )
+                                                                                       {
+                                                                                               BMessage msg( OPEN_DVD );
+                                                                                               msg.AddString( "device", deviceName.String() );
+                                                                                               PostMessage( &msg );
+                                                                                               add = false;
+                                                                                       }
+                                                                                       break;
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       vol.Unset();
+                                                                                       status = volRoster.GetNextVolume( &vol );
+                                                                               }
+                                                                       }
+                                                               }
+                                       if ( add )
+                                       {
+                                               add = false;
+                                               dir.Rewind();   // defensive programming
+                                               BEntry entry;
+                                                                       collect_folder_contents( dir, files,
+                                                                                                                        parseSubFolders,
+                                                                                                                        askedAlready,
+                                                                                                                        entry );
+                                       }
+                               }
+                               if ( add )
+                               {
+                                       BString* string = new BString( path.Path() );
+                                       if ( !files.AddItem( string, 0 ) )
+                                               delete string;  // at least don't leak
+                               }
+                           }
+                       }
+                       // give the list to VLC
+                       // BString objects allocated here will be deleted there
+                       int32 index;
+                       if ( p_message->FindInt32("drop index", &index) != B_OK )
+                               index = -1;
+                       p_wrapper->OpenFiles( &files, replace, index );
+                       _UpdatePlaylist();
+                       }
             }
             break;
 
@@ -608,7 +698,9 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             }
             break;
         }
-                
+        case MSG_UPDATE:
+               UpdateInterface();
+               break;
         default:
             BWindow::MessageReceived( p_message );
             break;
@@ -624,34 +716,8 @@ bool InterfaceWindow::QuitRequested()
     p_wrapper->PlaylistStop();
     p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
 
-    /* Save interface settings */
-    BRect frame = Frame();
-    config_PutInt( p_intf, "beos-intf-width", (int)frame.Width() );
-    config_PutInt( p_intf, "beos-intf-height", (int)frame.Height() );
-    config_PutInt( p_intf, "beos-intf-xpos", (int)frame.left );
-    config_PutInt( p_intf, "beos-intf-ypos", (int)frame.top );
-    if( fPlaylistWindow->Lock() )
-    {
-        frame = fPlaylistWindow->Frame();
-        config_PutInt( p_intf, "beos-playlist-width", (int)frame.Width() );
-        config_PutInt( p_intf, "beos-playlist-height", (int)frame.Height() );
-        config_PutInt( p_intf, "beos-playlist-xpos", (int)frame.left );
-        config_PutInt( p_intf, "beos-playlist-ypos", (int)frame.top );
-        config_PutInt( p_intf, "beos-playlist-show", !fPlaylistWindow->IsHidden() );
-        fPlaylistWindow->Unlock();
-    }
-    if( fMessagesWindow->Lock() )
-    {
-        frame = fMessagesWindow->Frame();
-        config_PutInt( p_intf, "beos-messages-width", (int)frame.Width() );
-        config_PutInt( p_intf, "beos-messages-height", (int)frame.Height() );
-        config_PutInt( p_intf, "beos-messages-xpos", (int)frame.left );
-        config_PutInt( p_intf, "beos-messages-ypos", (int)frame.top );
-        config_PutInt( p_intf, "beos-messages-show", !fMessagesWindow->IsHidden() );
-        fMessagesWindow->Unlock();
-    }
-    config_SaveConfigFile( p_intf, "beos" );
-    
+       _StoreSettings();
+   
     p_intf->b_die = 1;
 
     return( true );
@@ -666,9 +732,9 @@ void InterfaceWindow::UpdateInterface()
     {
         if ( acquire_sem( p_mediaControl->fScrubSem ) == B_OK )
         {
-            p_wrapper->SetTimeAsFloat(p_mediaControl->GetSeekTo());
+            p_wrapper->SetTimeAsFloat( p_mediaControl->GetSeekTo() );
         }
-        else if ( Lock() )
+        else if ( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK )
         {
             p_mediaControl->SetEnabled( true );
             bool hasTitles = p_wrapper->HasTitles();
@@ -686,7 +752,7 @@ void InterfaceWindow::UpdateInterface()
             p_wrapper->GetNavCapabilities( &canSkipPrev, &canSkipNext );
             p_mediaControl->SetSkippable( canSkipPrev, canSkipNext );
 
-            if ( p_wrapper->HasAudio() )
+            if ( p_wrapper->HasInput() )
             {
                 p_mediaControl->SetAudioEnabled( true );
                 p_mediaControl->SetMuted( p_wrapper->IsMuted() );
@@ -696,7 +762,7 @@ void InterfaceWindow::UpdateInterface()
             Unlock();
         }
         // update playlist as well
-        if ( fPlaylistWindow->Lock() )
+        if ( fPlaylistWindow->LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK )
         {
             fPlaylistWindow->UpdatePlaylist();
             fPlaylistWindow->Unlock();
@@ -704,22 +770,23 @@ void InterfaceWindow::UpdateInterface()
     }
     else
     {
-        _SetMenusEnabled( false );
-        if( !( p_wrapper->PlaylistSize() > 0 ) )
-           p_mediaControl->SetEnabled( false );
-        else
-            p_mediaControl->SetProgress( 0 );
-    }
-
-    /* always force the user-specified volume */
-    /* FIXME : I'm quite sure there is a cleaner way to do this */
-    int i_volume = p_mediaControl->GetVolume();
-    if( p_wrapper->GetVolume() != i_volume )
-    {
-        p_wrapper->SetVolume( i_volume );
+               if ( LockWithTimeout(INTERFACE_LOCKING_TIMEOUT) == B_OK )
+               {
+               _SetMenusEnabled( false );
+               if( !( p_wrapper->PlaylistSize() > 0 ) )
+                   p_mediaControl->SetEnabled( false );
+               else
+               {
+                   p_mediaControl->SetProgress( 0 );
+                   // enable/disable skip buttons
+                   bool canSkipPrev;
+                   bool canSkipNext;
+                   p_wrapper->GetNavCapabilities( &canSkipPrev, &canSkipNext );
+                   p_mediaControl->SetSkippable( canSkipPrev, canSkipNext );
+                       }
+            Unlock();
+        }
     }
-    
-    fMessagesWindow->UpdateMessages();
 
     fLastUpdateTime = system_time();
 }
@@ -758,30 +825,34 @@ InterfaceWindow::_SetMenusEnabled(bool hasFile, bool hasChapters, bool hasTitles
         hasChapters = false;
         hasTitles = false;
     }
-    if (Lock())
+    if ( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK)
     {
-        if (fNextChapterMI->IsEnabled() != hasChapters)
-            fNextChapterMI->SetEnabled(hasChapters);
-        if (fPrevChapterMI->IsEnabled() != hasChapters)
-            fPrevChapterMI->SetEnabled(hasChapters);
-        if (fChapterMenu->IsEnabled() != hasChapters)
-            fChapterMenu->SetEnabled(hasChapters);
-        if (fNextTitleMI->IsEnabled() != hasTitles)
-            fNextTitleMI->SetEnabled(hasTitles);
-        if (fPrevTitleMI->IsEnabled() != hasTitles)
-            fPrevTitleMI->SetEnabled(hasTitles);
-        if (fTitleMenu->IsEnabled() != hasTitles)
-            fTitleMenu->SetEnabled(hasTitles);
-        if (fAudioMenu->IsEnabled() != hasFile)
-            fAudioMenu->SetEnabled(hasFile);
-        if (fNavigationMenu->IsEnabled() != hasFile)
-            fNavigationMenu->SetEnabled(hasFile);
-        if (fLanguageMenu->IsEnabled() != hasFile)
-            fLanguageMenu->SetEnabled(hasFile);
-        if (fSubtitlesMenu->IsEnabled() != hasFile)
-            fSubtitlesMenu->SetEnabled(hasFile);
-        if (fSpeedMenu->IsEnabled() != hasFile)
-            fSpeedMenu->SetEnabled(hasFile);
+        if ( fNextChapterMI->IsEnabled() != hasChapters )
+             fNextChapterMI->SetEnabled( hasChapters );
+        if ( fPrevChapterMI->IsEnabled() != hasChapters )
+             fPrevChapterMI->SetEnabled( hasChapters );
+        if ( fChapterMenu->IsEnabled() != hasChapters )
+             fChapterMenu->SetEnabled( hasChapters );
+        if ( fNextTitleMI->IsEnabled() != hasTitles )
+             fNextTitleMI->SetEnabled( hasTitles );
+        if ( fPrevTitleMI->IsEnabled() != hasTitles )
+             fPrevTitleMI->SetEnabled( hasTitles );
+        if ( fTitleMenu->IsEnabled() != hasTitles )
+             fTitleMenu->SetEnabled( hasTitles );
+        if ( fAudioMenu->IsEnabled() != hasFile )
+             fAudioMenu->SetEnabled( hasFile );
+        if ( fNavigationMenu->IsEnabled() != hasFile )
+             fNavigationMenu->SetEnabled( hasFile );
+        if ( fLanguageMenu->IsEnabled() != hasFile )
+             fLanguageMenu->SetEnabled( hasFile );
+        if ( fSubtitlesMenu->IsEnabled() != hasFile )
+             fSubtitlesMenu->SetEnabled( hasFile );
+        if ( fSpeedMenu->IsEnabled() != hasFile )
+             fSpeedMenu->SetEnabled( hasFile );
+        // "goto menu" menu item
+        bool hasMenu = p_intf->p_sys->b_dvdmenus ? hasTitles : false;
+        if ( fGotoMenuMI->IsEnabled() != hasMenu )
+             fGotoMenuMI->SetEnabled( hasMenu );
         Unlock();
     }
 }
@@ -820,20 +891,243 @@ InterfaceWindow::_InputStreamChanged()
     p_wrapper->SetVolume( p_mediaControl->GetVolume() );
 }
 
+/*****************************************************************************
+ * InterfaceWindow::_ShowFilePanel
+ *****************************************************************************/
 void
-make_sure_frame_is_within_limits( BRect& frame, float minWidth, float minHeight,
-                                  float maxWidth, float maxHeight )
+InterfaceWindow::_ShowFilePanel( uint32 command, const char* windowTitle )
 {
-    if ( frame.Width() < minWidth )
-        frame.right = frame.left + minWidth;
-    if ( frame.Height() < minHeight )
-        frame.bottom = frame.top + minHeight;
-    if ( frame.Width() > maxWidth )
-        frame.right = frame.left + maxWidth;
-    if ( frame.Height() > maxHeight )
-        frame.bottom = frame.top + maxHeight;
+       if( !fFilePanel )
+       {
+               fFilePanel = new BFilePanel( B_OPEN_PANEL, NULL, NULL,
+                                                                        B_FILE_NODE | B_DIRECTORY_NODE );
+               fFilePanel->SetTarget( this );
+       }
+       fFilePanel->Window()->SetTitle( windowTitle );
+       BMessage message( command );
+       fFilePanel->SetMessage( &message );
+       if ( !fFilePanel->IsShowing() )
+       {
+               fFilePanel->Refresh();
+               fFilePanel->Show();
+       }
+}
+
+// set_window_pos
+void
+set_window_pos( BWindow* window, BRect frame )
+{
+       // sanity checks: make sure window is not too big/small
+       // and that it's not off-screen
+       float minWidth, maxWidth, minHeight, maxHeight;
+       window->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+       make_sure_frame_is_within_limits( frame,
+                                                                         minWidth, minHeight, maxWidth, maxHeight );
+       if ( make_sure_frame_is_on_screen( frame ) )
+       {
+               window->MoveTo( frame.LeftTop() );
+               window->ResizeTo( frame.Width(), frame.Height() );
+       }
+}
+
+// set_window_pos
+void
+launch_window( BWindow* window, bool showing )
+{
+       if ( window->Lock() )
+       {
+               if ( showing )
+               {
+                       if ( window->IsHidden() )
+                               window->Show();
+               }
+               else
+               {
+                       if ( !window->IsHidden() )
+                               window->Hide();
+               }
+               window->Unlock();
+       }
 }
 
+/*****************************************************************************
+ * InterfaceWindow::_RestoreSettings
+ *****************************************************************************/
+void
+InterfaceWindow::_RestoreSettings()
+{
+       if ( USE_VLC_CONFIG_FILE )
+       {
+               // main window size and position
+           int i_width = config_GetInt( p_intf, "beos-intf-width" ),
+               i_height = config_GetInt( p_intf, "beos-intf-height" ),
+               i_xpos = config_GetInt( p_intf, "beos-intf-xpos" ),
+               i_ypos = config_GetInt( p_intf, "beos-intf-ypos" );
+           if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
+           {
+               BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+               set_window_pos( this, r );
+           }
+               // playlist window size and position
+           i_width = config_GetInt( p_intf, "beos-playlist-width" ),
+           i_height = config_GetInt( p_intf, "beos-playlist-height" ),
+           i_xpos = config_GetInt( p_intf, "beos-playlist-xpos" ),
+           i_ypos = config_GetInt( p_intf, "beos-playlist-ypos" );
+           if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
+           {
+               BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+               set_window_pos( fPlaylistWindow, r );
+           }
+           // playlist showing
+           launch_window( fPlaylistWindow, config_GetInt( p_intf, "beos-playlist-show" ) );
+           // messages window size and position
+           i_width = config_GetInt( p_intf, "beos-messages-width" ),
+           i_height = config_GetInt( p_intf, "beos-messages-height" ),
+           i_xpos = config_GetInt( p_intf, "beos-messages-xpos" ),
+           i_ypos = config_GetInt( p_intf, "beos-messages-ypos" );
+           if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
+           {
+               BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+               set_window_pos( fMessagesWindow, r );
+           }
+           // messages showing
+           launch_window( fMessagesWindow, config_GetInt( p_intf, "beos-messages-show" ) );
+
+               // messages window size and position
+           i_width = config_GetInt( p_intf, "beos-settings-width" ),
+           i_height = config_GetInt( p_intf, "beos-settings-height" ),
+           i_xpos = config_GetInt( p_intf, "beos-settings-xpos" ),
+           i_ypos = config_GetInt( p_intf, "beos-settings-ypos" );
+           if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
+           {
+               BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+               set_window_pos( fPreferencesWindow, r );
+           }
+           // settings showing
+           launch_window( fPreferencesWindow, config_GetInt( p_intf, "beos-settings-show" ) );
+       }
+       else
+       {
+               if ( load_settings( fSettings, "interface_settings", "VideoLAN Client" ) == B_OK )
+               {
+                       BRect frame;
+                       if ( fSettings->FindRect( "main frame", &frame ) == B_OK )
+                               set_window_pos( this, frame );
+                       if (fSettings->FindRect( "playlist frame", &frame ) == B_OK )
+                               set_window_pos( fPlaylistWindow, frame );
+                       if (fSettings->FindRect( "messages frame", &frame ) == B_OK )
+                               set_window_pos( fMessagesWindow, frame );
+                       if (fSettings->FindRect( "settings frame", &frame ) == B_OK )
+                               set_window_pos( fPreferencesWindow, frame );
+                       
+                       bool showing;
+                       if ( fSettings->FindBool( "playlist showing", &showing ) == B_OK )
+                               launch_window( fPlaylistWindow, showing );
+                       if ( fSettings->FindBool( "messages showing", &showing ) == B_OK )
+                               launch_window( fMessagesWindow, showing );
+                       if ( fSettings->FindBool( "settings showing", &showing ) == B_OK )
+                               launch_window( fPreferencesWindow, showing );
+       
+                       uint32 displayMode;
+                       if ( fSettings->FindInt32( "playlist display mode", (int32*)&displayMode ) == B_OK )
+                               fPlaylistWindow->SetDisplayMode( displayMode );
+               }
+       }
+}
+
+/*****************************************************************************
+ * InterfaceWindow::_StoreSettings
+ *****************************************************************************/
+void
+InterfaceWindow::_StoreSettings()
+{
+       if ( USE_VLC_CONFIG_FILE )
+       {
+           // save interface settings in vlc config file
+           BRect frame = Frame();
+           config_PutInt( p_intf, "beos-intf-width", (int)frame.Width() );
+           config_PutInt( p_intf, "beos-intf-height", (int)frame.Height() );
+           config_PutInt( p_intf, "beos-intf-xpos", (int)frame.left );
+           config_PutInt( p_intf, "beos-intf-ypos", (int)frame.top );
+           if( fPlaylistWindow->Lock() )
+           {
+               frame = fPlaylistWindow->Frame();
+               config_PutInt( p_intf, "beos-playlist-width", (int)frame.Width() );
+               config_PutInt( p_intf, "beos-playlist-height", (int)frame.Height() );
+               config_PutInt( p_intf, "beos-playlist-xpos", (int)frame.left );
+               config_PutInt( p_intf, "beos-playlist-ypos", (int)frame.top );
+               config_PutInt( p_intf, "beos-playlist-show", !fPlaylistWindow->IsHidden() );
+               fPlaylistWindow->Unlock();
+           }
+           if( fMessagesWindow->Lock() )
+           {
+               frame = fMessagesWindow->Frame();
+               config_PutInt( p_intf, "beos-messages-width", (int)frame.Width() );
+               config_PutInt( p_intf, "beos-messages-height", (int)frame.Height() );
+               config_PutInt( p_intf, "beos-messages-xpos", (int)frame.left );
+               config_PutInt( p_intf, "beos-messages-ypos", (int)frame.top );
+               config_PutInt( p_intf, "beos-messages-show", !fMessagesWindow->IsHidden() );
+               fMessagesWindow->Unlock();
+           }
+           if( fPreferencesWindow->Lock() )
+           {
+               frame = fPreferencesWindow->Frame();
+               config_PutInt( p_intf, "beos-messages-width", (int)frame.Width() );
+               config_PutInt( p_intf, "beos-messages-height", (int)frame.Height() );
+               config_PutInt( p_intf, "beos-messages-xpos", (int)frame.left );
+               config_PutInt( p_intf, "beos-messages-ypos", (int)frame.top );
+               config_PutInt( p_intf, "beos-messages-show", !fPreferencesWindow->IsHidden() );
+               fPreferencesWindow->Unlock();
+           }
+       }
+    else
+    {
+               if ( fSettings->ReplaceRect( "main frame", Frame() ) != B_OK )
+                       fSettings->AddRect( "main frame", Frame() );
+               if ( fPlaylistWindow->Lock() )
+               {
+                       if (fSettings->ReplaceRect( "playlist frame", fPlaylistWindow->Frame() ) != B_OK)
+                               fSettings->AddRect( "playlist frame", fPlaylistWindow->Frame() );
+                       if (fSettings->ReplaceBool( "playlist showing", !fPlaylistWindow->IsHidden() ) != B_OK)
+                               fSettings->AddBool( "playlist showing", !fPlaylistWindow->IsHidden() );
+                       fPlaylistWindow->Unlock();
+               }
+               if ( fMessagesWindow->Lock() )
+               {
+                       if (fSettings->ReplaceRect( "messages frame", fMessagesWindow->Frame() ) != B_OK)
+                               fSettings->AddRect( "messages frame", fMessagesWindow->Frame() );
+                       if (fSettings->ReplaceBool( "messages showing", !fMessagesWindow->IsHidden() ) != B_OK)
+                               fSettings->AddBool( "messages showing", !fMessagesWindow->IsHidden() );
+                       fMessagesWindow->Unlock();
+               }
+               if ( fPreferencesWindow->Lock() )
+               {
+                       if (fSettings->ReplaceRect( "settings frame", fPreferencesWindow->Frame() ) != B_OK)
+                               fSettings->AddRect( "settings frame", fPreferencesWindow->Frame() );
+                       if (fSettings->ReplaceBool( "settings showing", !fPreferencesWindow->IsHidden() ) != B_OK)
+                               fSettings->AddBool( "settings showing", !fPreferencesWindow->IsHidden() );
+                       fPreferencesWindow->Unlock();
+               }
+               uint32 displayMode = fPlaylistWindow->DisplayMode();
+               if (fSettings->ReplaceInt32( "playlist display mode", displayMode ) != B_OK )
+                       fSettings->AddInt32( "playlist display mode", displayMode );
+       
+               save_settings( fSettings, "interface_settings", "VideoLAN Client" );
+    }
+
+       // save VLC internal settings
+       config_SaveConfigFile( p_intf, "beos" );
+       config_SaveConfigFile( p_intf, "main" );
+       config_SaveConfigFile( p_intf, "adjust" );
+       config_SaveConfigFile( p_intf, "ffmpeg" );
+}
+
+
+
+
+
+
 /*****************************************************************************
  * CDMenu::CDMenu
  *****************************************************************************/
@@ -855,9 +1149,9 @@ CDMenu::~CDMenu()
 void CDMenu::AttachedToWindow(void)
 {
     // remove all items
-    while (BMenuItem* item = RemoveItem(0L))
+    while ( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    GetCD("/dev/disk");
+    GetCD( "/dev/disk" );
     BMenu::AttachedToWindow();
 }
 
@@ -866,54 +1160,26 @@ void CDMenu::AttachedToWindow(void)
  *****************************************************************************/
 int CDMenu::GetCD( const char *directory )
 {
-    BVolumeRoster *volRoster;
-    BVolume       *vol;
-    BDirectory    *dir;
-    int           status;
-    int           mounted;   
-    char          name[B_FILE_NAME_LENGTH]; 
-    fs_info       info;
-    dev_t         dev;
-    
-    volRoster = new BVolumeRoster();
-    vol = new BVolume();
-    dir = new BDirectory();
-    status = volRoster->GetNextVolume(vol);
-    status = vol->GetRootDirectory(dir);
-    while (status ==  B_NO_ERROR)
-    {
-        mounted = vol->GetName(name);    
-        if ((mounted == B_OK) && /* Disk is currently Mounted */
-            (vol->IsReadOnly()) ) /* Disk is read-only */
-        {
-            dev = vol->Device();
-            fs_stat_dev(dev, &info);
-            
-            device_geometry g;
-            int i_dev;
-            i_dev = open( info.device_name, O_RDONLY );
-           
-            if( i_dev >= 0 )
-            {
-                if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
-                {
-                    if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
-                    {
-                        BMessage *msg;
-                        msg = new BMessage( OPEN_DVD );
-                        msg->AddString( "device", info.device_name );
-                        BMenuItem *menu_item;
-                        menu_item = new BMenuItem( name, msg );
-                        AddItem( menu_item );
-                    }
-                    close(i_dev);
-                }
-            }
-         }
-         vol->Unset();
-        status = volRoster->GetNextVolume(vol);
-    }
-    return 0;
+       BVolumeRoster volRoster;
+       BVolume vol;
+       BDirectory dir;
+       status_t status = volRoster.GetNextVolume( &vol );
+       while ( status ==  B_NO_ERROR )
+       {
+               BString deviceName;
+               BString volumeName;
+               bool isCDROM;
+               if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
+                        && isCDROM )
+               {
+                       BMessage* msg = new BMessage( OPEN_DVD );
+                       msg->AddString( "device", deviceName.String() );
+                       BMenuItem* item = new BMenuItem( volumeName.String(), msg );
+                       AddItem( item );
+               }
+               vol.Unset();
+               status = volRoster.GetNextVolume( &vol );
+       }
 }
 
 /*****************************************************************************
@@ -944,32 +1210,17 @@ void LanguageMenu::AttachedToWindow()
         delete item;
 
     SetRadioMode( true );
-    _GetChannels();
+       if ( BList *list = p_wrapper->GetChannels( kind ) )
+       {
+           for ( int32 i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+           
+           if ( list->CountItems() > 1 )
+               AddItem( new BSeparatorItem(), 1 );
+       }
     BMenu::AttachedToWindow();
 }
 
-/*****************************************************************************
- * LanguageMenu::_GetChannels
- *****************************************************************************/
-void LanguageMenu::_GetChannels()
-{
-    BMenuItem *item;
-    BList *list;
-    
-    if( ( list = p_wrapper->GetChannels( kind ) ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
-    
-    if( list->CountItems() > 1 )
-        AddItem( new BSeparatorItem(), 1 );
-}
-
-
 /*****************************************************************************
  * TitleMenu::TitleMenu
  *****************************************************************************/
@@ -991,21 +1242,14 @@ TitleMenu::~TitleMenu()
  *****************************************************************************/
 void TitleMenu::AttachedToWindow()
 {
-    BMenuItem *item;
-    BList *list;
-
-    while( ( item = RemoveItem( 0L ) ) )
+    while( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    
-    if( ( list = p_intf->p_sys->p_wrapper->GetTitles() ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
-    
+
+    if ( BList *list = p_intf->p_sys->p_wrapper->GetTitles() )
+       {    
+               for( int i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+       }
     BMenu::AttachedToWindow();
 }
 
@@ -1031,21 +1275,80 @@ ChapterMenu::~ChapterMenu()
  *****************************************************************************/
 void ChapterMenu::AttachedToWindow()
 {
-    BMenuItem *item;
-    BList *list;
-
-    while( ( item = RemoveItem( 0L ) ) )
+    while( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    
-    if( ( list = p_intf->p_sys->p_wrapper->GetChapters() ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
+
+    if ( BList* list = p_intf->p_sys->p_wrapper->GetChapters() )
+       {    
+           for( int i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+       }
     
     BMenu::AttachedToWindow();
 }
 
+
+
+
+
+
+
+
+
+/*****************************************************************************
+ * load_settings
+ *****************************************************************************/
+status_t
+load_settings( BMessage* message, const char* fileName, const char* folder )
+{
+       status_t ret = B_BAD_VALUE;
+       if ( message )
+       {
+               BPath path;
+               if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
+               {
+                       // passing folder is optional
+                       if ( folder )
+                               ret = path.Append( folder );
+                       if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
+                       {
+                               BFile file( path.Path(), B_READ_ONLY );
+                               if ( ( ret = file.InitCheck() ) == B_OK )
+                               {
+                                       ret = message->Unflatten( &file );
+                                       file.Unset();
+                               }
+                       }
+               }
+       }
+       return ret;
+}
+
+/*****************************************************************************
+ * save_settings
+ *****************************************************************************/
+status_t
+save_settings( BMessage* message, const char* fileName, const char* folder )
+{
+       status_t ret = B_BAD_VALUE;
+       if ( message )
+       {
+               BPath path;
+               if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
+               {
+                       // passing folder is optional
+                       if ( folder && ( ret = path.Append( folder ) ) == B_OK )
+                               ret = create_directory( path.Path(), 0777 );
+                       if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
+                       {
+                               BFile file( path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE );
+                               if ( ( ret = file.InitCheck() ) == B_OK )
+                               {
+                                       ret = message->Flatten( &file );
+                                       file.Unset();
+                               }
+                       }
+               }
+       }
+       return ret;
+}