From bae0154ca35cc1f8187cf9d09b63e0b08a41ad4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 16 May 2009 11:29:19 +0000 Subject: [PATCH] * I didn't like so much how the "Remove and Move into Trash" feature was implemented. It didn't reuse existing code and didn't integrate well. No Undo/Redo except via Tracker, but not in the Playlist... some bugs as well (Remove had same shortcut as Randomize, Didn't maintain current playback item if last entry was removed) * I need to reenable the main window short cut though. This is only temporary. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30768 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/ControllerView.cpp | 10 -- src/apps/mediaplayer/ControllerView.h | 3 +- src/apps/mediaplayer/MainWin.cpp | 131 ++++++++-------- src/apps/mediaplayer/playlist/ListViews.cpp | 27 ++-- src/apps/mediaplayer/playlist/ListViews.h | 8 +- src/apps/mediaplayer/playlist/Playlist.cpp | 41 ++--- src/apps/mediaplayer/playlist/Playlist.h | 10 +- .../mediaplayer/playlist/PlaylistListView.cpp | 18 +-- .../mediaplayer/playlist/PlaylistListView.h | 8 +- .../mediaplayer/playlist/PlaylistWindow.cpp | 68 +++----- .../mediaplayer/playlist/PlaylistWindow.h | 3 +- .../playlist/RemovePLItemsCommand.cpp | 147 +++++++++++++++++- .../playlist/RemovePLItemsCommand.h | 12 +- 13 files changed, 280 insertions(+), 206 deletions(-) diff --git a/src/apps/mediaplayer/ControllerView.cpp b/src/apps/mediaplayer/ControllerView.cpp index 8ce15e525d..84cf06f50a 100644 --- a/src/apps/mediaplayer/ControllerView.cpp +++ b/src/apps/mediaplayer/ControllerView.cpp @@ -135,16 +135,6 @@ ControllerView::SkipForward() } -void -ControllerView::SkipForwardAndDelete() -{ - BAutolock _(fPlaylist); - int32 index = fPlaylist->CurrentRefIndex(); - fPlaylist->SetCurrentRefIndex(index + 1); - fPlaylist->RemoveRefPermanent(index, true); -} - - void ControllerView::VolumeChanged(float value) { diff --git a/src/apps/mediaplayer/ControllerView.h b/src/apps/mediaplayer/ControllerView.h index 3e847043fe..9c4eb3c2ff 100644 --- a/src/apps/mediaplayer/ControllerView.h +++ b/src/apps/mediaplayer/ControllerView.h @@ -36,7 +36,7 @@ public: ControllerView(BRect frame, Controller* controller, Playlist* playlist); ~ControllerView(); - + // TransportControlGroup interface virtual uint32 EnabledButtons(); virtual void TogglePlaying(); @@ -45,7 +45,6 @@ public: virtual void Forward(); virtual void SkipBackward(); virtual void SkipForward(); - virtual void SkipForwardAndDelete(); virtual void VolumeChanged(float value); virtual void ToggleMute(); virtual void PositionChanged(float value); diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index 8b96efcc6d..05a27c4b64 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -63,7 +63,7 @@ enum { M_FILE_INFO, M_FILE_PLAYLIST, M_FILE_CLOSE, - M_FILE_QUIT, + M_FILE_QUIT, M_VIEW_50, M_VIEW_100, M_VIEW_200, @@ -93,7 +93,7 @@ enum { M_SELECT_VIDEO_TRACK_END = 0x000fffff, M_SET_PLAYLIST_POSITION, - + M_FILE_DELETE }; @@ -131,7 +131,7 @@ MainWin::MainWin() static int pos = 0; MoveBy(pos * 25, pos * 25); pos = (pos + 1) % 15; - + BRect rect = Bounds(); // background @@ -154,7 +154,7 @@ MainWin::MainWin() fMenuBarHeight + 10); fVideoView = new VideoView(rect, "video display", B_FOLLOW_NONE); fBackground->AddChild(fVideoView); - + // controls rect = BRect(0, fMenuBarHeight + 11, fBackground->Bounds().right, fBackground->Bounds().bottom); @@ -165,7 +165,7 @@ MainWin::MainWin() fControlsWidth = (int)fControls->Frame().Width() + 1; fControls->SetResizingMode(B_FOLLOW_BOTTOM | B_FOLLOW_LEFT_RIGHT); // fControls->MoveTo(0, fBackground->Bounds().bottom - fControlsHeight + 1); - + // fVideoView->ResizeTo(fBackground->Bounds().Width(), // fBackground->Bounds().Height() - fMenuBarHeight - fControlsHeight); @@ -175,14 +175,14 @@ MainWin::MainWin() PeakView* peakView = fControls->GetPeakView(); peakView->SetPeakNotificationWhat(MSG_PEAK_NOTIFICATION); fController->SetPeakListener(peakView); - + // printf("fMenuBarHeight %d\n", fMenuBarHeight); // printf("fControlsHeight %d\n", fControlsHeight); // printf("fControlsWidth %d\n", fControlsWidth); _SetupWindow(); - // setup the playlist window now, we need to have it + // setup the playlist window now, we need to have it // running for the undo/redo playlist editing fPlaylistWindow = new PlaylistWindow(BRect(150, 150, 500, 600), fPlaylist, fController); @@ -217,7 +217,7 @@ MainWin::~MainWin() if (fPlaylistWindow && fPlaylistWindow->Lock()) fPlaylistWindow->Quit(); - + delete fPlaylist; // quit the Controller looper thread @@ -275,7 +275,7 @@ MainWin::FrameResized(float newWidth, float newHeight) fVideoView->Show(); y += maxVideoHeight; } - + if (noControls) { if (!fControls->IsHidden()) fControls->Hide(); @@ -325,14 +325,14 @@ MainWin::DispatchMessage(BMessage *msg, BHandler *handler) fVideoView->OverlayScreenshotCleanup(); return; } - + // every other key gets dispatched to our _KeyDown first if (_KeyDown(msg) == B_OK) { // it got handled, don't pass it on return; } } - + BWindow::DispatchMessage(msg, handler); } @@ -501,7 +501,7 @@ MainWin::MessageReceived(BMessage *msg) case M_FILE_CLOSE: PostMessage(B_QUIT_REQUESTED); break; - case M_FILE_QUIT: + case M_FILE_QUIT: be_app->PostMessage(B_QUIT_REQUESTED); break; @@ -512,19 +512,19 @@ MainWin::MessageReceived(BMessage *msg) case M_TOGGLE_NO_MENU: _ToggleNoMenu(); break; - + case M_TOGGLE_NO_CONTROLS: _ToggleNoControls(); break; - + case M_TOGGLE_NO_BORDER: _ToggleNoBorder(); break; - + case M_TOGGLE_ALWAYS_ON_TOP: _ToggleAlwaysOnTop(); break; - + case M_TOGGLE_KEEP_ASPECT_RATIO: _ToggleKeepAspectRatio(); break; @@ -540,7 +540,7 @@ MainWin::MessageReceived(BMessage *msg) _ToggleFullscreen(); _ResizeWindow(50); break; - + case M_VIEW_100: if (!fHasVideo) break; @@ -572,17 +572,17 @@ MainWin::MessageReceived(BMessage *msg) _ToggleFullscreen(); _ResizeWindow(400); break; -/* +/* case B_ACQUIRE_OVERLAY_LOCK: printf("B_ACQUIRE_OVERLAY_LOCK\n"); fVideoView->OverlayLockAcquire(); break; - + case B_RELEASE_OVERLAY_LOCK: printf("B_RELEASE_OVERLAY_LOCK\n"); fVideoView->OverlayLockRelease(); break; -*/ +*/ case B_MOUSE_WHEEL_CHANGED: { float dx = msg->FindFloat("be:wheel_delta_x"); @@ -639,7 +639,7 @@ MainWin::MessageReceived(BMessage *msg) VideoFormatChange(544, 576, 1.41176, 1.0); break; -/* +/* default: if (msg->what >= M_SELECT_CHANNEL && msg->what <= M_SELECT_CHANNEL_END) { @@ -665,9 +665,7 @@ MainWin::MessageReceived(BMessage *msg) // the global settings instance... _AdoptGlobalSettings(); break; - case M_FILE_DELETE: - fControls->SkipForwardAndDelete(); - break; + default: // let BWindow handle the rest BWindow::MessageReceived(msg); @@ -689,16 +687,16 @@ MainWin::WindowActivated(bool active) // we will move it so all the window is on the screen. if (frame.right > screenFrame.right) // Move left - diffX = screenFrame.right - frame.right; + diffX = screenFrame.right - frame.right; if (frame.bottom > screenFrame.bottom) // Move up - diffY = screenFrame.bottom - frame.bottom; + diffY = screenFrame.bottom - frame.bottom; if (frame.left < screenFrame.left) // Move right - diffX = screenFrame.left - frame.left; + diffX = screenFrame.left - frame.left; if (frame.top < screenFrame.top) // Move down - diffY = screenFrame.top - frame.top; + diffY = screenFrame.top - frame.top; MoveBy(diffX, diffY); } @@ -731,7 +729,7 @@ MainWin::OpenFile(const entry_ref &ref) message << "The file '"; message << ref.name; message << "' could not be opened.\n\n"; - + if (err == B_MEDIA_NO_HANDLER) { // give a more detailed message for the most likely of all // errors @@ -794,7 +792,7 @@ MainWin::VideoFormatChange(int width, int height, float width_scale, float height_scale) { // called when video format or aspect ratio changes - + printf("VideoFormatChange enter: width %d, height %d, width_scale %.6f, " "height_scale %.6f\n", width, height, width_scale, height_scale); @@ -804,12 +802,12 @@ MainWin::VideoFormatChange(int width, int height, float width_scale, printf("inverting! new values: width_scale %.6f, height_scale %.6f\n", width_scale, height_scale); } - + fSourceWidth = width; fSourceHeight = height; fWidthScale = width_scale; fHeightScale = height_scale; - + FrameResized(Bounds().Width(), Bounds().Height()); printf("VideoFormatChange leave\n"); @@ -838,7 +836,7 @@ MainWin::_RefsReceived(BMessage* msg) void MainWin::_SetupWindow() { -// printf("MainWin::_SetupWindow\n"); +// printf("MainWin::_SetupWindow\n"); // Populate the track menus _SetupTrackMenus(); // Enable both if a file was loaded @@ -900,7 +898,7 @@ MainWin::_CreateMenu() // Add recent files BRecentFilesList recentFiles(10, false, NULL, kAppSig); BMenuItem *item = new BMenuItem(recentFiles.NewFileListMenu( - "Open File"B_UTF8_ELLIPSIS, new BMessage(B_REFS_RECEIVED), + "Open File"B_UTF8_ELLIPSIS, new BMessage(B_REFS_RECEIVED), NULL, this, 10, false, NULL, 0, kAppSig), new BMessage(M_FILE_OPEN)); item->SetShortcut('O', 0); fFileMenu->AddItem(item); @@ -979,9 +977,9 @@ MainWin::_SetupTrackMenus() { fAudioTrackMenu->RemoveItems(0, fAudioTrackMenu->CountItems(), true); fVideoTrackMenu->RemoveItems(0, fVideoTrackMenu->CountItems(), true); - + char s[100]; - + int count = fController->AudioTrackCount(); int current = fController->CurrentAudioTrack(); for (int i = 0; i < count; i++) { @@ -1021,7 +1019,7 @@ MainWin::_SetWindowSizeLimits() minWidth = max_c(minWidth, fMenuBarWidth); int minHeight = (fNoMenu ? 0 : fMenuBarHeight) + (fNoControls ? 0 : fControlsHeight); - + SetSizeLimits(minWidth - 1, 32000, minHeight - 1, fHasVideo ? 32000 : minHeight - 1); } @@ -1033,10 +1031,10 @@ MainWin::_ResizeWindow(int percent) // Get required window size int videoWidth = lround(fSourceWidth * fWidthScale); int videoHeight = lround(fSourceHeight * fHeightScale); - + videoWidth = (videoWidth * percent) / 100; videoHeight = (videoHeight * percent) / 100; - + // Calculate and set the initial window size int width = max_c(fControlsWidth, videoWidth); int height = (fNoControls ? 0 : fControlsHeight) + videoHeight; @@ -1054,7 +1052,7 @@ MainWin::_ResizeVideoView(int x, int y, int width, int height) { printf("_ResizeVideoView: %d,%d, width %d, height %d\n", x, y, width, height); - + if (fKeepAspectRatio) { // Keep aspect ratio, place video view inside // the background area (may create black bars). @@ -1111,7 +1109,7 @@ MainWin::_MouseDown(BMessage *msg, BView* originalHandler) return; } } - + if (2 == buttons && msg->FindInt32("clicks") % 2 == 0) { BRect r(screen_where.x - 1, screen_where.y - 1, screen_where.x + 1, screen_where.y + 1); @@ -1143,7 +1141,7 @@ MainWin::_MouseDown(BMessage *msg, BView* originalHandler) bigtime_t start = system_time(); bigtime_t delay = 200000; BPoint location; - do { + do { fVideoView->GetMouse(&location, &buttons); if ((buttons & 2) == 0) break; @@ -1162,9 +1160,9 @@ MainWin::_MouseMoved(BMessage *msg, BView* originalHandler) BPoint mousePos; uint32 buttons = msg->FindInt32("buttons"); - + if (1 == buttons && fMouseDownTracking && !fIsFullscreen) { -/* +/* // very broken in Zeta: BPoint mousePos = msg->FindPoint("where"); printf("view where: %.0f, %.0f => ", mousePos.x, mousePos.y); @@ -1259,14 +1257,14 @@ status_t MainWin::_KeyDown(BMessage *msg) { // msg->PrintToStream(); - + uint32 key = msg->FindInt32("key"); uint32 raw_char = msg->FindInt32("raw_char"); uint32 modifier = msg->FindInt32("modifiers"); - + printf("key 0x%lx, raw_char 0x%lx, modifiers 0x%lx\n", key, raw_char, modifier); - + switch (raw_char) { case B_SPACE: fController->TogglePlaying(); @@ -1285,7 +1283,7 @@ MainWin::_KeyDown(BMessage *msg) return B_OK; } else break; - + case B_TAB: if ((modifier & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY | B_MENU_KEY)) == 0) { @@ -1293,7 +1291,7 @@ MainWin::_KeyDown(BMessage *msg) return B_OK; } else break; - + case B_UP_ARROW: if (modifier & B_COMMAND_KEY) { PostMessage(M_SKIP_NEXT); @@ -1309,7 +1307,7 @@ MainWin::_KeyDown(BMessage *msg) PostMessage(M_VOLUME_DOWN); } return B_OK; - + case B_RIGHT_ARROW: if (modifier & B_COMMAND_KEY) { PostMessage(M_VOLUME_UP); @@ -1329,7 +1327,7 @@ MainWin::_KeyDown(BMessage *msg) case B_PAGE_UP: PostMessage(M_SKIP_NEXT); return B_OK; - + case B_PAGE_DOWN: PostMessage(M_SKIP_PREV); return B_OK; @@ -1359,26 +1357,27 @@ MainWin::_KeyDown(BMessage *msg) case 0x59: // numeric keypad down arrow PostMessage(M_VOLUME_DOWN); return B_OK; - + case 0x39: // numeric keypad page up case 0x4a: // numeric keypad right arrow PostMessage(M_SKIP_NEXT); return B_OK; - + case 0x5a: // numeric keypad page down case 0x48: // numeric keypad left arrow PostMessage(M_SKIP_PREV); return B_OK; - case 0x34: //delete button - case 0x3e: //d for delete - case 0x2b: //t for Trash - if (modifiers() & B_COMMAND_KEY) { - PostMessage(M_FILE_DELETE); - return B_OK; - } - break; +// TODO: Reenable this and use Undo/Redo stack... +// case 0x34: //delete button +// case 0x3e: //d for delete +// case 0x2b: //t for Trash +// if (modifiers() & B_COMMAND_KEY) { +// PostMessage(M_FILE_DELETE); +// return B_OK; +// } +// break; } - + return B_ERROR; } @@ -1415,10 +1414,10 @@ MainWin::_ToggleFullscreen() } fIsFullscreen = !fIsFullscreen; - + if (fIsFullscreen) { // switch to fullscreen - + fSavedFrame = Frame(); printf("saving current frame: %d %d %d %d\n", int(fSavedFrame.left), int(fSavedFrame.top), int(fSavedFrame.right), @@ -1451,7 +1450,7 @@ MainWin::_ToggleNoControls() printf("_ToggleNoControls enter\n"); if (fIsFullscreen) { - // fullscreen is always without menu + // fullscreen is always without menu printf("_ToggleNoControls leave, doing nothing, we are fullscreen\n"); return; } @@ -1476,7 +1475,7 @@ MainWin::_ToggleNoMenu() printf("_ToggleNoMenu enter\n"); if (fIsFullscreen) { - // fullscreen is always without menu + // fullscreen is always without menu printf("_ToggleNoMenu leave, doing nothing, we are fullscreen\n"); return; } diff --git a/src/apps/mediaplayer/playlist/ListViews.cpp b/src/apps/mediaplayer/playlist/ListViews.cpp index dc8d47dbc7..a42851af8a 100644 --- a/src/apps/mediaplayer/playlist/ListViews.cpp +++ b/src/apps/mediaplayer/playlist/ListViews.cpp @@ -264,12 +264,12 @@ DragSortableListView::InitiateDrag( BPoint point, int32 index, bool ) v->SetHighColor( 0, 0, 0, 255 ); v->StrokeRect( v->Bounds() ); v->Sync(); - + uint8 *bits = (uint8 *)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); - + if (fade) { for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) { uint8 *line = bits + 3; @@ -395,7 +395,7 @@ DragSortableListView::KeyDown( const char* bytes, int32 numBytes ) { if ( numBytes < 1 ) return; - + if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) ) RemoveSelected(); @@ -569,7 +569,7 @@ DragSortableListView::SetDropTargetRect(const BMessage* message, BPoint where) // offset where by half of item height r = ItemFrame(0); where.y += r.Height() / 2.0; - + int32 index = IndexOf(where); if (index < 0) index = CountItems(); @@ -627,7 +627,7 @@ DragSortableListView::ScrollTo(int32 index) // MoveItems void -DragSortableListView::MoveItems(BList& indices, int32 index) +DragSortableListView::MoveItems(const BList& indices, int32 index) { DeselectAll(); // we remove the items while we look at them, the insertion index is decreased @@ -659,7 +659,7 @@ DragSortableListView::MoveItems(BList& indices, int32 index) // CopyItems void -DragSortableListView::CopyItems(BList& indices, int32 toIndex) +DragSortableListView::CopyItems(const BList& indices, int32 toIndex) { DeselectAll(); // by inserting the items after we copied all items first, we avoid @@ -689,7 +689,7 @@ DragSortableListView::CopyItems(BList& indices, int32 toIndex) // RemoveItemList void -DragSortableListView::RemoveItemList(BList& indices) +DragSortableListView::RemoveItemList(const BList& indices) { int32 count = indices.CountItems(); for (int32 i = 0; i < count; i++) { @@ -698,11 +698,10 @@ DragSortableListView::RemoveItemList(BList& indices) } } -// RemoveSelected +// GetSelectedItems void -DragSortableListView::RemoveSelected() +DragSortableListView::GetSelectedItems(BList& indices) { - BList indices; for (int32 i = 0; true; i++) { int32 index = CurrentSelection(i); if (index < 0) @@ -710,6 +709,14 @@ DragSortableListView::RemoveSelected() if (!indices.AddItem((void*)index)) break; } +} + +// RemoveSelected +void +DragSortableListView::RemoveSelected() +{ + BList indices; + GetSelectedItems(indices); DeselectAll(); diff --git a/src/apps/mediaplayer/playlist/ListViews.h b/src/apps/mediaplayer/playlist/ListViews.h index 2f7f077ec8..493b68402c 100644 --- a/src/apps/mediaplayer/playlist/ListViews.h +++ b/src/apps/mediaplayer/playlist/ListViews.h @@ -89,9 +89,11 @@ class DragSortableListView : public BListView { bool MouseWheelChanged(float x, float y); - virtual void MoveItems(BList& indices, int32 toIndex); - virtual void CopyItems(BList& indices, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void MoveItems(const BList& indices, int32 toIndex); + virtual void CopyItems(const BList& indices, int32 toIndex); + virtual void RemoveItemList(const BList& indices); + + void GetSelectedItems(BList& indices); void RemoveSelected(); // uses RemoveItemList() void RemoveAll(); // uses RemoveItemList() int32 CountSelectedItems() const; diff --git a/src/apps/mediaplayer/playlist/Playlist.cpp b/src/apps/mediaplayer/playlist/Playlist.cpp index 9863bdcad4..22c1cce3ef 100644 --- a/src/apps/mediaplayer/playlist/Playlist.cpp +++ b/src/apps/mediaplayer/playlist/Playlist.cpp @@ -288,18 +288,6 @@ Playlist::RemoveRef(int32 index, bool careAboutCurrentIndex) } -void -Playlist::RemoveRefPermanent(int32 index, bool removeToTrash) -{ - if (index != -1) { - entry_ref song = RemoveRef(index); - - if(removeToTrash) - _DeleteEntry(&song);//Remove with tracker - } -} - - int32 Playlist::IndexOf(const entry_ref& _ref) const { @@ -455,7 +443,7 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist) BEntry entry(&ref, true); if (entry.InitCheck() < B_OK || !entry.Exists()) return; - + if (entry.IsDirectory()) { BDirectory dir(&entry); if (dir.InitCheck() < B_OK) @@ -490,8 +478,8 @@ Playlist::AppendPlaylistToPlaylist(const entry_ref& ref, Playlist* playlist) FileReadWrite lineReader(&file); BString str; - entry_ref refPath; - status_t err; + entry_ref refPath; + status_t err; BPath path; while (lineReader.Next(str)) { str = str.RemoveFirst("file://"); @@ -501,7 +489,7 @@ Playlist::AppendPlaylistToPlaylist(const entry_ref& ref, Playlist* playlist) if (path.Path() != NULL) { if ((err = get_ref_for_path(path.Path(), &refPath)) == B_OK) { playlist->AddRef(refPath); - } else + } else printf("Error - %s: [%lx]\n", strerror(err), (int32) err); } else printf("Error - No File Found in playlist\n"); @@ -536,7 +524,7 @@ Playlist::playlist_cmp(const void *p1, const void *p2) Playlist::_IsMediaFile(const BString& mimeString) { BMimeType superType; - BMimeType fileType(mimeString.String()); + BMimeType fileType(mimeString.String()); if (fileType.GetSupertype(&superType) != B_OK) return false; @@ -550,21 +538,21 @@ Playlist::_IsMediaFile(const BString& mimeString) /*static*/ bool Playlist::_IsTextPlaylist(const BString& mimeString) -{ +{ return mimeString.Compare(kTextPlaylistMimeString) == 0; } /*static*/ bool Playlist::_IsBinaryPlaylist(const BString& mimeString) -{ +{ return mimeString.Compare(kBinaryPlaylistMimeString) == 0; } /*static*/ bool Playlist::_IsPlaylist(const BString& mimeString) -{ +{ return _IsTextPlaylist(mimeString) || _IsBinaryPlaylist(mimeString); } @@ -583,18 +571,7 @@ Playlist::_MIMEString(const entry_ref* ref) strlcpy(mimeString, type.Type(), B_MIME_TYPE_LENGTH); nodeInfo.SetType(type.Type()); } - return BString(mimeString); -} - - -void -Playlist::_DeleteEntry(const entry_ref* file) -{ - // Move entry_ref to Trash - BMessage trash(BPrivate::kMoveToTrash); - trash.AddRef("refs", file); - - BMessenger("application/x-vnd.Be-TRAK").SendMessage(&trash); + return BString(mimeString); } diff --git a/src/apps/mediaplayer/playlist/Playlist.h b/src/apps/mediaplayer/playlist/Playlist.h index 13c9123a13..7efdc06e0e 100644 --- a/src/apps/mediaplayer/playlist/Playlist.h +++ b/src/apps/mediaplayer/playlist/Playlist.h @@ -68,9 +68,6 @@ public: entry_ref RemoveRef(int32 index, bool careAboutCurrentIndex = true); - void RemoveRefPermanent(int32 index, - bool removeToTrash); - bool AdoptPlaylist(Playlist& other); bool AdoptPlaylist(Playlist& other, int32 index); @@ -81,7 +78,7 @@ public: // navigating current ref bool SetCurrentRefIndex(int32 index); int32 CurrentRefIndex() const; - + void GetSkipInfo(bool* canSkipPrevious, bool* canSkipNext) const; @@ -89,7 +86,7 @@ public: bool AddListener(Listener* listener); void RemoveListener(Listener* listener); - // support functions + // support functions void AppendRefs(const BMessage* refsReceivedMessage, int32 appendIndex = -1); static void AppendToPlaylistRecursive(const entry_ref& ref, @@ -103,8 +100,7 @@ private: static bool _IsTextPlaylist(const BString& mimeString); static bool _IsBinaryPlaylist(const BString& mimeString); static bool _IsPlaylist(const BString& mimeString); - static BString _MIMEString(const entry_ref* entry); - void _DeleteEntry(const entry_ref* file); + static BString _MIMEString(const entry_ref* ref); void _NotifyRefAdded(const entry_ref& ref, int32 index) const; void _NotifyRefRemoved(int32 index) const; diff --git a/src/apps/mediaplayer/playlist/PlaylistListView.cpp b/src/apps/mediaplayer/playlist/PlaylistListView.cpp index 2e529b6806..e08f2fa9c7 100644 --- a/src/apps/mediaplayer/playlist/PlaylistListView.cpp +++ b/src/apps/mediaplayer/playlist/PlaylistListView.cpp @@ -358,7 +358,7 @@ PlaylistListView::KeyDown(const char* bytes, int32 numBytes) { if (numBytes < 1) return; - + if ((bytes[0] == B_BACKSPACE) || (bytes[0] == B_DELETE)) RemoveSelected(); @@ -367,7 +367,7 @@ PlaylistListView::KeyDown(const char* bytes, int32 numBytes) void -PlaylistListView::MoveItems(BList& indices, int32 toIndex) +PlaylistListView::MoveItems(const BList& indices, int32 toIndex) { fCommandStack->Perform(new (nothrow) MovePLItemsCommand(fPlaylist, (int32*)indices.Items(), indices.CountItems(), toIndex)); @@ -375,7 +375,7 @@ PlaylistListView::MoveItems(BList& indices, int32 toIndex) void -PlaylistListView::CopyItems(BList& indices, int32 toIndex) +PlaylistListView::CopyItems(const BList& indices, int32 toIndex) { fCommandStack->Perform(new (nothrow) CopyPLItemsCommand(fPlaylist, (int32*)indices.Items(), indices.CountItems(), toIndex)); @@ -383,7 +383,7 @@ PlaylistListView::CopyItems(BList& indices, int32 toIndex) void -PlaylistListView::RemoveItemList(BList& indices) +PlaylistListView::RemoveItemList(const BList& indices) { fCommandStack->Perform(new (nothrow) RemovePLItemsCommand(fPlaylist, (int32*)indices.Items(), indices.CountItems())); @@ -444,12 +444,12 @@ PlaylistListView::Randomize() void -PlaylistListView::PermanentRemoveSelectedFile(bool permRemove) +PlaylistListView::RemoveSelectionToTrash() { - BAutolock _(fPlaylist); - int32 index = fPlaylist->CurrentRefIndex(); - fPlaylist->SetCurrentRefIndex(index + 1); - fPlaylist->RemoveRefPermanent(index, permRemove); + BList indices; + GetSelectedItems(indices); + fCommandStack->Perform(new (nothrow) RemovePLItemsCommand(fPlaylist, + (int32*)indices.Items(), indices.CountItems(), true)); } diff --git a/src/apps/mediaplayer/playlist/PlaylistListView.h b/src/apps/mediaplayer/playlist/PlaylistListView.h index dbbfa56adc..762af204b7 100644 --- a/src/apps/mediaplayer/playlist/PlaylistListView.h +++ b/src/apps/mediaplayer/playlist/PlaylistListView.h @@ -33,9 +33,9 @@ class PlaylistListView : public SimpleListView { virtual void KeyDown(const char* bytes, int32 numBytes); // SimpleListView interface - virtual void MoveItems(BList& indices, int32 toIndex); - virtual void CopyItems(BList& indices, int32 toIndex); - virtual void RemoveItemList(BList& indices); + virtual void MoveItems(const BList& indices, int32 toIndex); + virtual void CopyItems(const BList& indices, int32 toIndex); + virtual void RemoveItemList(const BList& indices); virtual void DrawListItem(BView* owner, int32 index, BRect frame) const; @@ -45,7 +45,7 @@ class PlaylistListView : public SimpleListView { int32 appendIndex); void Randomize(); - void PermanentRemoveSelectedFile(bool permRemove); + void RemoveSelectionToTrash(); private: void _FullSync(); diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.cpp b/src/apps/mediaplayer/playlist/PlaylistWindow.cpp index 416e60af61..972f0c0982 100644 --- a/src/apps/mediaplayer/playlist/PlaylistWindow.cpp +++ b/src/apps/mediaplayer/playlist/PlaylistWindow.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2008, Haiku. All rights reserved. + * Copyright 2007-2009, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -46,18 +46,17 @@ enum { // file - M_PLAYLIST_OPEN = 'open', - M_PLAYLIST_SAVE = 'save', - M_PLAYLIST_SAVE_AS = 'svas', - M_PLAYLIST_SAVE_RESULT = 'psrs', + M_PLAYLIST_OPEN = 'open', + M_PLAYLIST_SAVE = 'save', + M_PLAYLIST_SAVE_AS = 'svas', + M_PLAYLIST_SAVE_RESULT = 'psrs', // edit - M_PLAYLIST_EMPTY = 'emty', - M_PLAYLIST_RANDOMIZE = 'rand', - - // - M_PLAYLIST_DELETE_FILE = 'dlfi', - M_PLAYLIST_PER_DEL_FILE = 'pdfi' + M_PLAYLIST_EMPTY = 'emty', + M_PLAYLIST_RANDOMIZE = 'rand', + + M_PLAYLIST_REMOVE = 'rmov', + M_PLAYLIST_REMOVE_AND_PUT_INTO_TRASH = 'rmtr' }; #define SPACE 5 @@ -195,11 +194,11 @@ PlaylistWindow::MessageReceived(BMessage* message) case M_PLAYLIST_RANDOMIZE: fListView->Randomize(); break; - case M_PLAYLIST_DELETE_FILE: - fListView->PermanentRemoveSelectedFile(false); - break; - case M_PLAYLIST_PER_DEL_FILE: - fListView->PermanentRemoveSelectedFile(true); + case M_PLAYLIST_REMOVE: + fListView->RemoveSelected(); + break; + case M_PLAYLIST_REMOVE_AND_PUT_INTO_TRASH: + fListView->RemoveSelectionToTrash(); break; default: BWindow::MessageReceived(message); @@ -208,35 +207,6 @@ PlaylistWindow::MessageReceived(BMessage* message) } -void -PlaylistWindow::DispatchMessage(BMessage *message, BHandler *handler) -{ - if (message->what == B_KEY_DOWN) { - - uint32 key = message->FindInt32("key"); - - switch (key) { - case 0x34: //delete button - case 0x3e: //d for delete - case 0x2b: //t for Trash - if (modifiers() & B_COMMAND_KEY) { - fListView->PermanentRemoveSelectedFile(true); - return; - } - break; - case 0x2a: //r for Remove - if (modifiers() & B_COMMAND_KEY) { - fListView->PermanentRemoveSelectedFile(false); - return; - } - break; - } - } - - BWindow::DispatchMessage(message, handler); -} - - // #pragma mark - @@ -268,10 +238,10 @@ PlaylistWindow::_CreateMenu(BRect& frame) editMenu->AddItem(new BMenuItem("Randomize", new BMessage(M_PLAYLIST_RANDOMIZE), 'R')); editMenu->AddSeparatorItem(); - editMenu->AddItem(new BMenuItem("Remove", - new BMessage(M_PLAYLIST_DELETE_FILE), 'R')); - editMenu->AddItem(new BMenuItem("Remove Permanent", - new BMessage(M_PLAYLIST_PER_DEL_FILE), 'T', B_COMMAND_KEY)); + editMenu->AddItem(new BMenuItem("Remove (Del)", + new BMessage(M_PLAYLIST_REMOVE)/*, B_DELETE, 0*/)); + editMenu->AddItem(new BMenuItem("Remove and Put into Trash", + new BMessage(M_PLAYLIST_REMOVE_AND_PUT_INTO_TRASH), 'T')); editMenu->AddItem(new BMenuItem("Remove All", new BMessage(M_PLAYLIST_EMPTY), 'N')); diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.h b/src/apps/mediaplayer/playlist/PlaylistWindow.h index 40d5829882..fd65b76057 100644 --- a/src/apps/mediaplayer/playlist/PlaylistWindow.h +++ b/src/apps/mediaplayer/playlist/PlaylistWindow.h @@ -6,7 +6,7 @@ * Stephan Aßmus * Fredrik Modéen */ - + #ifndef PLAYLIST_WINDOW_H #define PLAYLIST_WINDOW_H @@ -36,7 +36,6 @@ public: virtual bool QuitRequested(); virtual void MessageReceived(BMessage* message); - virtual void DispatchMessage(BMessage *msg, BHandler *handler); private: void _CreateMenu(BRect& frame); diff --git a/src/apps/mediaplayer/playlist/RemovePLItemsCommand.cpp b/src/apps/mediaplayer/playlist/RemovePLItemsCommand.cpp index 46228068c1..b446b1f44c 100644 --- a/src/apps/mediaplayer/playlist/RemovePLItemsCommand.cpp +++ b/src/apps/mediaplayer/playlist/RemovePLItemsCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007, Haiku. All rights reserved. + * Copyright 2007-2009, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -11,7 +11,12 @@ #include #include +#include #include +#include +#include +#include +#include #include "Playlist.h" @@ -20,12 +25,16 @@ using std::nothrow; RemovePLItemsCommand::RemovePLItemsCommand(Playlist* playlist, - const int32* indices, int32 count) - : Command() - , fPlaylist(playlist) - , fRefs(count > 0 ? new (nothrow) entry_ref[count] : NULL) - , fIndices(count > 0 ? new (nothrow) int32[count] : NULL) - , fCount(count) + const int32* indices, int32 count, bool moveFilesToTrash) + : + Command(), + fPlaylist(playlist), + fRefs(count > 0 ? new (nothrow) entry_ref[count] : NULL), + fNamesInTrash(NULL), + fIndices(count > 0 ? new (nothrow) int32[count] : NULL), + fCount(count), + fMoveFilesToTrash(moveFilesToTrash), + fMoveErrorShown(false) { if (!indices || !fPlaylist || !fRefs || !fIndices) { // indicate a bad object state @@ -36,6 +45,12 @@ RemovePLItemsCommand::RemovePLItemsCommand(Playlist* playlist, memcpy(fIndices, indices, fCount * sizeof(int32)); + if (fMoveFilesToTrash) { + fNamesInTrash = new (nothrow) BString[count]; + if (fNamesInTrash == NULL) + return; + } + // init original entry indices for (int32 i = 0; i < fCount; i++) { if (fPlaylist->GetRefAt(fIndices[i], &fRefs[i]) < B_OK) { @@ -51,14 +66,17 @@ RemovePLItemsCommand::~RemovePLItemsCommand() { delete[] fRefs; delete[] fIndices; + delete[] fNamesInTrash; } status_t RemovePLItemsCommand::InitCheck() { - if (!fPlaylist || !fRefs || !fIndices) + if (!fPlaylist || !fRefs || !fIndices + || (fMoveFilesToTrash && !fNamesInTrash)) { return B_NO_INIT; + } return B_OK; } @@ -81,6 +99,71 @@ RemovePLItemsCommand::Perform() if (fPlaylist->CurrentRefIndex() == -1) fPlaylist->SetCurrentRefIndex(lastRemovedIndex); + if (fMoveFilesToTrash) { + BString errorFiles; + status_t moveError = B_OK; + bool errorOnAllFiles = true; + char trashPath[B_PATH_NAME_LENGTH]; + for (int32 i = 0; i < fCount; i++) { + status_t err = find_directory(B_TRASH_DIRECTORY, fRefs[i].device, + true /*create it*/, trashPath, B_PATH_NAME_LENGTH); + if (err != B_OK) { + fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); + continue; + } + + BEntry entry(&fRefs[i]); + err = entry.InitCheck(); + if (err != B_OK) { + fprintf(stderr, "failed to init BEntry for %s: %s\n", + fRefs[i].name, strerror(err)); + continue; + } + BDirectory trashDir(trashPath); + if (err != B_OK) { + fprintf(stderr, "failed to init BDirectory for %s: %s\n", + trashPath, strerror(err)); + continue; + } + + // Find a unique name for the entry in the trash + fNamesInTrash[i] = fRefs[i].name; + int32 uniqueNameIndex = 1; + while (true) { + BEntry test(&trashDir, fNamesInTrash[i].String()); + if (!test.Exists()) + break; + fNamesInTrash[i] = fRefs[i].name; + fNamesInTrash[i] << ' ' << uniqueNameIndex; + uniqueNameIndex++; + } + + // Finally, move the entry into the trash + err = entry.MoveTo(&trashDir, fNamesInTrash[i].String()); + if (err != B_OK) { + moveError = err; + if (errorFiles.Length() > 0) + errorFiles << ' '; + errorFiles << fRefs[i].name; + } else + errorOnAllFiles = false; + } + // Show an error alert if necessary + if (!fMoveErrorShown && moveError != B_OK) { + fMoveErrorShown = true; + BString message; + if (errorOnAllFiles) + message << "All "; + else + message << "Some "; + message << "files could not be moved into the Trash.\n\n"; + message << "Error: " << strerror(moveError); + (new BAlert("Move Into Trash Error", message.String(), + "Ok", NULL, NULL, B_WIDTH_AS_USUAL, + B_WARNING_ALERT))->Go(NULL); + } + } + return B_OK; } @@ -92,6 +175,51 @@ RemovePLItemsCommand::Undo() status_t ret = B_OK; + if (fMoveFilesToTrash) { + char trashPath[B_PATH_NAME_LENGTH]; + for (int32 i = 0; i < fCount; i++) { + status_t err = find_directory(B_TRASH_DIRECTORY, fRefs[i].device, + false /*create it*/, trashPath, B_PATH_NAME_LENGTH); + if (err != B_OK) { + fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); + continue; + } + // construct the entry to the file in the trash +// TODO: BEntry(const BDirectory* directory, const char* path) is broken! +// BEntry entry(trashPath, fNamesInTrash[i].String()); +BPath path(trashPath, fNamesInTrash[i].String()); +BEntry entry(path.Path()); + err = entry.InitCheck(); + if (err != B_OK) { + fprintf(stderr, "failed to init BEntry for %s: %s\n", + fNamesInTrash[i].String(), strerror(err)); + continue; + } +//entry.GetPath(&path); +//printf("moving '%s'\n", path.Path()); + + // construct the folder of the original entry_ref + node_ref nodeRef; + nodeRef.device = fRefs[i].device; + nodeRef.node = fRefs[i].directory; + BDirectory originalDir(&nodeRef); + + if (err != B_OK) { + fprintf(stderr, "failed to init original BDirectory for " + "%s: %s\n", fRefs[i].name, strerror(err)); + continue; + } + +//path.SetTo(&originalDir, fRefs[i].name); +//printf("as '%s'\n", path.Path()); + + // Finally, move the entry back into the original folder + err = entry.MoveTo(&originalDir, fRefs[i].name); + if (err != B_OK) + ret = err; + } + } + // remember currently playling ref in case we move it entry_ref currentRef; bool adjustCurrentRef = fPlaylist->GetRefAt(fPlaylist->CurrentRefIndex(), @@ -122,4 +250,7 @@ RemovePLItemsCommand::GetName(BString& name) name << "Remove Entries"; else name << "Remove Entry"; + + if (fMoveFilesToTrash) + name << " into Trash"; } diff --git a/src/apps/mediaplayer/playlist/RemovePLItemsCommand.h b/src/apps/mediaplayer/playlist/RemovePLItemsCommand.h index 013130ac72..b7870fd4f7 100644 --- a/src/apps/mediaplayer/playlist/RemovePLItemsCommand.h +++ b/src/apps/mediaplayer/playlist/RemovePLItemsCommand.h @@ -1,5 +1,5 @@ /* - * Copyright 2007, Haiku. All rights reserved. + * Copyright 2007-2009, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -11,17 +11,18 @@ #include "Command.h" -class Playlist; struct entry_ref; +class Playlist; class RemovePLItemsCommand : public Command { public: RemovePLItemsCommand( Playlist* playlist, const int32* indices, - int32 count); + int32 count, + bool moveFilesToTrash = false); virtual ~RemovePLItemsCommand(); - + virtual status_t InitCheck(); virtual status_t Perform(); @@ -32,8 +33,11 @@ class RemovePLItemsCommand : public Command { private: Playlist* fPlaylist; entry_ref* fRefs; + BString* fNamesInTrash; int32* fIndices; int32 fCount; + bool fMoveFilesToTrash; + bool fMoveErrorShown; }; #endif // REMOVE_PL_ITEMS_COMMAND_H