MediaPlayer: Make location field clickable in File info window
The "Location" field in the File info window will be clickable if it
refers to a local file. This will open the containing folder in the Tracker.
Fixes #8842
Change-Id: I0b17587607275da12aac89a1716ec85652a31e29
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9796
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
Reviewed-by: nephele nephele <nep-git@packageloss.eu>
Diff
src/apps/mediaplayer/InfoWin.cpp | 17 +++++++++++++++++
src/apps/mediaplayer/InfoWin.h | 4 +++-
src/apps/mediaplayer/Jamfile | 1 +
src/apps/mediaplayer/interface/LocationStringView.cpp | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/apps/mediaplayer/interface/LocationStringView.h | 40 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 204 insertions(+), 2 deletions(-)
@@ -31,6 +31,7 @@
#include "Controller.h"
#include "ControllerObserver.h"
#include "LocationStringView.h"
#include "PlaylistItem.h"
@@ -208,7 +209,7 @@
BStringView* locationLabel = _CreateLabel("locationLabel",
B_TRANSLATE("Location"));
locationLabel->SetHighUIColor(B_PANEL_TEXT_COLOR);
fLocationInfo = _CreateInfo("location");
fLocationInfo = _CreateInfoLocation("location");
fCopyrightSeparator = _CreateSeparator();
fCopyrightLabel = _CreateLabel("copyrightLabel", B_TRANSLATE("Copyright"));
@@ -371,6 +372,7 @@
info = B_TRANSLATE("<unknown>");
fLocationInfo->SetText(info.String());
fLocationInfo->SetToolTip(info.String());
fLocationInfo->CheckAndSetStyleForLink();
if (fController->GetName(&info) != B_OK || info.IsEmpty())
info = B_TRANSLATE("<unnamed media>");
@@ -380,6 +382,7 @@
fFilenameView->SetText(B_TRANSLATE("<no media>"));
fContainerInfo->SetText("-");
fLocationInfo->SetText("-");
fLocationInfo->CheckAndSetStyleForLink();
}
if (!iconSet)
@@ -591,6 +594,18 @@
InfoWin::_CreateInfo(const char* name)
{
BStringView* view = new BStringView(name, "");
view->SetExplicitMinSize(BSize(200, B_SIZE_UNSET));
view->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
view->SetTruncation(B_TRUNCATE_SMART);
return view;
}
LocationStringView*
InfoWin::_CreateInfoLocation(const char* name)
{
LocationStringView* view = new LocationStringView(name, "");
view->SetExplicitMinSize(BSize(200, B_SIZE_UNSET));
view->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
view->SetTruncation(B_TRUNCATE_SMART);
@@ -18,6 +18,7 @@
class Controller;
class ControllerObserver;
class IconView;
class LocationStringView;
#define INFO_STATS 0x00000001
@@ -52,6 +53,7 @@
BStringView* _CreateLabel(const char* name,
const char* label);
BStringView* _CreateInfo(const char* name);
LocationStringView* _CreateInfoLocation(const char* name);
BLayoutItem* _CreateSeparator();
void _SetVisible(BView* view, bool visible);
@@ -74,7 +76,7 @@
BStringView* fAudioFormatInfo;
BStringView* fAudioConfigInfo;
BStringView* fDurationInfo;
BStringView* fLocationInfo;
LocationStringView* fLocationInfo;
BLayoutItem* fCopyrightSeparator;
BStringView* fCopyrightLabel;
BStringView* fCopyrightInfo;
@@ -28,6 +28,7 @@
Application [ MultiArchDefaultGristFiles MediaPlayer ] :
# interface
DurationView.cpp
LocationStringView.cpp
PeakView.cpp
PlayPauseButton.cpp
PositionToolTip.cpp
@@ -1,0 +1,144 @@
/*
* Copyright 2025, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Nathan Patrizi, nathan.patrizi@gmail.com
*/
#include "LocationStringView.h"
#include <Cursor.h>
#include <Entry.h>
#include <Font.h>
#include <Path.h>
#include <Roster.h>
#include <String.h>
#include <StringView.h>
LocationStringView::LocationStringView(const char* name, const char* text)
: BStringView(name, text)
{
fOriginalHighColor = HighColor();
fStyledAsLink = false;
}
void
LocationStringView::CheckAndSetStyleForLink()
{
_StyleAsLink(_IsFileLink());
}
void
LocationStringView::MouseDown(BPoint point)
{
if (fStyledAsLink) {
BMessenger tracker("application/x-vnd.Be-TRAK");
BMessage message(B_REFS_RECEIVED);
BEntry dirEntry(fFilePathParent.Path());
entry_ref dirRef;
dirEntry.GetRef(&dirRef);
BEntry entry(fFilePath.Path());
node_ref node;
entry.GetNodeRef(&node);
message.AddRef("refs", &dirRef);
message.AddData("nodeRefToSelect", B_RAW_TYPE, &node, sizeof(node_ref));
tracker.SendMessage(&message);
}
}
void
LocationStringView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage)
{
if (!fStyledAsLink)
return;
switch (transit) {
case B_ENTERED_VIEW:
_MouseOver();
break;
case B_EXITED_VIEW:
_MouseAway();
break;
}
}
void
LocationStringView::_MouseAway()
{
BCursor defaultCursor(B_CURSOR_ID_SYSTEM_DEFAULT);
SetViewCursor(&defaultCursor);
BFont font;
GetFont(&font);
font.SetFace(B_REGULAR_FACE);
SetFont(&font);
}
void
LocationStringView::_MouseOver()
{
BCursor linkCursor(B_CURSOR_ID_FOLLOW_LINK);
SetViewCursor(&linkCursor);
BFont font;
GetFont(&font);
font.SetFace(B_UNDERSCORE_FACE);
SetFont(&font);
}
bool
LocationStringView::_IsFileLink()
{
BString filePath(Text());
return filePath.StartsWith("file:");
}
void
LocationStringView::_StripFileProtocol()
{
BString filePath(Text());
filePath.RemoveFirst("file:");
if (filePath.StartsWith("///"))
filePath.RemoveFirst("//");
else if (filePath.StartsWith("//localhost/"))
filePath.RemoveFirst("//localhost");
fFilePath = filePath.String();
fFilePath.GetParent(&fFilePathParent);
SetText(fFilePathParent.Path());
SetToolTip(fFilePathParent.Path());
}
void
LocationStringView::_StyleAsLink(bool enableLinkStyle)
{
fStyledAsLink = enableLinkStyle;
if (enableLinkStyle) {
SetHighUIColor(B_LINK_TEXT_COLOR);
_StripFileProtocol();
} else {
SetHighColor(fOriginalHighColor);
_MouseAway();
}
}
@@ -1,0 +1,40 @@
/*
* Copyright 2025, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Nathan Patrizi, nathan.patrizi@gmail.com
*/
#ifndef LOCATION_STRING_VIEW_H
#define LOCATION_STRING_VIEW_H
#include <Path.h>
#include <StringView.h>
class LocationStringView : public BStringView {
public:
LocationStringView(const char* name, const char* text);
void MouseDown(BPoint point);
void MouseMoved(BPoint point, uint32 transit,
const BMessage* dragMessage);
void CheckAndSetStyleForLink();
private:
bool _IsFileLink();
void _StripFileProtocol();
void _StyleAsLink(bool set);
void _MouseAway();
void _MouseOver();
private:
BPath fFilePath;
BPath fFilePathParent;
rgb_color fOriginalHighColor;
bool fStyledAsLink;
};
#endif