modules/gui/beos/InterfaceWindow.h/.cpp
authorStephan Assmus <stippi@videolan.org>
Mon, 3 Feb 2003 17:18:48 +0000 (17:18 +0000)
committerStephan Assmus <stippi@videolan.org>
Mon, 3 Feb 2003 17:18:48 +0000 (17:18 +0000)
- improved file loading:
- contents of sub folders can optionally be loaded too
- files are loaded in expected order from filepanel
_and_ drag'n'drop
- file panel accepts folders to load
- saving of playlist's display mode
- added updating of interface when playlist is modified
while nothing is playing
- added compatibility for SoundPlay's drag'n'drop message format

modules/gui/beos/ListViews.h/.cpp

- implemented reversal of playlist
- list can display full path or file name only
- drag'n'drop interaction with SoundPlay

modules/gui/beos/MediaControlView.cpp

- cosmetic fix

modules/gui/beos/PlayListWindow.h/.cpp

- added reverse sort command to edit menu
- added view menu, to allow the user to display paths
or only names in the list

modules/gui/beos/InterfaceWindow.cpp
modules/gui/beos/ListViews.cpp
modules/gui/beos/ListViews.h
modules/gui/beos/MediaControlView.cpp
modules/gui/beos/MsgVals.h
modules/gui/beos/PlayListWindow.cpp
modules/gui/beos/PlayListWindow.h

index b42eab2..3ebfd14 100644 (file)
@@ -2,7 +2,7 @@
  * InterfaceWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: InterfaceWindow.cpp,v 1.26 2003/02/01 12:01:10 stippi Exp $
+ * $Id: InterfaceWindow.cpp,v 1.27 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -130,6 +130,50 @@ get_volume_info( BVolume& volume, BString& volumeName, bool& isCDROM, BString& d
        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
@@ -607,6 +651,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:
             {
@@ -614,86 +671,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 folder?
-                        BDirectory dir( &ref );
-                        if ( dir.InitCheck() == B_OK)
-                        {
-                               // has the user dropped a dvd disk icon?
-                                       // TODO: this code does not work for the following situation:
-                                       // if the user dropped the icon for his partition containing
-                                       // all his mp3 files, this routine will not do anything, because
-                                       // the folder that was dropped is a root folder, but no DVD drive
-                                                       if ( dir.IsRootDirectory() )
-                                                       {
-                                                               BVolumeRoster volRoster;
-                                                               BVolume vol;
-                                                               BDirectory volumeRoot;
-                                                               status_t status = volRoster.GetNextVolume( &vol );
-                                                               while ( status == B_NO_ERROR )
+                
+                // 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() )
                                                                {
-                                                                       if ( vol.GetRootDirectory( &volumeRoot ) == B_OK
-                                                                                && dir == volumeRoot )
+                                                                       BVolumeRoster volRoster;
+                                                                       BVolume vol;
+                                                                       BDirectory volumeRoot;
+                                                                       status_t status = volRoster.GetNextVolume( &vol );
+                                                                       while ( status == B_NO_ERROR )
                                                                        {
-                                                                               BString volumeName;
-                                                                               BString deviceName;
-                                                                               bool isCDROM;
-                                                                               if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
-                                                                                        && isCDROM )
+                                                                               if ( vol.GetRootDirectory( &volumeRoot ) == B_OK
+                                                                                        && dir == volumeRoot )
                                                                                {
-                                                                                       BMessage msg( OPEN_DVD );
-                                                                                       msg.AddString( "device", deviceName.String() );
-                                                                                       PostMessage( &msg );
-                                                                                       add = false;
+                                                                                       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 );
                                                                                }
-                                                                               break;
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               vol.Unset();
-                                                                               status = volRoster.GetNextVolume( &vol );
                                                                        }
                                                                }
-                                                       }
-                               else
-                               {
-                                       // add all files from the dropped folder
-                                       // TODO: do this recursively
-                                       dir.Rewind();
-                                       add = false;
-                                       BEntry entry;
-                                       while ( dir.GetNextEntry( &entry ) == B_OK )
-                                       {
-                                                                       // ", 0" is because we receive the files in reverse order
-                                               if ( !entry.IsDirectory() && entry.GetPath( &path ) == B_OK )
-                                                   files.AddItem( new BString( path.Path() ), 0 );
-                                       }
-                               }
-                        }
-                        if( add )
-                        {
-                            files.AddItem( new BString( path.Path() ) );
-                        }
-                    }
-                }
-                // 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();
+                                       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;
 
@@ -722,7 +789,9 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             }
             break;
         }
-                
+        case MSG_UPDATE:
+               UpdateInterface();
+               break;
         default:
             BWindow::MessageReceived( p_message );
             break;
@@ -819,11 +888,22 @@ void InterfaceWindow::UpdateInterface()
     }
     else
     {
-        _SetMenusEnabled( false );
-        if( !( p_wrapper->PlaylistSize() > 0 ) )
-            p_mediaControl->SetEnabled( false );
-        else
-            p_mediaControl->SetProgress( 0 );
+               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();
+        }
     }
 
     /* always force the user-specified volume */
@@ -946,7 +1026,8 @@ InterfaceWindow::_ShowFilePanel( uint32 command, const char* windowTitle )
 {
        if( !fFilePanel )
        {
-               fFilePanel = new BFilePanel();
+               fFilePanel = new BFilePanel( B_OPEN_PANEL, NULL, NULL,
+                                                                        B_FILE_NODE | B_DIRECTORY_NODE );
                fFilePanel->SetTarget( this );
        }
        fFilePanel->Window()->SetTitle( windowTitle );
@@ -1022,6 +1103,10 @@ InterfaceWindow::_RestoreSettings()
                        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 );
        }
 }
 
@@ -1057,6 +1142,11 @@ InterfaceWindow::_StoreSettings()
                        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" );
 }
 
index 373d681..04abaa3 100644 (file)
@@ -2,7 +2,7 @@
  * ListViews.h: BeOS interface list view class implementation
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: ListViews.cpp,v 1.4 2003/02/02 11:29:12 stippi Exp $
+ * $Id: ListViews.cpp,v 1.5 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Stephan Aßmus <stippi@yellowbites.com>
  *
@@ -25,6 +25,7 @@
 #include <malloc.h>
 
 #include <Bitmap.h>
+#include <Entry.h>
 #include <String.h>
 
 /* VLC headers */
  * PlaylistItem class
  *****************************************************************************/
 PlaylistItem::PlaylistItem( const char *name )
-       : BStringItem( name )
+       : BStringItem( name ),
+         fName( "" )
 {
+       entry_ref ref;
+       if ( get_ref_for_path( name, &ref) == B_OK )
+               fName.SetTo( ref.name );
 }
 
 PlaylistItem::~PlaylistItem()
@@ -57,7 +62,7 @@ PlaylistItem::~PlaylistItem()
  *****************************************************************************/
 void
 PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
-                                       bool active, bool playing )
+                                       uint32 mode, bool active, bool playing )
 {
        rgb_color color = (rgb_color){ 255, 255, 255, 255 };
        if ( tintedLine )
@@ -71,7 +76,18 @@ PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
        owner->SetHighColor( 0, 0, 0, 255 );
        font_height fh;
        owner->GetFontHeight( &fh );
-       BString truncatedString( Text() );
+       const char* text = Text();
+       switch ( mode )
+       {
+               case DISPLAY_NAME:
+                       if ( fName.CountChars() > 0 )
+                               text = fName.String();
+                       break;
+               case DISPLAY_PATH:
+               default:
+                       break;
+       }
+       BString truncatedString( text );
        owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
                                                   frame.Width() - TEXT_OFFSET - 4.0 );
        owner->DrawString( truncatedString.String(),
@@ -330,12 +346,15 @@ DragSortableListView::MessageReceived(BMessage* message)
 void
 DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
 {
-       if ( msg && msg->what == B_SIMPLE_DATA )
+       if ( msg && ( msg->what == B_SIMPLE_DATA || msg->what == MSG_SOUNDPLAY ) )
        {
                bool replaceAll = !msg->HasPointer("list") && !(modifiers() & B_SHIFT_KEY);
                switch ( transit )
                {
                        case B_ENTERED_VIEW:
+                               // remember drag message
+                               // this is needed to react on modifier changes
+                               fDragMessageCopy = *msg;
                        case B_INSIDE_VIEW:
                        {
                                if ( replaceAll )
@@ -359,19 +378,18 @@ DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *m
                                break;
                        }
                        case B_EXITED_VIEW:
+                               // forget drag message
+                               fDragMessageCopy.what = 0;
                        case B_OUTSIDE_VIEW:
                                _RemoveDropAnticipationRect();
                                break;
                }
-               // remember drag message
-               // this is needed to react on modifier changes
-               fDragMessageCopy = *msg;
        }
        else
        {
                _RemoveDropAnticipationRect();
-               fDragMessageCopy.what = 0;
                BListView::MouseMoved(where, transit, msg);
+               fDragMessageCopy.what = 0;
        }
 }
 
@@ -383,6 +401,7 @@ DragSortableListView::MouseUp( BPoint where )
 {
        // remove drop mark
        _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
+       // be sure to forget drag message
        fDragMessageCopy.what = 0;
        BListView::MouseUp( where );
 }
@@ -506,6 +525,18 @@ DragSortableListView::RemoveSelected()
        RemoveItemList( items );
 }
 
+/*****************************************************************************
+ * DragSortableListView::CountSelectedItems
+ *****************************************************************************/
+int32
+DragSortableListView::CountSelectedItems() const
+{
+       int32 count = 0;
+       while ( CurrentSelection( count ) >= 0 )
+               count++;
+       return count;
+}
+
 /*****************************************************************************
  * DragSortableListView::_SetDropAnticipationRect
  *****************************************************************************/
@@ -585,8 +616,10 @@ PlaylistView::PlaylistView( BRect frame, InterfaceWindow* mainWindow,
                                                        | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
          fCurrentIndex( -1 ),
          fPlaying( false ),
+         fDisplayMode( DISPLAY_PATH ),
          fMainWindow( mainWindow ),
          fSelectionChangeMessage( selectionChangeMessage ),
+         fLastClickedItem( NULL ),
          fVlcWrapper( wrapper )
 {
 }
@@ -614,6 +647,7 @@ PlaylistView::MessageReceived( BMessage* message)
 {
        switch ( message->what )
        {
+               case MSG_SOUNDPLAY:
                case B_SIMPLE_DATA:
                        if ( message->HasPointer( "list" ) )
                        {
@@ -649,17 +683,26 @@ PlaylistView::MouseDown( BPoint where )
                {
                        if ( clicks == 2 )
                        {
-                               fVlcWrapper->PlaylistJumpTo( i );
-                               handled = true;
+                               // only do something if user clicked the same item twice
+                               if ( fLastClickedItem == item )
+                               {
+                                       fVlcWrapper->PlaylistJumpTo( i );
+                                       handled = true;
+                               }
                        }
-                       else if ( i == fCurrentIndex )
+                       else
                        {
-                               r.right = r.left + TEXT_OFFSET;
-                               if ( r.Contains ( where ) )
+                               // remember last clicked item
+                               fLastClickedItem = item;
+                               if ( i == fCurrentIndex )
                                {
-                                       fMainWindow->PostMessage( PAUSE_PLAYBACK );
-                                       InvalidateItem( i );
-                                       handled = true;
+                                       r.right = r.left + TEXT_OFFSET;
+                                       if ( r.Contains ( where ) )
+                                       {
+                                               fMainWindow->PostMessage( PAUSE_PLAYBACK );
+                                               InvalidateItem( i );
+                                               handled = true;
+                                       }
                                }
                        }
                        break;
@@ -727,9 +770,7 @@ PlaylistView::MoveItems( BList& items, int32 index )
                int32 count = items.CountItems();
                int32 indexOriginal = index;
                // remember currently playing item
-               int32 currentIndex, size;
-               fVlcWrapper->GetPlaylistInfo( currentIndex, size );
-               BListItem* playingItem = ItemAt( currentIndex );
+               BListItem* playingItem = _PlayingItem();
                // collect item pointers for removal by index
                for ( int32 i = 0; i < count; i++ )
                {
@@ -761,15 +802,10 @@ PlaylistView::MoveItems( BList& items, int32 index )
                // update GUI
                DragSortableListView::MoveItems( items, indexOriginal );
                // restore currently playing item
-               for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
-               {
-                       if ( item == playingItem )
-                       {
-                               fVlcWrapper->PlaylistSetPlaying( i );
-                               SetCurrent( i );
-                               break;
-                       }
-               }
+               _SetPlayingIndex( playingItem );
+               // update interface (in case it isn't playing,
+               // there is a chance that it needs to update)
+               fMainWindow->PostMessage( MSG_UPDATE );
                fVlcWrapper->PlaylistUnlock();
        }
 }
@@ -789,9 +825,7 @@ PlaylistView::CopyItems( BList& items, int32 toIndex )
                BList clonedItems;
                int32 count = items.CountItems();
                // remember currently playing item
-               int32 currentIndex, size;
-               fVlcWrapper->GetPlaylistInfo( currentIndex, size );
-               BListItem* playingItem = ItemAt( currentIndex );
+               BListItem* playingItem = _PlayingItem();
                // collect cloned item pointers
                for ( int32 i = 0; i < count; i++ )
                {
@@ -815,15 +849,10 @@ PlaylistView::CopyItems( BList& items, int32 toIndex )
                // update GUI
                DragSortableListView::CopyItems( items, toIndex );
                // restore currently playing item
-               for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
-               {
-                       if ( item == playingItem )
-                       {
-                               fVlcWrapper->PlaylistSetPlaying( i );
-                               SetCurrent( i );
-                               break;
-                       }
-               }
+               _SetPlayingIndex( playingItem );
+               // update interface (in case it isn't playing,
+               // there is a chance that it needs to update)
+               fMainWindow->PostMessage( MSG_UPDATE );
                fVlcWrapper->PlaylistUnlock();
        }
 }
@@ -836,6 +865,8 @@ PlaylistView::RemoveItemList( BList& items )
 {
        if ( fVlcWrapper->PlaylistLock() )
        {
+               // remember currently playing item
+               BListItem* playingItem = _PlayingItem();
                // collect item pointers for removal
                BList removeItems;
                int32 count = items.CountItems();
@@ -854,6 +885,11 @@ PlaylistView::RemoveItemList( BList& items )
                }
                // update GUI
                DragSortableListView::RemoveItemList( items );
+               // restore currently playing item
+               _SetPlayingIndex( playingItem );
+               // update interface (in case it isn't playing,
+               // there is a chance that it needs to update)
+               fMainWindow->PostMessage( MSG_UPDATE );
                fVlcWrapper->PlaylistUnlock();
        }
 }
@@ -877,7 +913,8 @@ void
 PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
 {
        if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
-               item->Draw( owner,  frame, index % 2, index == fCurrentIndex, fPlaying );
+               item->Draw( owner,  frame, index % 2,
+                                       fDisplayMode, index == fCurrentIndex, fPlaying );
 }
 
 /*****************************************************************************
@@ -891,8 +928,16 @@ PlaylistView::MakeDragMessage( BMessage* message ) const
                message->AddPointer( "list", (void*)this );
                int32 index;
                for ( int32 i = 0; ( index = CurrentSelection( i ) ) >= 0; i++ )
+               {
                        message->AddInt32( "index", index );
-                       // TODO: add refs to message (inter application communication)
+                       // add refs to message (inter application communication)
+                       if ( BStringItem* item = dynamic_cast<BStringItem*>( ItemAt( index ) ) )
+                       {
+                               entry_ref ref;
+                               if ( get_ref_for_path( item->Text(), &ref ) == B_OK )
+                                       message->AddRef( "refs", &ref );
+                       }
+               }
        }
 }
 
@@ -938,3 +983,93 @@ PlaylistView::RebuildList()
        for ( int i = 0; i < fVlcWrapper->PlaylistSize(); i++ )
                AddItem( new PlaylistItem( fVlcWrapper->PlaylistItemName( i ) ) );
 }
+
+
+/*****************************************************************************
+ * PlaylistView::SortReverse
+ *****************************************************************************/
+void
+PlaylistView::SortReverse()
+{
+       if ( int32 count = CountSelectedItems() )
+       {
+               int32 last  = count - 1;
+               // remember currently playing item
+               BListItem* playingItem = _PlayingItem();
+               for ( int32 first = 0; first < count / 2; first++, last-- )
+               {
+                       int32 index1 = CurrentSelection( first);
+                       int32 index2 = CurrentSelection( last);
+                       if ( SwapItems( index1, index2 ) )
+                       {
+                               // index2 > index1, so the list won't get messed up
+                               // if we remove the items in that order
+                               // TODO: Error checking + handling!
+                               void* item2 = fVlcWrapper->PlaylistRemoveItem( index2 );
+                               void* item1 = fVlcWrapper->PlaylistRemoveItem( index1 );
+                               fVlcWrapper->PlaylistAddItem( item2, index1 );
+                               fVlcWrapper->PlaylistAddItem( item1, index2 );
+                       }
+               }
+               // restore currently playing item
+               _SetPlayingIndex( playingItem );
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::SortByPath
+ *****************************************************************************/
+void
+PlaylistView::SortByPath()
+{
+       
+}
+
+/*****************************************************************************
+ * PlaylistView::SortByName
+ *****************************************************************************/
+void
+PlaylistView::SortByName()
+{
+}
+
+/*****************************************************************************
+ * PlaylistView::SetDisplayMode
+ *****************************************************************************/
+void
+PlaylistView::SetDisplayMode( uint32 mode )
+{
+       if ( mode != fDisplayMode )
+       {
+               fDisplayMode = mode;
+               Invalidate();
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::_PlayingItem
+ *****************************************************************************/
+BListItem*
+PlaylistView::_PlayingItem() const
+{
+       int32 currentIndex, size;
+       fVlcWrapper->GetPlaylistInfo( currentIndex, size );
+       return ItemAt( currentIndex );
+}
+
+/*****************************************************************************
+ * PlaylistView::_SetPlayingIndex
+ *****************************************************************************/
+void
+PlaylistView::_SetPlayingIndex( BListItem* playingItem )
+{
+       for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
+       {
+               if ( item == playingItem )
+               {
+                       fVlcWrapper->PlaylistSetPlaying( i );
+                       SetCurrent( i );
+                       break;
+               }
+       }
+}
index cc93430..df9104b 100644 (file)
@@ -2,7 +2,7 @@
  * ListViews.h: BeOS interface list view class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: ListViews.h,v 1.3 2003/02/01 12:01:11 stippi Exp $
+ * $Id: ListViews.h,v 1.4 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Stephan Aßmus <stippi@yellowbites.com>
  *
 
 #include <ListItem.h>
 #include <ListView.h>
+#include <String.h>
+
+enum
+{
+       DISPLAY_PATH    = 0,
+       DISPLAY_NAME,
+};
 
 class InterfaceWindow;
 
@@ -38,9 +45,13 @@ class PlaylistItem : public BStringItem
 
                virtual void            Draw( BView* owner, BRect frame,
                                                                  bool tintedLine,
+                                                                 uint32 mode,
                                                                  bool active = false,
                                                                  bool playing = false );
 
+ private:
+               BString                         fName;  // additional to BStringItem::Text()
+
 };
 
 // DragSortableListView
@@ -79,6 +90,7 @@ class DragSortableListView : public BListView
        virtual void                    CopyItems( BList& items, int32 toIndex );
        virtual void                    RemoveItemList( BList& indices );
                        void                    RemoveSelected(); // uses RemoveItemList()
+                       int32                   CountSelectedItems() const;
 
        virtual BListItem*              CloneItem( int32 atIndex ) const = 0;
        virtual void                    DrawListItem( BView* owner, int32 index,
@@ -130,11 +142,24 @@ class PlaylistView : public DragSortableListView
                        void                    SetPlaying( bool playing );
                        void                    RebuildList();
 
+                       void                    SortReverse();
+                       void                    SortByPath();
+                       void                    SortByName();
+
+                       void                    SetDisplayMode( uint32 mode );
+                       uint32                  DisplayMode() const
+                                                               { return fDisplayMode; }
+
  private:
+                       BListItem*              _PlayingItem() const;
+                       void                    _SetPlayingIndex( BListItem* item );
+
        int32                                   fCurrentIndex;
        bool                                    fPlaying;
+       uint32                                  fDisplayMode;
        InterfaceWindow*                fMainWindow;
        BMessage*                               fSelectionChangeMessage;
+       PlaylistItem*                   fLastClickedItem;
        
        VlcWrapper*                             fVlcWrapper;
 };
index 32aa9f7..8ab9d17 100644 (file)
@@ -2,7 +2,7 @@
  * MediaControlView.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: MediaControlView.cpp,v 1.14 2003/02/01 12:01:11 stippi Exp $
+ * $Id: MediaControlView.cpp,v 1.15 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Tony Castley <tony@castley.net>
  *          Stephan Aßmus <stippi@yellowbites.com>
@@ -1454,12 +1454,12 @@ void
 PositionInfoView::_MakeString( BString& into, int32 index, int32 maxIndex ) const
 {
        into = "";
-       if ( index >= 0)
+       if ( index >= 0 && maxIndex >= 0 )
                into << index;
        else
                into << "-";
        into << "/";
-       if ( maxIndex >= 0)
+       if ( maxIndex >= 0 )
                into << maxIndex;
        else
                into << "-";
index c62b879..b29cdd3 100644 (file)
@@ -2,7 +2,7 @@
  * MsgVals.h
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: MsgVals.h,v 1.5 2003/01/25 20:15:41 titer Exp $
+ * $Id: MsgVals.h,v 1.6 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Tony Castley <tcastley@mail.powerup.com.au>
  *          Stephan Aßmus <stippi@yellowbites.com>
@@ -63,9 +63,11 @@ const uint32 RESIZE_100         = 'rsor';
 const uint32 RESIZE_200         = 'rsdb';
 const uint32 RESIZE_TRUE        = 'rstr';
 const uint32 ASPECT_CORRECT     = 'asco';
-const uint32 VERT_SYNC          = 'vsyn';
-const uint32 WINDOW_FEEL        = 'wfel';
-const uint32 SCREEN_SHOT        = 'scrn';
+const uint32 VERT_SYNC                 = 'vsyn';
+const uint32 WINDOW_FEEL               = 'wfel';
+const uint32 SCREEN_SHOT               = 'scrn';
+const uint32 MSG_UPDATE                        = 'updt';
+const uint32 MSG_SOUNDPLAY             = 'move';       // drag'n'drop from soundplay playlist
 const uint32 INTERFACE_CREATED  = 'ifcr';  /* see VlcApplication::MessageReceived()
                                             * in src/misc/beos_specific.cpp */
 
index 12a1ef7..c65427b 100644 (file)
@@ -2,7 +2,7 @@
  * PlayListWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: PlayListWindow.cpp,v 1.7 2003/02/01 12:01:11 stippi Exp $
+ * $Id: PlayListWindow.cpp,v 1.8 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -46,12 +46,14 @@ enum
        MSG_SELECT_ALL                  = 'sall',
        MSG_SELECT_NONE                 = 'none',
        MSG_RANDOMIZE                   = 'rndm',
+       MSG_SORT_REVERSE                = 'srtr',
        MSG_SORT_NAME                   = 'srtn',
        MSG_SORT_PATH                   = 'srtp',
        MSG_REMOVE                              = 'rmov',
        MSG_REMOVE_ALL                  = 'rmal',
 
        MSG_SELECTION_CHANGED   = 'slch',
+       MSG_SET_DISPLAY                 = 'stds',
 };
 
 
@@ -103,6 +105,9 @@ PlayListWindow::PlayListWindow( BRect frame, const char* name,
        editMenu->AddItem( fSelectNoneMI );
 
        editMenu->AddSeparatorItem();
+       fSortReverseMI = new BMenuItem( "Sort Reverse",
+                                                                new BMessage( MSG_SORT_REVERSE ), 'F' );
+       editMenu->AddItem( fSortReverseMI );
        fSortNameMI = new BMenuItem( "Sort by Name",
                                                                 new BMessage( MSG_SORT_NAME ), 'N' );
 fSortNameMI->SetEnabled( false );
@@ -123,6 +128,22 @@ fRandomizeMI->SetEnabled( false );
                                                                  new BMessage( MSG_REMOVE_ALL ) );
        editMenu->AddItem( fRemoveAllMI );
 
+       // Add View menu
+       fViewMenu = new BMenu( "View" );
+       fMenuBar->AddItem( fViewMenu );
+
+       fViewMenu->SetRadioMode( true );
+       BMessage* message = new BMessage( MSG_SET_DISPLAY );
+       message->AddInt32( "mode", DISPLAY_PATH );
+       item = new BMenuItem( "Path", message );
+       item->SetMarked( true );
+       fViewMenu->AddItem( item );
+
+       message = new BMessage( MSG_SET_DISPLAY );
+       message->AddInt32( "mode", DISPLAY_NAME );
+       item = new BMenuItem( "Name", message );
+       fViewMenu->AddItem( item );
+
        // make menu bar resize to correct height
        float menuWidth, menuHeight;
        fMenuBar->GetPreferredSize( &menuWidth, &menuHeight );
@@ -145,8 +166,8 @@ fRandomizeMI->SetEnabled( false );
        // be up to date
        UpdatePlaylist();
        FrameResized( Bounds().Width(), Bounds().Height() );
-       SetSizeLimits( menuWidth * 2.0, menuWidth * 6.0,
-                                  menuHeight * 5.0, menuHeight * 25.0 );
+       SetSizeLimits( menuWidth * 1.5, menuWidth * 8.0,
+                                  menuHeight * 5.0, menuHeight * 50.0 );
 
        UpdatePlaylist( true );
        // start window thread in hidden state
@@ -193,6 +214,9 @@ PlayListWindow::MessageReceived( BMessage * p_message )
                        break;
                case MSG_RANDOMIZE:
                        break;
+               case MSG_SORT_REVERSE:
+                       fListView->SortReverse();
+                       break;
                case MSG_SORT_NAME:
                        break;
                case MSG_SORT_PATH:
@@ -207,6 +231,13 @@ PlayListWindow::MessageReceived( BMessage * p_message )
                case MSG_SELECTION_CHANGED:
                        _CheckItemsEnableState();
                        break;
+               case MSG_SET_DISPLAY:
+               {
+                       uint32 mode;
+                       if ( p_message->FindInt32( "mode", (int32*)&mode ) == B_OK )
+                               SetDisplayMode( mode );
+                       break;
+               }
                case B_MODIFIERS_CHANGED:
                        fListView->ModifiersChanged();
                        break;
@@ -257,6 +288,42 @@ PlayListWindow::UpdatePlaylist( bool rebuild )
        _CheckItemsEnableState();
 }
 
+/*****************************************************************************
+ * PlayListWindow::SetDisplayMode
+ *****************************************************************************/
+void
+PlayListWindow::SetDisplayMode( uint32 mode )
+{
+       if ( Lock() )
+       {
+               // propagate to list view
+               fListView->SetDisplayMode( mode );
+               // mark correct menu item
+               for ( int32 i = 0; BMenuItem* item = fViewMenu->ItemAt( i ); i++ )
+               {
+                       BMessage* message = item->Message();
+                       uint32 itemMode;
+                       if ( message
+                                && message->FindInt32( "mode", (int32*)&itemMode ) == B_OK
+                                && itemMode == mode )
+                       {
+                               item->SetMarked( true );
+                               break;
+                       }
+               }
+               Unlock();
+       }
+}
+
+/*****************************************************************************
+ * PlayListWindow::DisplayMode
+ *****************************************************************************/
+uint32
+PlayListWindow::DisplayMode() const
+{
+       return fListView->DisplayMode();
+}
+
 /*****************************************************************************
  * PlayListWindow::_CheckItemsEnableState
  *****************************************************************************/
@@ -267,11 +334,12 @@ PlayListWindow::_CheckItemsEnableState() const
        int32 test = fListView->CurrentSelection( 0 );
        bool enable1 = test >= 0;
        // check if at least two items selected
-//     test = fListView->CurrentSelection( 1 );
-//     bool enable2 = test >= 0;
+       test = fListView->CurrentSelection( 1 );
+       bool enable2 = test >= 0;
        bool notEmpty = fListView->CountItems() > 0;
        _SetMenuItemEnabled( fSelectAllMI, notEmpty );
        _SetMenuItemEnabled( fSelectNoneMI, enable1 );
+       _SetMenuItemEnabled( fSortReverseMI, enable2 );
 //     _SetMenuItemEnabled( fSortNameMI, enable2 );
 //     _SetMenuItemEnabled( fSortPathMI, enable2 );
 //     _SetMenuItemEnabled( fRandomizeMI, enable2 );
index ed098d6..7694888 100644 (file)
@@ -2,7 +2,7 @@
  * PlayListWindow.h: BeOS interface window class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: PlayListWindow.h,v 1.6 2003/02/01 12:01:11 stippi Exp $
+ * $Id: PlayListWindow.h,v 1.7 2003/02/03 17:18:48 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Tony Castley <tcastley@mail.powerup.com.au>
@@ -51,6 +51,9 @@ class PlayListWindow : public BWindow
                        void                            ReallyQuit();
                        void                            UpdatePlaylist( bool rebuild = false );
 
+                       void                            SetDisplayMode( uint32 mode );
+                       uint32                          DisplayMode() const;
+
  private:      
                        void                            _CheckItemsEnableState() const;
                        void                            _SetMenuItemEnabled( BMenuItem* item,
@@ -63,11 +66,13 @@ class PlayListWindow : public BWindow
 
                        BMenuItem*                      fSelectAllMI;
                        BMenuItem*                      fSelectNoneMI;
+                       BMenuItem*                      fSortReverseMI;
                        BMenuItem*                      fSortNameMI;
                        BMenuItem*                      fSortPathMI;
                        BMenuItem*                      fRandomizeMI;
                        BMenuItem*                      fRemoveMI;
                        BMenuItem*                      fRemoveAllMI;
+                       BMenu*                          fViewMenu;
                        
                        intf_thread_t *     p_intf;
                        VlcWrapper *            p_wrapper;