Commit 71282d99 authored by Camilo Higuita's avatar Camilo Higuita

complete missing features: remove from playlist, delete playlist, sent to...

complete missing features: remove from playlist, delete playlist, sent to device kdeconnect, and few other improvements
parent 11ccf8c9
......@@ -25,6 +25,7 @@
#if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID))
#include "kde/notify.h"
#include "kde/kdeconnect.h"
#endif
using namespace BAE;
......@@ -503,7 +504,7 @@ QString Babe::homeDir()
#if defined(Q_OS_ANDROID)
QAndroidJniObject mediaDir = QAndroidJniObject::callStaticObjectMethod("android/os/Environment", "getExternalStorageDirectory", "()Ljava/io/File;");
QAndroidJniObject mediaPath = mediaDir.callObjectMethod( "getAbsolutePath", "()Ljava/lang/String;" );
// bDebug::Instance()->msg("HOMEDIR FROM ADNROID"+ mediaPath.toString());
// bDebug::Instance()->msg("HOMEDIR FROM ADNROID"+ mediaPath.toString());
if(BAE::fileExists("/mnt/extSdCard"))
return "/mnt/sdcard";
......@@ -687,6 +688,20 @@ QVariantList Babe::searchFor(const QStringList &queries)
return mapList;
}
QVariantList Babe::getDevices()
{
#if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID))
return KdeConnect::getDevices();
#endif
}
bool Babe::sendToDevice(const QString &name, const QString &id, const QString &url)
{
#if (defined (Q_OS_LINUX) && !defined (Q_OS_ANDROID))
return KdeConnect::sendToDevice(name, id, url) ? true : false;
#endif
}
void Babe::debug(const QString &msg)
{
emit this->message(msg);
......
......@@ -50,8 +50,7 @@ public:
Q_INVOKABLE bool babeTrack(const QString &path, const bool &value);
Q_INVOKABLE void notify(const QString &title, const QString &body);
Q_INVOKABLE void notifySong(const QString &url);
/* SETTINGS */
Q_INVOKABLE void scanDir(const QString &url);
......@@ -109,6 +108,12 @@ public:
Q_INVOKABLE QString loadCover(const QString &url);
Q_INVOKABLE QVariantList searchFor(const QStringList &queries);
/*KDE*/
Q_INVOKABLE static QVariantList getDevices();
Q_INVOKABLE static bool sendToDevice(const QString &name, const QString &id, const QString &url);
Q_INVOKABLE void notify(const QString &title, const QString &body);
Q_INVOKABLE void notifySong(const QString &url);
public slots:
void debug(const QString &msg);
......
......@@ -238,7 +238,7 @@ void CollectionDB::addTrack(const DB &track)
auto artwork = track[KEY::ARTWORK].isEmpty()? "" : track[KEY::ARTWORK];
qDebug()<< "writting to db: "<<title<<artist;
bDebug::Instance()->msg("Writting to db: "+title+" "+artist);
/* first needs to insert album and artist*/
QVariantMap sourceMap {{KEYMAP[KEY::URL],sourceUrl},
{KEYMAP[KEY::SOURCE_TYPE], sourceType(url)}};
......
......@@ -91,8 +91,8 @@ public:
Q_INVOKABLE QStringList getPlaylists();
bool removePlaylistTrack(const QString &url, const QString &playlist);
bool removePlaylist(const QString &playlist);
Q_INVOKABLE bool removePlaylistTrack(const QString &url, const QString &playlist);
Q_INVOKABLE bool removePlaylist(const QString &playlist);
bool removeArtist(const QString &artist);
bool cleanArtists();
bool removeAlbum(const QString &album, const QString &artist);
......
......@@ -19,4 +19,10 @@ linux:unix:!android {
}
HEADERS += \
$$PWD/kdeconnect.h
SOURCES += \
$$PWD/kdeconnect.cpp
#include "kdeconnect.h"
#include "../utils/babeconsole.h"
#include <QProcess>
KdeConnect::KdeConnect(QObject *parent) : QObject(parent)
{
}
QVariantList KdeConnect::getDevices()
{
QVariantList devices;
bDebug::Instance()->msg("Getting the kdeconnect devices avaliable");
QProcess process;
process.start("kdeconnect-cli -a");
process.waitForFinished();
// auto output = process->readAllStandardOutput();
process.setReadChannel(QProcess::StandardOutput);
while (process.canReadLine())
{
QString line = QString::fromLocal8Bit(process.readLine());
if(line.contains("(paired and reachable)"))
{
QVariantMap _devices;
QStringList items = line.split(" ");
auto key = QString(items.at(2));
auto name = QString(items.at(1)).replace(":","");
bDebug::Instance()->msg("Founded devices: "+key+" : "+name);
_devices.insert("key", key);
_devices.insert("name", name);
devices.append(_devices);
}
}
return devices;
}
bool KdeConnect::sendToDevice(const QString &device, const QString &id, const QString &url)
{
QString deviceName = device;
QString deviceKey = id;
bDebug::Instance()->msg("Trying to send "+url + " to : "+ deviceName);
auto process = new QProcess();
connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
[=](int exitCode, QProcess::ExitStatus exitStatus)
{
bDebug::Instance()->msg("ProcessFinished_totally"+exitCode+exitStatus);
// BabeWindow::nof->notify("Song sent to " + deviceName,title +" by "+ artist);
// process->deleteLater();
});
bDebug::Instance()->msg("kdeconnect-cli -d " +deviceKey+ " --share " + url);
process->start("kdeconnect-cli -d " +deviceKey+ " --share " +"\""+ url+"\"");
return true;
}
#ifndef KDECONNECT_H
#define KDECONNECT_H
#include <QObject>
#include <QMap>
#include <QString>
#include <QVariantList>
class KdeConnect : public QObject
{
Q_OBJECT
public:
explicit KdeConnect(QObject *parent = nullptr);
static QVariantList getDevices();
static bool sendToDevice(const QString &device, const QString &id, const QString &url);
signals:
public slots:
};
#endif // KDECONNECT_H
......@@ -44,12 +44,14 @@ Kirigami.ApplicationWindow
property var currentTrack : ({babe: "0", stars: "0"})
property int currentTrackIndex : 0
property int prevTrackIndex : 0
property string currentArtwork : mainPlaylist.table.count > 0 ? mainPlaylist.list.model.get(0).artwork : ""
property string currentArtwork : !mainlistEmpty ? mainPlaylist.list.model.get(0).artwork : ""
property bool currentBabe : currentTrack.babe == "0" ? false : true
property string durationTimeLabel : "00:00"
property string progressTimeLabel : "00:00"
property bool isPlaying : false
property bool autoplay : bae.loadSetting("AUTOPLAY", "BABE", false) === "true" ? true : false
property int onQueue : 0
/*THEMING*/
property string babeColor : bae.babeColor()
......@@ -107,18 +109,20 @@ Kirigami.ApplicationWindow
readonly property int headerHeight: rowHeight
readonly property int contentMargins : isMobile ? 8 : 10
readonly property var viewsIndex : ({
"babeit": 0,
"tracks" : 1,
"albums" : 2,
"artists" : 3,
"playlists" : 4,
"search" : 5
"tracks" : 0,
"albums" : 1,
"artists" : 2,
"playlists" : 3,
"search" : 4,
"babeit": 5,
})
property bool mainlistEmpty : !mainPlaylist.table.count > 0
/*PROPS*/
property int toolBarIconSize: bae.loadSetting("ICON_SIZE", "BABE", iconSizes.medium)
property int toolBarHeight : isMobile ? 48 : toolBarIconSize *2
property int miniArtSize : isMobile ? 40 : 34
property int columnWidth: Kirigami.Units.gridUnit * 18
property int coverSize: isMobile ? Math.sqrt(root.width*root.height)*0.4 : columnWidth * 0.65
......@@ -185,7 +189,7 @@ Kirigami.ApplicationWindow
Component.onCompleted:
{
if(isMobile) settingsDrawer.switchColorScheme(bae.loadSetting("THEME", "BABE", "Dark"))
settingsDrawer.visible = false
settingsDrawer.close()
}
......@@ -426,8 +430,9 @@ Kirigami.ApplicationWindow
{
visible: miniArtwork.visible
anchors.centerIn: parent
height: 44
width: 44
height: miniArtSize+4
width: miniArtSize+4
color: darkForegroundColor
z: -999
radius: Math.min(width, height)
......@@ -439,7 +444,7 @@ Kirigami.ApplicationWindow
to: 360;
duration: 5000
loops: Animation.Infinite
running: isPlaying
running: miniArtwork.visible && isPlaying
}
// height: headerHeight
// width: miniArtwork.visible ? headerHeight : 0
......@@ -449,8 +454,8 @@ Kirigami.ApplicationWindow
id: miniArtwork
visible: ((!pageStack.wideMode && pageStack.currentIndex !== 0) || !mainPlaylist.cover.visible) && !mainlistEmpty
height: 40
width: 40
height: miniArtSize
width: miniArtSize
// anchors.left: parent.left
anchors.centerIn: parent
source:
......@@ -539,9 +544,7 @@ Kirigami.ApplicationWindow
onClicked:
{
var value = mainPlaylist.contextMenu.babeIt(currentTrackIndex)
currentTrack.babe = value ? "1" : "0"
currentBabe = value
// bae.runPy();
}
}
......@@ -559,7 +562,7 @@ Kirigami.ApplicationWindow
id: playIcon
iconColor: darkForegroundColor
iconName: isPlaying ? "media-playback-pause" : "media-playback-start"
iconName: isPlaying ? "media-playback-pause" : "media-playback-start"
onClicked:
{
if(isPlaying) Player.pauseTrack()
......@@ -575,7 +578,7 @@ Kirigami.ApplicationWindow
iconName: "media-skip-forward"
onClicked: Player.nextTrack()
onPressAndHold: Player.playAt(Player.shuffle())
// onPressAndHold: Player.playAt(Player.shuffle())
}
BabeButton
......@@ -735,10 +738,6 @@ Kirigami.ApplicationWindow
babeitView.logginDialog.open()
}
BabeitView
{
id: babeitView
}
TracksView
{
......@@ -750,6 +749,7 @@ Kirigami.ApplicationWindow
onQuickPlayTrack: Player.quickPlay(tracksView.model.get(index))
onPlayAll: Player.playAll(bae.get(Q.GET.allTracks))
onAppendAll: Player.appendAll(bae.get(Q.GET.allTracks))
onQueueTrack: Player.queueTracks([tracksView.model.get(index)])
}
}
......@@ -824,6 +824,11 @@ Kirigami.ApplicationWindow
}
}
BabeitView
{
id: babeitView
}
}
}
}
......
......@@ -26,7 +26,7 @@ bool Player::play()
if(sourceurl.isEmpty()) return false;
if(!updater->isActive())
this->updater->start(250);
this->updater->start(150);
if(this->player->isAvailable())
this->player->play();
......
......@@ -72,6 +72,7 @@ public slots:
int newTracks = 0;
if(urls.size()>0)
{
TagInfo info;
for(auto url : urls)
{
......@@ -79,6 +80,7 @@ public slots:
{
if(!con->check_existance(BAE::TABLEMAP[BAE::TABLE::TRACKS],BAE::KEYMAP[BAE::KEY::URL],url))
{
info.feed(url);
auto album = BAE::fixString(info.getAlbum());
auto track= info.getTrack();
......@@ -124,8 +126,7 @@ signals:
void collectionSize(int size);
private:
QThread t;
TagInfo info;
QThread t;
bool go = false;
bool wait = true;
QStringList queue;
......
......@@ -1661,11 +1661,14 @@ var Babe = {
"audio-headphones": Icon.headphones,
"headphones": Icon.headphones,
"view-media-track" : Icon.musicNote,
"filename-filetype-amarok": Icon.musicNote,
"musicnote": Icon.musicNote,
"album" : Icon.album,
"media-album-cover": Icon.album,
"view-media-album-cover": Icon.album,
"artist": Icon.face,
"view-media-artist": Icon.face,
......@@ -1674,6 +1677,7 @@ var Babe = {
"view-media-playlist" : Icon.libraryMusic,
"application-menu": Icon.menu,
"view-media-config" : Icon.menu,
"games-config-options" : Icon.settings,
"edit-comment" : Icon.comment,
......@@ -1708,13 +1712,23 @@ var Babe = {
"list-remove": Icon.minus,
"entry-delete":Icon.playlistRemove,
"amarok_playcount": Icon.trendingUp,
"view-media-playcount": Icon.trendingUp,
"view-media-favorite": Icon.starCircle,
"draw-star": Icon.starCircle,
"filename-year-amarok": Icon.clock,
"view-media-recent": Icon.clock,
"internet-services": Icon.youtubePlay,
"internet-amarok": Icon.youtubePlay,
"tag" : Icon.tagMultiple,
"view-media-similarartists": Icon.tagFaces,
"similarartists-amarok": Icon.tagFaces,
"office-chart-line" : Icon.fire,
"view-media-chart": Icon.fire,
"view-media-genre": Icon.attachment,
"filename-track-amarok" : Icon.attachment,
......@@ -1725,7 +1739,9 @@ var Babe = {
"player-time" : Icon.playBoxOutline,
"media-repeat-track-amarok": Icon.playlistPlay,
"archive-insert": Icon.playlistPlus,
"media-playlist-append": Icon.playlistPlus,
"amarok_clock" : Icon.playlistPlay,
"media-playlist-play" : Icon.playBoxOutline,
/*others*/
......
......@@ -39,6 +39,21 @@ function playTrack(track)
}
}
function queueTracks(tracks)
{
if(tracks)
{
if(tracks.length > 0)
{
onQueue++
console.log(onQueue)
appendTracksAt(tracks, currentTrackIndex+1)
if(!isMobile)
bae.notify("Queue", tracks.length + " tracks added put on queue")
}
}
}
function setLyrics(lyrics)
{
currentTrack.lyrics = lyrics
......@@ -55,28 +70,33 @@ function stop()
function pauseTrack()
{
player.pause()
player.pause()
}
function resumeTrack()
{
if(!player.play() && !mainlistEmpty)
playAt(0)
if(!player.play() && !mainlistEmpty)
playAt(0)
}
function nextTrack()
{
if(root.mainPlaylist.list.count>0)
if(!mainlistEmpty)
{
var next = 0
if(root.shuffle)
if(root.shuffle && onQueue === 0)
next = shuffle()
else
next = root.mainPlaylist.list.currentIndex+1 >= root.mainPlaylist.list.count? 0 : root.mainPlaylist.list.currentIndex+1
next = currentTrackIndex+1 >= mainPlaylist.list.count? 0 : currentTrackIndex+1
root.prevTrackIndex = root.mainPlaylist.list.currentIndex
prevTrackIndex = mainPlaylist.list.currentIndex
playAt(next)
if(onQueue > 0)
{
onQueue--
console.log(onQueue)
}
}
}
......@@ -84,8 +104,8 @@ function previousTrack()
{
if(root.mainPlaylist.list.count>0)
{
var previous = previous = root.mainPlaylist.list.currentIndex-1 >= 0 ? root.mainPlaylist.list.currentIndex-1 : root.mainPlaylist.list.count-1
root.prevTrackIndex = root.mainPlaylist.list.currentIndex
var previous = previous = currentTrackIndex-1 >= 0 ? mainPlaylist.list.currentIndex-1 : currentTrackIndex-1
prevTrackIndex = mainPlaylist.list.currentIndex
playAt(previous)
}
}
......@@ -120,8 +140,8 @@ function appendTracksAt(tracks, at)
if(tracks)
for(var i in tracks)
{
if(tracks[i].url !== root.mainPlaylist.list.model.get(at).url)
root.mainPlaylist.list.model.insert(parseInt(at)+parseInt(i), tracks[i])
if(tracks[i].url !== mainPlaylist.list.model.get(at).url)
mainPlaylist.list.model.insert(parseInt(at)+parseInt(i), tracks[i])
}
}
......@@ -226,8 +246,6 @@ function playAll(tracks)
mainPlaylist.list.positionViewAtBeginning()
playAt(0)
}
}
function babeTrack(url, value)
......
......@@ -2,6 +2,7 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.2 as Kirigami
import "../../utils/Player.js" as Player
import ".."
......@@ -17,13 +18,13 @@ BabeList
property bool quickPlayVisible : true
property bool coverArtVisible : false
property bool menuItemVisible : isMobile
property int prevIndex
property bool trackDuration
property bool trackRating
property alias headerMenu: headerMenu
property alias contextMenu : contextMenu
signal rowClicked(int index)
signal rowPressed(int index)
signal quickPlayTrack(int index)
......@@ -39,7 +40,7 @@ BabeList
id : playAllBtn
visible : headerBarVisible && count > 0
anim : true
iconName : /*"amarok_clock"*/ "media-playback-start"
iconName : "media-playlist-play"
onClicked : playAll()
}
......@@ -50,7 +51,7 @@ BabeList
id: appendBtn
visible: headerBarVisible && count > 0
anim : true
iconName : "archive-insert"//"media-repeat-track-amarok"
iconName : "media-playlist-append"//"media-repeat-track-amarok"
onClicked: appendAll()
iconColor: textColor
},
......@@ -73,6 +74,7 @@ BabeList
{
id: headerMenu
onSaveListClicked: saveList()
onQueueListClicked: queueList()
}
TableMenu
......@@ -141,11 +143,27 @@ BabeList
function saveList()
{
var trackList = []
for(var i = 0; i < model.count; ++i)
trackList.push(model.get(i).url)
if(model.count > 0)
{
for(var i = 0; i < model.count; ++i)
trackList.push(model.get(i).url)
playlistDialog.tracks = trackList
playlistDialog.open()
}
}
playlistDialog.tracks = trackList
playlistDialog.open()
function queueList()
{
var trackList = []
if(model.count > 0)
{
for(var i = 0; i < model.count; ++i)
trackList.push(model.get(i))
Player.queueTracks(trackList)
}
}
// Component.onCompleted: forceActiveFocus()
......
......@@ -10,7 +10,8 @@ import ".."
BabeMenu
{
signal saveListClicked();
signal saveListClicked()
signal queueListClicked()
property alias menuItem: babeMenu.children
......@@ -20,7 +21,7 @@ BabeMenu
BabeMenuItem
{
text: "Queue list"
onTriggered: {}
onTriggered: queueListClicked()
}
BabeMenuItem
......
......@@ -5,6 +5,7 @@ import QtQuick.Layouts 1.3
import "../../view_models/BabeMenu"
import "../../utils"
import ".."
import "../../utils/Player.js" as Player
BabeMenu
{
......@@ -15,6 +16,13 @@ BabeMenu
property string starReg : foregroundColor
property string starIcon: "draw-star"
property alias menuItem : customItems.children
function queueIt(index)
{
Player.queueTracks([list.model.get(index)])
}
function rateIt(rank)
{
rate = rank
......@@ -52,6 +60,58 @@ BabeMenu
return value
}
BabePopup
{
id: sendToPopup
parent: babeTableRoot
leftPadding: 1
rightPadding: 1
topPadding: contentMargins
bottomPadding: contentMargins
BabeList
{
id: sentToList
headerBarVisible: false
anchors.fill: parent
holder.message: qsTr("There's not avalible devices")
model: ListModel
{
id: model
}
delegate: BabeDelegate
{
id: delegate
label : name
Connections
{
target: delegate
onClicked:
{
sentToList.currentIndex = index
console.log(sentToList.model.get(index).name,sentToList.model.get(index).key)
bae.sendToDevice(sentToList.model.get(index).name,
sentToList.model.get(index).key,
babeTableRoot.model.get(babeTableRoot.currentIndex).url)
}
}
}
}
onOpened:
{
sentToList.clearTable()
var devices = bae.getDevices()
for( var i in devices)
sentToList.model.append({name: devices[i].name, key: devices[i].key })
}
}
Label
{
id: titleLabel
......@@ -75,7 +135,7 @@ BabeMenu
BabeMenuItem
{
text: "Queue"
onTriggered: list.queueTrack(list.currentIndex)
onTriggered: queueIt(list.currentIndex)
}
BabeMenuItem
......@@ -97,7 +157,7 @@ BabeMenu
BabeMenuItem
{
text: "Send to..."
onTriggered: {}
onTriggered: sendToPopup.open()
}
BabeMenuItem
......@@ -106,6 +166,11 @@ BabeMenu
onTriggered: listModel.remove(list.currentIndex)
}
Column
{
id: customItems
}
BabeMenuItem
{
id: starsRow
......
......@@ -67,7 +67,7 @@ ToolBar
anchors.centerIn: parent
anchors.left: parent.left
iconName: "application-menu"
iconName: "view-media-config"
iconColor: settingsDrawer.visible ? babeColor : textColor/*(pageStack.wideMode || pageStack.currentIndex === 0 ) && !isMobile ? accentColor : textColor*/
onClicked: settingsViewClicked()
......@@ -83,32 +83,7 @@ ToolBar
{
Layout.fillWidth: true
Layout.fillHeight: true
}
Item
{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: toolBarIconSize*2
Layout.maximumHeight: toolBarIconSize
BabeButton
{
anchors.centerIn: parent
iconName: "love"
iconColor: accent && currentIndex === viewsIndex.babeit ? accentColor : textColor
onClicked: babeViewClicked()