Get to the point where we are fairly happy with our uncrustify config. Fixes #6.
This commit is contained in:
parent
d07d3dfe50
commit
62de9c2032
58 changed files with 4811 additions and 1946 deletions
|
@ -22,27 +22,27 @@
|
|||
#include "../playlist/playlist.h"
|
||||
#include "add-remove-track-popover.h"
|
||||
|
||||
extern KotoCartographer *koto_maps;
|
||||
extern KotoCartographer * koto_maps;
|
||||
|
||||
struct _KotoAddRemoveTrackPopover {
|
||||
GtkPopover parent_instance;
|
||||
GtkWidget *list_box;
|
||||
GHashTable *checkbox_to_playlist_uuid;
|
||||
GHashTable *playlist_uuid_to_checkbox;
|
||||
GList *tracks;
|
||||
GtkWidget * list_box;
|
||||
GHashTable * checkbox_to_playlist_uuid;
|
||||
GHashTable * playlist_uuid_to_checkbox;
|
||||
GList * tracks;
|
||||
|
||||
GHashTable *checkbox_to_signal_ids;
|
||||
GHashTable * checkbox_to_signal_ids;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(KotoAddRemoveTrackPopover, koto_add_remove_track_popover, GTK_TYPE_POPOVER);
|
||||
|
||||
KotoAddRemoveTrackPopover *koto_add_remove_track_popup = NULL;
|
||||
KotoAddRemoveTrackPopover * koto_add_remove_track_popup = NULL;
|
||||
|
||||
static void koto_add_remove_track_popover_class_init(KotoAddRemoveTrackPopoverClass *c) {
|
||||
static void koto_add_remove_track_popover_class_init(KotoAddRemoveTrackPopoverClass * c) {
|
||||
(void) c;
|
||||
}
|
||||
|
||||
static void koto_add_remove_track_popover_init(KotoAddRemoveTrackPopover *self) {
|
||||
static void koto_add_remove_track_popover_init(KotoAddRemoveTrackPopover * self) {
|
||||
self->list_box = gtk_list_box_new(); // Create our new GtkListBox
|
||||
gtk_list_box_set_selection_mode(GTK_LIST_BOX(self->list_box), GTK_SELECTION_NONE);
|
||||
|
||||
|
@ -58,7 +58,10 @@ static void koto_add_remove_track_popover_init(KotoAddRemoveTrackPopover *self)
|
|||
g_signal_connect(koto_maps, "playlist-removed", G_CALLBACK(koto_add_remove_track_popover_handle_playlist_removed), self);
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_add_playlist(KotoAddRemoveTrackPopover *self, KotoPlaylist *playlist) {
|
||||
void koto_add_remove_track_popover_add_playlist(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
KotoPlaylist * playlist
|
||||
) {
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -67,24 +70,29 @@ void koto_add_remove_track_popover_add_playlist(KotoAddRemoveTrackPopover *self,
|
|||
return;
|
||||
}
|
||||
|
||||
gchar *playlist_uuid = koto_playlist_get_uuid(playlist); // Get the UUID of the playlist
|
||||
gchar * playlist_uuid = koto_playlist_get_uuid(playlist); // Get the UUID of the playlist
|
||||
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON(g_hash_table_lookup(self->playlist_uuid_to_checkbox, playlist_uuid))) { // Already have a check button for this
|
||||
g_free(playlist_uuid);
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWidget *playlist_button = gtk_check_button_new_with_label(koto_playlist_get_name(playlist)); // Create our GtkCheckButton
|
||||
GtkWidget * playlist_button = gtk_check_button_new_with_label(koto_playlist_get_name(playlist)); // Create our GtkCheckButton
|
||||
|
||||
|
||||
g_hash_table_insert(self->checkbox_to_playlist_uuid, playlist_button, playlist_uuid);
|
||||
g_hash_table_insert(self->playlist_uuid_to_checkbox, playlist_uuid, playlist_button);
|
||||
|
||||
gulong playlist_sig_id = g_signal_connect(playlist_button, "toggled", G_CALLBACK(koto_add_remove_track_popover_handle_checkbutton_toggle), self);
|
||||
|
||||
|
||||
g_hash_table_insert(self->checkbox_to_signal_ids, playlist_button, GUINT_TO_POINTER(playlist_sig_id)); // Add our GSignal handler ID
|
||||
|
||||
gtk_list_box_append(GTK_LIST_BOX(self->list_box), playlist_button); // Add the playlist to the list box
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_clear_tracks(KotoAddRemoveTrackPopover *self) {
|
||||
void koto_add_remove_track_popover_clear_tracks(KotoAddRemoveTrackPopover * self) {
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -95,7 +103,10 @@ void koto_add_remove_track_popover_clear_tracks(KotoAddRemoveTrackPopover *self)
|
|||
}
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_remove_playlist(KotoAddRemoveTrackPopover *self, gchar *playlist_uuid) {
|
||||
void koto_add_remove_track_popover_remove_playlist(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
gchar * playlist_uuid
|
||||
) {
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -104,7 +115,8 @@ void koto_add_remove_track_popover_remove_playlist(KotoAddRemoveTrackPopover *se
|
|||
return;
|
||||
}
|
||||
|
||||
GtkCheckButton *btn = GTK_CHECK_BUTTON(g_hash_table_lookup(self->playlist_uuid_to_checkbox, playlist_uuid)); // Get the check button
|
||||
GtkCheckButton * btn = GTK_CHECK_BUTTON(g_hash_table_lookup(self->playlist_uuid_to_checkbox, playlist_uuid)); // Get the check button
|
||||
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON(btn)) { // Is a check button
|
||||
g_hash_table_remove(self->checkbox_to_playlist_uuid, btn); // Remove uuid based on btn
|
||||
|
@ -114,31 +126,38 @@ void koto_add_remove_track_popover_remove_playlist(KotoAddRemoveTrackPopover *se
|
|||
g_hash_table_remove(self->playlist_uuid_to_checkbox, playlist_uuid);
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_handle_checkbutton_toggle(GtkCheckButton *btn, gpointer user_data) {
|
||||
KotoAddRemoveTrackPopover *self = user_data;
|
||||
void koto_add_remove_track_popover_handle_checkbutton_toggle(
|
||||
GtkCheckButton * btn,
|
||||
gpointer user_data
|
||||
) {
|
||||
KotoAddRemoveTrackPopover * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gboolean should_add = gtk_check_button_get_active(btn); // Get the now active state
|
||||
gchar *playlist_uuid = g_hash_table_lookup(self->checkbox_to_playlist_uuid, btn); // Get the playlist UUID for this button
|
||||
gchar * playlist_uuid = g_hash_table_lookup(self->checkbox_to_playlist_uuid, btn); // Get the playlist UUID for this button
|
||||
|
||||
KotoPlaylist * playlist = koto_cartographer_get_playlist_by_uuid(koto_maps, playlist_uuid); // Get the playlist
|
||||
|
||||
KotoPlaylist *playlist = koto_cartographer_get_playlist_by_uuid(koto_maps, playlist_uuid); // Get the playlist
|
||||
|
||||
if (!KOTO_IS_PLAYLIST(playlist)) { // Failed to get the playlist
|
||||
return;
|
||||
}
|
||||
|
||||
GList *pos;
|
||||
GList * pos;
|
||||
|
||||
|
||||
for (pos = self->tracks; pos != NULL; pos = pos->next) { // Iterate over our KotoIndexedTracks
|
||||
KotoIndexedTrack *track = pos->data;
|
||||
KotoIndexedTrack * track = pos->data;
|
||||
|
||||
if (!KOTO_INDEXED_TRACK(track)) { // Not a track
|
||||
continue; // Skip this
|
||||
}
|
||||
|
||||
gchar *track_uuid = koto_indexed_track_get_uuid(track); // Get the track
|
||||
gchar * track_uuid = koto_indexed_track_get_uuid(track); // Get the track
|
||||
|
||||
if (should_add) { // Should be adding
|
||||
koto_playlist_add_track_by_uuid(playlist, track_uuid, FALSE, TRUE); // Add the track to the playlist
|
||||
|
@ -150,9 +169,14 @@ void koto_add_remove_track_popover_handle_checkbutton_toggle(GtkCheckButton *btn
|
|||
gtk_popover_popdown(GTK_POPOVER(self)); // Temporary to hopefully prevent a bork
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_handle_playlist_added(KotoCartographer *carto, KotoPlaylist *playlist, gpointer user_data) {
|
||||
void koto_add_remove_track_popover_handle_playlist_added(
|
||||
KotoCartographer * carto,
|
||||
KotoPlaylist * playlist,
|
||||
gpointer user_data
|
||||
) {
|
||||
(void) carto;
|
||||
KotoAddRemoveTrackPopover *self = user_data;
|
||||
KotoAddRemoveTrackPopover * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
|
@ -161,9 +185,14 @@ void koto_add_remove_track_popover_handle_playlist_added(KotoCartographer *carto
|
|||
koto_add_remove_track_popover_add_playlist(self, playlist);
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_handle_playlist_removed(KotoCartographer *carto, gchar *playlist_uuid, gpointer user_data) {
|
||||
void koto_add_remove_track_popover_handle_playlist_removed(
|
||||
KotoCartographer * carto,
|
||||
gchar * playlist_uuid,
|
||||
gpointer user_data
|
||||
) {
|
||||
(void) carto;
|
||||
KotoAddRemoveTrackPopover *self = user_data;
|
||||
KotoAddRemoveTrackPopover * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
|
@ -172,7 +201,11 @@ void koto_add_remove_track_popover_handle_playlist_removed(KotoCartographer *car
|
|||
koto_add_remove_track_popover_remove_playlist(self, playlist_uuid);
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_set_pointing_to_widget(KotoAddRemoveTrackPopover *self, GtkWidget *widget, GtkPositionType pos) {
|
||||
void koto_add_remove_track_popover_set_pointing_to_widget(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
GtkWidget * widget,
|
||||
GtkPositionType pos
|
||||
) {
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -183,6 +216,7 @@ void koto_add_remove_track_popover_set_pointing_to_widget(KotoAddRemoveTrackPopo
|
|||
|
||||
GtkWidget* existing_parent = gtk_widget_get_parent(GTK_WIDGET(self));
|
||||
|
||||
|
||||
if (existing_parent != NULL) {
|
||||
g_object_ref(GTK_WIDGET(self)); // Increment widget ref since unparent will do an unref
|
||||
gtk_widget_unparent(GTK_WIDGET(self)); // Unparent the popup
|
||||
|
@ -192,30 +226,35 @@ void koto_add_remove_track_popover_set_pointing_to_widget(KotoAddRemoveTrackPopo
|
|||
gtk_popover_set_position(GTK_POPOVER(self), pos);
|
||||
}
|
||||
|
||||
void koto_add_remove_track_popover_set_tracks(KotoAddRemoveTrackPopover *self, GList *tracks) {
|
||||
void koto_add_remove_track_popover_set_tracks(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
GList * tracks
|
||||
) {
|
||||
if (!KOTO_JS_ADD_REMOVE_TRACK_POPOVER(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gint tracks_len = g_list_length(tracks);
|
||||
|
||||
|
||||
if (tracks_len == 0) { // No tracks
|
||||
return;
|
||||
}
|
||||
|
||||
self->tracks = g_list_copy(tracks);
|
||||
GHashTable *playlists = koto_cartographer_get_playlists(koto_maps); // Get our playlists
|
||||
GHashTable * playlists = koto_cartographer_get_playlists(koto_maps); // Get our playlists
|
||||
GHashTableIter playlists_iter;
|
||||
gpointer uuid, playlist_ptr;
|
||||
|
||||
|
||||
g_hash_table_iter_init(&playlists_iter, playlists); // Init our HashTable iterator
|
||||
|
||||
while (g_hash_table_iter_next(&playlists_iter, &uuid, &playlist_ptr)) { // While we are iterating through our playlists
|
||||
KotoPlaylist *playlist = playlist_ptr;
|
||||
KotoPlaylist * playlist = playlist_ptr;
|
||||
gboolean should_be_checked = FALSE;
|
||||
|
||||
if (tracks_len > 1) { // More than one track
|
||||
GList *pos;
|
||||
GList * pos;
|
||||
for (pos = self->tracks; pos != NULL; pos = pos->next) { // Iterate over our tracks
|
||||
should_be_checked = (koto_playlist_get_position_of_track(playlist, pos->data) != -1);
|
||||
|
||||
|
@ -224,7 +263,7 @@ void koto_add_remove_track_popover_set_tracks(KotoAddRemoveTrackPopover *self, G
|
|||
}
|
||||
}
|
||||
} else {
|
||||
KotoIndexedTrack *track = g_list_nth_data(self->tracks, 0); // Get the first track
|
||||
KotoIndexedTrack * track = g_list_nth_data(self->tracks, 0); // Get the first track
|
||||
|
||||
if (KOTO_IS_INDEXED_TRACK(track)) {
|
||||
gint pos = koto_playlist_get_position_of_track(playlist, track);
|
||||
|
@ -232,7 +271,7 @@ void koto_add_remove_track_popover_set_tracks(KotoAddRemoveTrackPopover *self, G
|
|||
}
|
||||
}
|
||||
|
||||
GtkCheckButton *playlist_check = g_hash_table_lookup(self->playlist_uuid_to_checkbox, uuid); // Get the GtkCheckButton for this playlist
|
||||
GtkCheckButton * playlist_check = g_hash_table_lookup(self->playlist_uuid_to_checkbox, uuid); // Get the GtkCheckButton for this playlist
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON(playlist_check)) { // Is a checkbox
|
||||
gpointer sig_id_ptr = g_hash_table_lookup(self->checkbox_to_signal_ids, playlist_check);
|
||||
|
@ -244,6 +283,6 @@ void koto_add_remove_track_popover_set_tracks(KotoAddRemoveTrackPopover *self, G
|
|||
}
|
||||
}
|
||||
|
||||
KotoAddRemoveTrackPopover* koto_add_remove_track_popover_new() {
|
||||
KotoAddRemoveTrackPopover * koto_add_remove_track_popover_new() {
|
||||
return g_object_new(KOTO_TYPE_ADD_REMOVE_TRACK_POPOVER, NULL);
|
||||
}
|
|
@ -25,7 +25,7 @@ G_BEGIN_DECLS
|
|||
|
||||
/**
|
||||
* Type Definition
|
||||
**/
|
||||
**/
|
||||
|
||||
#define KOTO_TYPE_ADD_REMOVE_TRACK_POPOVER koto_add_remove_track_popover_get_type()
|
||||
G_DECLARE_FINAL_TYPE(KotoAddRemoveTrackPopover, koto_add_remove_track_popover, KOTO, ADD_REMOVE_TRACK_POPOVER, GtkPopover);
|
||||
|
@ -33,16 +33,48 @@ G_DECLARE_FINAL_TYPE(KotoAddRemoveTrackPopover, koto_add_remove_track_popover, K
|
|||
|
||||
/**
|
||||
* Functions
|
||||
**/
|
||||
**/
|
||||
|
||||
KotoAddRemoveTrackPopover* koto_add_remove_track_popover_new();
|
||||
void koto_add_remove_track_popover_add_playlist(KotoAddRemoveTrackPopover *self, KotoPlaylist *playlist);
|
||||
void koto_add_remove_track_popover_clear_tracks(KotoAddRemoveTrackPopover *self);
|
||||
void koto_add_remove_track_popover_remove_playlist(KotoAddRemoveTrackPopover *self, gchar *playlist_uuid);
|
||||
void koto_add_remove_track_popover_handle_checkbutton_toggle(GtkCheckButton *btn, gpointer user_data);
|
||||
void koto_add_remove_track_popover_handle_playlist_added(KotoCartographer *carto, KotoPlaylist *playlist, gpointer user_data);
|
||||
void koto_add_remove_track_popover_handle_playlist_removed(KotoCartographer *carto, gchar *playlist_uuid, gpointer user_data);
|
||||
void koto_add_remove_track_popover_set_pointing_to_widget(KotoAddRemoveTrackPopover *self, GtkWidget *widget, GtkPositionType pos);
|
||||
void koto_add_remove_track_popover_set_tracks(KotoAddRemoveTrackPopover *self, GList *tracks);
|
||||
KotoAddRemoveTrackPopover * koto_add_remove_track_popover_new();
|
||||
|
||||
void koto_add_remove_track_popover_add_playlist(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
KotoPlaylist * playlist
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_clear_tracks(KotoAddRemoveTrackPopover * self);
|
||||
|
||||
void koto_add_remove_track_popover_remove_playlist(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
gchar * playlist_uuid
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_handle_checkbutton_toggle(
|
||||
GtkCheckButton * btn,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_handle_playlist_added(
|
||||
KotoCartographer * carto,
|
||||
KotoPlaylist * playlist,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_handle_playlist_removed(
|
||||
KotoCartographer * carto,
|
||||
gchar * playlist_uuid,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_set_pointing_to_widget(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
GtkWidget * widget,
|
||||
GtkPositionType pos
|
||||
);
|
||||
|
||||
void koto_add_remove_track_popover_set_tracks(
|
||||
KotoAddRemoveTrackPopover * self,
|
||||
GList * tracks
|
||||
);
|
||||
|
||||
G_END_DECLS
|
|
@ -24,8 +24,8 @@
|
|||
#include "../koto-window.h"
|
||||
#include "create-modify-dialog.h"
|
||||
|
||||
extern KotoCartographer *koto_maps;
|
||||
extern KotoWindow *main_window;
|
||||
extern KotoCartographer * koto_maps;
|
||||
extern KotoWindow * main_window;
|
||||
|
||||
enum {
|
||||
PROP_DIALOG_0,
|
||||
|
@ -33,29 +33,44 @@ enum {
|
|||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *dialog_props[N_PROPS] = { NULL, };
|
||||
static GParamSpec * dialog_props[N_PROPS] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
struct _KotoCreateModifyPlaylistDialog {
|
||||
GtkBox parent_instance;
|
||||
GtkWidget *playlist_image;
|
||||
GtkWidget *name_entry;
|
||||
GtkWidget * playlist_image;
|
||||
GtkWidget * name_entry;
|
||||
|
||||
GtkWidget *create_button;
|
||||
GtkWidget * create_button;
|
||||
|
||||
gchar *playlist_image_path;
|
||||
gchar *playlist_uuid;
|
||||
gchar * playlist_image_path;
|
||||
gchar * playlist_uuid;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(KotoCreateModifyPlaylistDialog, koto_create_modify_playlist_dialog, GTK_TYPE_BOX);
|
||||
|
||||
KotoCreateModifyPlaylistDialog *playlist_create_modify_dialog;
|
||||
KotoCreateModifyPlaylistDialog * playlist_create_modify_dialog;
|
||||
|
||||
static void koto_create_modify_playlist_dialog_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
static void koto_create_modify_playlist_dialog_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
static void koto_create_modify_playlist_dialog_class_init(KotoCreateModifyPlaylistDialogClass * c) {
|
||||
GObjectClass * gobject_class;
|
||||
|
||||
static void koto_create_modify_playlist_dialog_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec);
|
||||
static void koto_create_modify_playlist_dialog_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec);
|
||||
|
||||
static void koto_create_modify_playlist_dialog_class_init(KotoCreateModifyPlaylistDialogClass *c) {
|
||||
GObjectClass *gobject_class;
|
||||
gobject_class = G_OBJECT_CLASS(c);
|
||||
gobject_class->set_property = koto_create_modify_playlist_dialog_set_property;
|
||||
gobject_class->get_property = koto_create_modify_playlist_dialog_get_property;
|
||||
|
@ -65,13 +80,13 @@ static void koto_create_modify_playlist_dialog_class_init(KotoCreateModifyPlayli
|
|||
"Playlist UUID",
|
||||
"Playlist UUID",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
g_object_class_install_properties(gobject_class, N_PROPS, dialog_props);
|
||||
}
|
||||
|
||||
static void koto_create_modify_playlist_dialog_init(KotoCreateModifyPlaylistDialog *self) {
|
||||
static void koto_create_modify_playlist_dialog_init(KotoCreateModifyPlaylistDialog * self) {
|
||||
self->playlist_image_path = NULL;
|
||||
|
||||
gtk_widget_set_halign(GTK_WIDGET(self), GTK_ALIGN_CENTER);
|
||||
|
@ -82,11 +97,15 @@ static void koto_create_modify_playlist_dialog_init(KotoCreateModifyPlaylistDial
|
|||
gtk_widget_set_size_request(self->playlist_image, 220, 220);
|
||||
gtk_box_append(GTK_BOX(self), self->playlist_image); // Add our image
|
||||
|
||||
GtkDropTarget *target = gtk_drop_target_new(G_TYPE_FILE, GDK_ACTION_COPY);
|
||||
GtkDropTarget * target = gtk_drop_target_new(G_TYPE_FILE, GDK_ACTION_COPY);
|
||||
|
||||
|
||||
g_signal_connect(GTK_EVENT_CONTROLLER(target), "drop", G_CALLBACK(koto_create_modify_playlist_dialog_handle_drop), self);
|
||||
gtk_widget_add_controller(self->playlist_image, GTK_EVENT_CONTROLLER(target));
|
||||
|
||||
GtkGesture *image_click_controller = gtk_gesture_click_new(); // Create a click gesture for the image clicking
|
||||
GtkGesture * image_click_controller = gtk_gesture_click_new(); // Create a click gesture for the image clicking
|
||||
|
||||
|
||||
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(image_click_controller), 1); // Only allow left click
|
||||
g_signal_connect(GTK_EVENT_CONTROLLER(image_click_controller), "pressed", G_CALLBACK(koto_create_modify_playlist_dialog_handle_image_click), self);
|
||||
|
||||
|
@ -105,8 +124,14 @@ static void koto_create_modify_playlist_dialog_init(KotoCreateModifyPlaylistDial
|
|||
gtk_box_append(GTK_BOX(self), self->create_button); // Add the create button
|
||||
}
|
||||
|
||||
static void koto_create_modify_playlist_dialog_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec){
|
||||
KotoCreateModifyPlaylistDialog *self = KOTO_CREATE_MODIFY_PLAYLIST_DIALOG(obj);
|
||||
static void koto_create_modify_playlist_dialog_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoCreateModifyPlaylistDialog * self = KOTO_CREATE_MODIFY_PLAYLIST_DIALOG(obj);
|
||||
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLAYLIST_UUID:
|
||||
|
@ -118,9 +143,17 @@ static void koto_create_modify_playlist_dialog_get_property(GObject *obj, guint
|
|||
}
|
||||
}
|
||||
|
||||
static void koto_create_modify_playlist_dialog_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec) {
|
||||
KotoCreateModifyPlaylistDialog *self = KOTO_CREATE_MODIFY_PLAYLIST_DIALOG(obj);
|
||||
(void) self; (void) val;
|
||||
static void koto_create_modify_playlist_dialog_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoCreateModifyPlaylistDialog * self = KOTO_CREATE_MODIFY_PLAYLIST_DIALOG(obj);
|
||||
|
||||
|
||||
(void) self;
|
||||
(void) val;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLAYLIST_UUID:
|
||||
|
@ -132,19 +165,26 @@ static void koto_create_modify_playlist_dialog_set_property(GObject *obj, guint
|
|||
}
|
||||
}
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_chooser_response(GtkNativeDialog *native, int response, gpointer user_data) {
|
||||
void koto_create_modify_playlist_dialog_handle_chooser_response(
|
||||
GtkNativeDialog * native,
|
||||
int response,
|
||||
gpointer user_data
|
||||
) {
|
||||
if (response != GTK_RESPONSE_ACCEPT) { // Not accept
|
||||
g_object_unref(native);
|
||||
return;
|
||||
}
|
||||
|
||||
KotoCreateModifyPlaylistDialog *self = user_data;
|
||||
KotoCreateModifyPlaylistDialog * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_IS_CURRENT_MODIFY_PLAYLIST(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(native));
|
||||
gchar *file_path = g_file_get_path(file); // Get the absolute path
|
||||
GFile * file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(native));
|
||||
gchar * file_path = g_file_get_path(file); // Get the absolute path
|
||||
|
||||
|
||||
if (file_path != NULL) {
|
||||
self->playlist_image_path = g_strdup(file_path);
|
||||
|
@ -156,10 +196,14 @@ void koto_create_modify_playlist_dialog_handle_chooser_response(GtkNativeDialog
|
|||
g_object_unref(native);
|
||||
}
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_create_click(GtkButton *button, gpointer user_data) {
|
||||
void koto_create_modify_playlist_dialog_handle_create_click(
|
||||
GtkButton * button,
|
||||
gpointer user_data
|
||||
) {
|
||||
(void) button;
|
||||
|
||||
KotoCreateModifyPlaylistDialog *self = user_data;
|
||||
KotoCreateModifyPlaylistDialog * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_IS_CURRENT_MODIFY_PLAYLIST(self)) {
|
||||
return;
|
||||
|
@ -170,9 +214,10 @@ void koto_create_modify_playlist_dialog_handle_create_click(GtkButton *button, g
|
|||
return;
|
||||
}
|
||||
|
||||
KotoPlaylist *playlist = NULL;
|
||||
KotoPlaylist * playlist = NULL;
|
||||
gboolean modify_existing_playlist = koto_utils_is_string_valid(self->playlist_uuid);
|
||||
|
||||
|
||||
if (modify_existing_playlist) { // Modifying an existing playlist
|
||||
playlist = koto_cartographer_get_playlist_by_uuid(koto_maps, self->playlist_uuid);
|
||||
} else { // Creating a new playlist
|
||||
|
@ -196,21 +241,32 @@ void koto_create_modify_playlist_dialog_handle_create_click(GtkButton *button, g
|
|||
koto_window_hide_dialogs(main_window); // Hide the dialogs
|
||||
}
|
||||
|
||||
gboolean koto_create_modify_playlist_dialog_handle_drop(GtkDropTarget *target, const GValue *val, double x, double y, gpointer user_data) {
|
||||
(void) target; (void) x; (void) y;
|
||||
gboolean koto_create_modify_playlist_dialog_handle_drop(
|
||||
GtkDropTarget * target,
|
||||
const GValue * val,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data
|
||||
) {
|
||||
(void) target;
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
if (!G_VALUE_HOLDS(val, G_TYPE_FILE)) { // Not a file
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
KotoCreateModifyPlaylistDialog *self = user_data;
|
||||
KotoCreateModifyPlaylistDialog * self = user_data;
|
||||
|
||||
|
||||
if (!KOTO_IS_CURRENT_MODIFY_PLAYLIST(self)) { // No dialog
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GFile *dropped_file = g_value_get_object(val); // Get the GValue
|
||||
gchar *file_path = g_file_get_path(dropped_file); // Get the absolute path
|
||||
GFile * dropped_file = g_value_get_object(val); // Get the GValue
|
||||
gchar * file_path = g_file_get_path(dropped_file); // Get the absolute path
|
||||
|
||||
|
||||
g_object_unref(dropped_file); // Unref the file
|
||||
|
||||
if (file_path == NULL) {
|
||||
|
@ -219,6 +275,7 @@ gboolean koto_create_modify_playlist_dialog_handle_drop(GtkDropTarget *target, c
|
|||
|
||||
magic_t magic_cookie = magic_open(MAGIC_MIME);
|
||||
|
||||
|
||||
if (magic_cookie == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -227,7 +284,8 @@ gboolean koto_create_modify_playlist_dialog_handle_drop(GtkDropTarget *target, c
|
|||
goto cookie_closure;
|
||||
}
|
||||
|
||||
const char *mime_type = magic_file(magic_cookie, file_path);
|
||||
const char * mime_type = magic_file(magic_cookie, file_path);
|
||||
|
||||
|
||||
if ((mime_type != NULL) && g_str_has_prefix(mime_type, "image/")) { // Is an image
|
||||
self->playlist_image_path = g_strdup(file_path);
|
||||
|
@ -237,21 +295,32 @@ gboolean koto_create_modify_playlist_dialog_handle_drop(GtkDropTarget *target, c
|
|||
}
|
||||
|
||||
cookie_closure:
|
||||
magic_close(magic_cookie);
|
||||
return FALSE;
|
||||
magic_close(magic_cookie);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_image_click(GtkGestureClick *gesture, int n_press, double x, double y, gpointer user_data) {
|
||||
(void) gesture; (void) n_press; (void) x; (void) y;
|
||||
void koto_create_modify_playlist_dialog_handle_image_click(
|
||||
GtkGestureClick * gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data
|
||||
) {
|
||||
(void) gesture;
|
||||
(void) n_press;
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
KotoCreateModifyPlaylistDialog *self = user_data;
|
||||
KotoCreateModifyPlaylistDialog * self = user_data;
|
||||
|
||||
GtkFileChooserNative* chooser = koto_utils_create_image_file_chooser("Choose playlist image");
|
||||
|
||||
|
||||
g_signal_connect(chooser, "response", G_CALLBACK(koto_create_modify_playlist_dialog_handle_chooser_response), self);
|
||||
gtk_native_dialog_show(GTK_NATIVE_DIALOG(chooser)); // Show our file chooser
|
||||
}
|
||||
|
||||
void koto_create_modify_playlist_dialog_reset(KotoCreateModifyPlaylistDialog *self) {
|
||||
void koto_create_modify_playlist_dialog_reset(KotoCreateModifyPlaylistDialog * self) {
|
||||
if (!KOTO_IS_CURRENT_MODIFY_PLAYLIST(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -262,12 +331,16 @@ void koto_create_modify_playlist_dialog_reset(KotoCreateModifyPlaylistDialog *se
|
|||
gtk_button_set_label(GTK_BUTTON(self->create_button), "Create");
|
||||
}
|
||||
|
||||
void koto_create_modify_playlist_dialog_set_playlist_uuid(KotoCreateModifyPlaylistDialog *self, gchar *playlist_uuid) {
|
||||
void koto_create_modify_playlist_dialog_set_playlist_uuid(
|
||||
KotoCreateModifyPlaylistDialog * self,
|
||||
gchar * playlist_uuid
|
||||
) {
|
||||
if (!koto_utils_is_string_valid(playlist_uuid)) { // Not a valid playlist UUID string
|
||||
return;
|
||||
}
|
||||
|
||||
KotoPlaylist *playlist = koto_cartographer_get_playlist_by_uuid(koto_maps, playlist_uuid);
|
||||
KotoPlaylist * playlist = koto_cartographer_get_playlist_by_uuid(koto_maps, playlist_uuid);
|
||||
|
||||
|
||||
if (!KOTO_IS_PLAYLIST(playlist)) {
|
||||
return;
|
||||
|
@ -277,7 +350,8 @@ void koto_create_modify_playlist_dialog_set_playlist_uuid(KotoCreateModifyPlayli
|
|||
gtk_entry_buffer_set_text(gtk_entry_get_buffer(GTK_ENTRY(self->name_entry)), koto_playlist_get_name(playlist), -1); // Update the input buffer
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(self->name_entry), ""); // Clear placeholder
|
||||
|
||||
gchar *art = koto_playlist_get_artwork(playlist);
|
||||
gchar * art = koto_playlist_get_artwork(playlist);
|
||||
|
||||
|
||||
if (!koto_utils_is_string_valid(art)) { // If art is not defined
|
||||
gtk_image_set_from_icon_name(GTK_IMAGE(self->playlist_image), "insert-image-symbolic"); // Reset the image
|
||||
|
@ -289,13 +363,8 @@ void koto_create_modify_playlist_dialog_set_playlist_uuid(KotoCreateModifyPlayli
|
|||
gtk_button_set_label(GTK_BUTTON(self->create_button), "Save");
|
||||
}
|
||||
|
||||
KotoCreateModifyPlaylistDialog* koto_create_modify_playlist_dialog_new(char *playlist_uuid) {
|
||||
KotoCreateModifyPlaylistDialog * koto_create_modify_playlist_dialog_new(char * playlist_uuid) {
|
||||
(void) playlist_uuid;
|
||||
|
||||
return g_object_new(KOTO_TYPE_CREATE_MODIFY_PLAYLIST_DIALOG,
|
||||
"orientation",
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
"spacing",
|
||||
40,
|
||||
NULL);
|
||||
return g_object_new(KOTO_TYPE_CREATE_MODIFY_PLAYLIST_DIALOG, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 40, NULL);
|
||||
}
|
|
@ -23,7 +23,7 @@ G_BEGIN_DECLS
|
|||
|
||||
/**
|
||||
* Type Definition
|
||||
**/
|
||||
**/
|
||||
|
||||
#define KOTO_TYPE_CREATE_MODIFY_PLAYLIST_DIALOG koto_create_modify_playlist_dialog_get_type()
|
||||
G_DECLARE_FINAL_TYPE(KotoCreateModifyPlaylistDialog, koto_create_modify_playlist_dialog, KOTO, CREATE_MODIFY_PLAYLIST_DIALOG, GtkBox);
|
||||
|
@ -31,14 +31,42 @@ G_DECLARE_FINAL_TYPE(KotoCreateModifyPlaylistDialog, koto_create_modify_playlist
|
|||
|
||||
/**
|
||||
* Functions
|
||||
**/
|
||||
**/
|
||||
|
||||
KotoCreateModifyPlaylistDialog* koto_create_modify_playlist_dialog_new();
|
||||
void koto_create_modify_playlist_dialog_handle_chooser_response(GtkNativeDialog *native, int response, gpointer user_data);
|
||||
void koto_create_modify_playlist_dialog_handle_create_click(GtkButton *button, gpointer user_data);
|
||||
gboolean koto_create_modify_playlist_dialog_handle_drop(GtkDropTarget *target, const GValue *val, double x, double y, gpointer user_data);
|
||||
void koto_create_modify_playlist_dialog_handle_image_click(GtkGestureClick *gesture, int n_press, double x, double y, gpointer user_data);
|
||||
void koto_create_modify_playlist_dialog_reset(KotoCreateModifyPlaylistDialog *self);
|
||||
void koto_create_modify_playlist_dialog_set_playlist_uuid(KotoCreateModifyPlaylistDialog *self, gchar *playlist_uuid);
|
||||
KotoCreateModifyPlaylistDialog * koto_create_modify_playlist_dialog_new();
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_chooser_response(
|
||||
GtkNativeDialog * native,
|
||||
int response,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_create_click(
|
||||
GtkButton * button,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
gboolean koto_create_modify_playlist_dialog_handle_drop(
|
||||
GtkDropTarget * target,
|
||||
const GValue * val,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_create_modify_playlist_dialog_handle_image_click(
|
||||
GtkGestureClick * gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_create_modify_playlist_dialog_reset(KotoCreateModifyPlaylistDialog * self);
|
||||
|
||||
void koto_create_modify_playlist_dialog_set_playlist_uuid(
|
||||
KotoCreateModifyPlaylistDialog * self,
|
||||
gchar * playlist_uuid
|
||||
);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -24,22 +24,37 @@ enum {
|
|||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPERTIES] = { NULL, };
|
||||
static GParamSpec * props[N_PROPERTIES] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
KotoCurrentPlaylist *current_playlist = NULL;
|
||||
KotoCurrentPlaylist * current_playlist = NULL;
|
||||
|
||||
struct _KotoCurrentPlaylist {
|
||||
GObject parent_class;
|
||||
KotoPlaylist *current_playlist;
|
||||
KotoPlaylist * current_playlist;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(KotoCurrentPlaylist, koto_current_playlist, G_TYPE_OBJECT);
|
||||
|
||||
static void koto_current_playlist_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec);
|
||||
static void koto_current_playlist_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec);
|
||||
static void koto_current_playlist_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
static void koto_current_playlist_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
static void koto_current_playlist_class_init(KotoCurrentPlaylistClass * c) {
|
||||
GObjectClass * gobject_class;
|
||||
|
||||
|
||||
static void koto_current_playlist_class_init(KotoCurrentPlaylistClass *c) {
|
||||
GObjectClass *gobject_class;
|
||||
gobject_class = G_OBJECT_CLASS(c);
|
||||
gobject_class->set_property = koto_current_playlist_set_property;
|
||||
gobject_class->get_property = koto_current_playlist_get_property;
|
||||
|
@ -49,18 +64,24 @@ static void koto_current_playlist_class_init(KotoCurrentPlaylistClass *c) {
|
|||
"Current Playlist",
|
||||
"Current Playlist",
|
||||
KOTO_TYPE_PLAYLIST,
|
||||
G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
g_object_class_install_properties(gobject_class, N_PROPERTIES, props);
|
||||
}
|
||||
|
||||
static void koto_current_playlist_init(KotoCurrentPlaylist *self) {
|
||||
static void koto_current_playlist_init(KotoCurrentPlaylist * self) {
|
||||
self->current_playlist = NULL;
|
||||
}
|
||||
|
||||
void koto_current_playlist_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec) {
|
||||
KotoCurrentPlaylist *self = KOTO_CURRENT_PLAYLIST(obj);
|
||||
void koto_current_playlist_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoCurrentPlaylist * self = KOTO_CURRENT_PLAYLIST(obj);
|
||||
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CURRENT_PLAYLIST:
|
||||
|
@ -72,8 +93,14 @@ void koto_current_playlist_get_property(GObject *obj, guint prop_id, GValue *val
|
|||
}
|
||||
}
|
||||
|
||||
void koto_current_playlist_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec) {
|
||||
KotoCurrentPlaylist *self = KOTO_CURRENT_PLAYLIST(obj);
|
||||
void koto_current_playlist_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoCurrentPlaylist * self = KOTO_CURRENT_PLAYLIST(obj);
|
||||
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CURRENT_PLAYLIST:
|
||||
|
@ -85,11 +112,14 @@ void koto_current_playlist_set_property(GObject *obj, guint prop_id, const GValu
|
|||
}
|
||||
}
|
||||
|
||||
KotoPlaylist* koto_current_playlist_get_playlist(KotoCurrentPlaylist *self) {
|
||||
KotoPlaylist * koto_current_playlist_get_playlist(KotoCurrentPlaylist * self) {
|
||||
return self->current_playlist;
|
||||
}
|
||||
|
||||
void koto_current_playlist_set_playlist(KotoCurrentPlaylist *self, KotoPlaylist *playlist) {
|
||||
void koto_current_playlist_set_playlist(
|
||||
KotoCurrentPlaylist * self,
|
||||
KotoPlaylist * playlist
|
||||
) {
|
||||
if (!KOTO_IS_CURRENT_PLAYLIST(self)) {
|
||||
return;
|
||||
}
|
||||
|
@ -99,7 +129,7 @@ void koto_current_playlist_set_playlist(KotoCurrentPlaylist *self, KotoPlaylist
|
|||
}
|
||||
|
||||
if (self->current_playlist != NULL && KOTO_IS_PLAYLIST(self->current_playlist)) {
|
||||
gboolean *is_temp = FALSE;
|
||||
gboolean * is_temp = FALSE;
|
||||
g_object_get(self->current_playlist, "ephemeral", &is_temp, NULL); // Get the current ephemeral value
|
||||
|
||||
if (is_temp) { // Is a temporary playlist
|
||||
|
@ -118,6 +148,6 @@ void koto_current_playlist_set_playlist(KotoCurrentPlaylist *self, KotoPlaylist
|
|||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_CURRENT_PLAYLIST]);
|
||||
}
|
||||
|
||||
KotoCurrentPlaylist* koto_current_playlist_new() {
|
||||
KotoCurrentPlaylist * koto_current_playlist_new() {
|
||||
return g_object_new(KOTO_TYPE_CURRENT_PLAYLIST, NULL);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ G_BEGIN_DECLS
|
|||
|
||||
/**
|
||||
* Type Definition
|
||||
**/
|
||||
**/
|
||||
|
||||
#define KOTO_TYPE_CURRENT_PLAYLIST koto_current_playlist_get_type()
|
||||
G_DECLARE_FINAL_TYPE(KotoCurrentPlaylist, koto_current_playlist, KOTO, CURRENT_PLAYLIST, GObject);
|
||||
|
@ -31,10 +31,15 @@ G_DECLARE_FINAL_TYPE(KotoCurrentPlaylist, koto_current_playlist, KOTO, CURRENT_P
|
|||
|
||||
/**
|
||||
* Current Playlist Functions
|
||||
**/
|
||||
**/
|
||||
|
||||
KotoCurrentPlaylist* koto_current_playlist_new();
|
||||
KotoPlaylist* koto_current_playlist_get_playlist(KotoCurrentPlaylist *self);
|
||||
void koto_current_playlist_set_playlist(KotoCurrentPlaylist *self, KotoPlaylist *playlist);
|
||||
KotoCurrentPlaylist * koto_current_playlist_new();
|
||||
|
||||
KotoPlaylist * koto_current_playlist_get_playlist(KotoCurrentPlaylist * self);
|
||||
|
||||
void koto_current_playlist_set_playlist(
|
||||
KotoCurrentPlaylist * self,
|
||||
KotoPlaylist * playlist
|
||||
);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include "../koto-utils.h"
|
||||
#include "playlist.h"
|
||||
|
||||
extern KotoCartographer *koto_maps;
|
||||
extern sqlite3 *koto_db;
|
||||
extern KotoCartographer * koto_maps;
|
||||
extern sqlite3 * koto_db;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
@ -46,11 +46,11 @@ enum {
|
|||
|
||||
struct _KotoPlaylist {
|
||||
GObject parent_instance;
|
||||
gchar *uuid;
|
||||
gchar *name;
|
||||
gchar *art_path;
|
||||
gchar * uuid;
|
||||
gchar * name;
|
||||
gchar * art_path;
|
||||
gint current_position;
|
||||
gchar *current_uuid;
|
||||
gchar * current_uuid;
|
||||
|
||||
KotoPreferredModelType model;
|
||||
|
||||
|
@ -58,32 +58,56 @@ struct _KotoPlaylist {
|
|||
gboolean is_shuffle_enabled;
|
||||
gboolean finalized;
|
||||
|
||||
GListStore *store;
|
||||
GQueue *sorted_tracks;
|
||||
GListStore * store;
|
||||
GQueue * sorted_tracks;
|
||||
|
||||
GQueue *tracks; // This is effectively our vanilla value that should never change
|
||||
GQueue *played_tracks;
|
||||
GQueue * tracks; // This is effectively our vanilla value that should never change
|
||||
GQueue * played_tracks;
|
||||
};
|
||||
|
||||
struct _KotoPlaylistClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* modified) (KotoPlaylist *playlist);
|
||||
void (* track_added) (KotoPlaylist *playlist, gchar *track_uuid);
|
||||
void (* track_load_finalized) (KotoPlaylist *playlist);
|
||||
void (* track_removed) (KotoPlaylist *playlist, gchar *track_uuid);
|
||||
void (* modified) (KotoPlaylist * playlist);
|
||||
void (* track_added) (
|
||||
KotoPlaylist * playlist,
|
||||
gchar * track_uuid
|
||||
);
|
||||
void (* track_load_finalized) (KotoPlaylist * playlist);
|
||||
void (* track_removed) (
|
||||
KotoPlaylist * playlist,
|
||||
gchar * track_uuid
|
||||
);
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(KotoPlaylist, koto_playlist, G_TYPE_OBJECT);
|
||||
|
||||
static GParamSpec *props[N_PROPERTIES] = { NULL };
|
||||
static guint playlist_signals[N_SIGNALS] = { 0 };
|
||||
static GParamSpec * props[N_PROPERTIES] = {
|
||||
NULL
|
||||
};
|
||||
static guint playlist_signals[N_SIGNALS] = {
|
||||
0
|
||||
};
|
||||
|
||||
static void koto_playlist_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
;
|
||||
static void koto_playlist_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
);
|
||||
|
||||
static void koto_playlist_class_init(KotoPlaylistClass * c) {
|
||||
GObjectClass * gobject_class;
|
||||
|
||||
static void koto_playlist_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec);;
|
||||
static void koto_playlist_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec);
|
||||
|
||||
static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
||||
GObjectClass *gobject_class;
|
||||
gobject_class = G_OBJECT_CLASS(c);
|
||||
gobject_class->set_property = koto_playlist_set_property;
|
||||
gobject_class->get_property = koto_playlist_get_property;
|
||||
|
@ -93,7 +117,7 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
"UUID of the Playlist",
|
||||
"UUID of the Playlist",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_NAME] = g_param_spec_string(
|
||||
|
@ -101,7 +125,7 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
"Name of the Playlist",
|
||||
"Name of the Playlist",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_ART_PATH] = g_param_spec_string(
|
||||
|
@ -109,7 +133,7 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
"Path to any associated artwork of the Playlist",
|
||||
"Path to any associated artwork of the Playlist",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_EPHEMERAL] = g_param_spec_boolean(
|
||||
|
@ -117,7 +141,7 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
"Is the playlist ephemeral (temporary)",
|
||||
"Is the playlist ephemeral (temporary)",
|
||||
FALSE,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_IS_SHUFFLE_ENABLED] = g_param_spec_boolean(
|
||||
|
@ -125,7 +149,7 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
"Is shuffling enabled",
|
||||
"Is shuffling enabled",
|
||||
FALSE,
|
||||
G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READWRITE
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
g_object_class_install_properties(gobject_class, N_PROPERTIES, props);
|
||||
|
@ -181,8 +205,14 @@ static void koto_playlist_class_init(KotoPlaylistClass *c) {
|
|||
);
|
||||
}
|
||||
|
||||
static void koto_playlist_get_property(GObject *obj, guint prop_id, GValue *val, GParamSpec *spec) {
|
||||
KotoPlaylist *self = KOTO_PLAYLIST(obj);
|
||||
static void koto_playlist_get_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoPlaylist * self = KOTO_PLAYLIST(obj);
|
||||
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UUID:
|
||||
|
@ -206,8 +236,14 @@ static void koto_playlist_get_property(GObject *obj, guint prop_id, GValue *val,
|
|||
}
|
||||
}
|
||||
|
||||
static void koto_playlist_set_property(GObject *obj, guint prop_id, const GValue *val, GParamSpec *spec) {
|
||||
KotoPlaylist *self = KOTO_PLAYLIST(obj);
|
||||
static void koto_playlist_set_property(
|
||||
GObject * obj,
|
||||
guint prop_id,
|
||||
const GValue * val,
|
||||
GParamSpec * spec
|
||||
) {
|
||||
KotoPlaylist * self = KOTO_PLAYLIST(obj);
|
||||
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_UUID:
|
||||
|
@ -231,7 +267,7 @@ static void koto_playlist_set_property(GObject *obj, guint prop_id, const GValue
|
|||
}
|
||||
}
|
||||
|
||||
static void koto_playlist_init(KotoPlaylist *self) {
|
||||
static void koto_playlist_init(KotoPlaylist * self) {
|
||||
self->current_position = -1; // Default to -1 so first time incrementing puts it at 0
|
||||
self->current_uuid = NULL;
|
||||
self->model = KOTO_PREFERRED_MODEL_TYPE_DEFAULT; // Default to default model
|
||||
|
@ -245,7 +281,10 @@ static void koto_playlist_init(KotoPlaylist *self) {
|
|||
self->store = g_list_store_new(KOTO_TYPE_INDEXED_TRACK);
|
||||
}
|
||||
|
||||
void koto_playlist_add_to_played_tracks(KotoPlaylist *self, gchar *uuid) {
|
||||
void koto_playlist_add_to_played_tracks(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
) {
|
||||
if (g_queue_index(self->played_tracks, uuid) != -1) { // Already added
|
||||
return;
|
||||
}
|
||||
|
@ -253,18 +292,31 @@ void koto_playlist_add_to_played_tracks(KotoPlaylist *self, gchar *uuid) {
|
|||
g_queue_push_tail(self->played_tracks, uuid); // Add to end
|
||||
}
|
||||
|
||||
void koto_playlist_add_track(KotoPlaylist *self, KotoIndexedTrack *track, gboolean current, gboolean commit_to_table) {
|
||||
void koto_playlist_add_track(
|
||||
KotoPlaylist * self,
|
||||
KotoIndexedTrack * track,
|
||||
gboolean current,
|
||||
gboolean commit_to_table
|
||||
) {
|
||||
koto_playlist_add_track_by_uuid(self, koto_indexed_track_get_uuid(track), current, commit_to_table);
|
||||
}
|
||||
|
||||
void koto_playlist_add_track_by_uuid(KotoPlaylist *self, gchar *uuid, gboolean current, gboolean commit_to_table) {
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, uuid); // Get the track
|
||||
void koto_playlist_add_track_by_uuid(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid,
|
||||
gboolean current,
|
||||
gboolean commit_to_table
|
||||
) {
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, uuid); // Get the track
|
||||
|
||||
|
||||
if (!KOTO_IS_INDEXED_TRACK(track)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GList *found_tracks_uuids = g_queue_find_custom(self->tracks, uuid, koto_playlist_compare_track_uuids);
|
||||
GList * found_tracks_uuids = g_queue_find_custom(self->tracks, uuid, koto_playlist_compare_track_uuids);
|
||||
|
||||
|
||||
if (found_tracks_uuids != NULL) { // Is somewhere in the tracks already
|
||||
g_list_free(found_tracks_uuids);
|
||||
return;
|
||||
|
@ -296,8 +348,13 @@ void koto_playlist_add_track_by_uuid(KotoPlaylist *self, gchar *uuid, gboolean c
|
|||
);
|
||||
}
|
||||
|
||||
void koto_playlist_apply_model(KotoPlaylist *self, KotoPreferredModelType preferred_model) {
|
||||
GList *sort_user_data = NULL;
|
||||
void koto_playlist_apply_model(
|
||||
KotoPlaylist * self,
|
||||
KotoPreferredModelType preferred_model
|
||||
) {
|
||||
GList * sort_user_data = NULL;
|
||||
|
||||
|
||||
sort_user_data = g_list_prepend(sort_user_data, GUINT_TO_POINTER(preferred_model)); // Prepend our preferred model first
|
||||
sort_user_data = g_list_prepend(sort_user_data, self); // Prepend ourself
|
||||
|
||||
|
@ -307,16 +364,16 @@ void koto_playlist_apply_model(KotoPlaylist *self, KotoPreferredModelType prefer
|
|||
self->model = preferred_model; // Update our preferred model
|
||||
|
||||
/*if (self->current_position != -1) { // Have a position set
|
||||
koto_playlist_set_track_as_current(self, self->current_uuid); // Update the position based on the new model just by setting it as current again
|
||||
}*/
|
||||
koto_playlist_set_track_as_current(self, self->current_uuid); // Update the position based on the new model just by setting it as current again
|
||||
}*/
|
||||
}
|
||||
|
||||
void koto_playlist_commit(KotoPlaylist *self) {
|
||||
void koto_playlist_commit(KotoPlaylist * self) {
|
||||
if (self->ephemeral) { // Temporary playlist
|
||||
return;
|
||||
}
|
||||
|
||||
gchar *commit_op = g_strdup_printf(
|
||||
gchar * commit_op = g_strdup_printf(
|
||||
"INSERT INTO playlist_meta(id, name, art_path, preferred_model)"
|
||||
"VALUES('%s', quote(\"%s\"), quote(\"%s\"), 0)"
|
||||
"ON CONFLICT(id) DO UPDATE SET name=excluded.name, art_path=excluded.art_path;",
|
||||
|
@ -325,9 +382,10 @@ void koto_playlist_commit(KotoPlaylist *self) {
|
|||
self->art_path
|
||||
);
|
||||
|
||||
gchar *commit_op_errmsg = NULL;
|
||||
gchar * commit_op_errmsg = NULL;
|
||||
int rc = sqlite3_exec(koto_db, commit_op, 0, 0, &commit_op_errmsg);
|
||||
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
g_warning("Failed to save playlist: %s", commit_op_errmsg);
|
||||
} else { // Successfully saved our playlist
|
||||
|
@ -338,49 +396,59 @@ void koto_playlist_commit(KotoPlaylist *self) {
|
|||
g_free(commit_op_errmsg);
|
||||
}
|
||||
|
||||
void koto_playlist_commit_tracks(gpointer data, gpointer user_data) {
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, data); // Get the track
|
||||
void koto_playlist_commit_tracks(
|
||||
gpointer data,
|
||||
gpointer user_data
|
||||
) {
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, data); // Get the track
|
||||
|
||||
|
||||
if (track == NULL) { // Not a track
|
||||
KotoPlaylist *self = user_data;
|
||||
gchar *playlist_uuid = self->uuid; // Get the playlist UUID
|
||||
KotoPlaylist * self = user_data;
|
||||
gchar * playlist_uuid = self->uuid; // Get the playlist UUID
|
||||
|
||||
gchar *current_track = g_queue_peek_nth(self->tracks, self->current_position); // Get the UUID of the current track
|
||||
gchar * current_track = g_queue_peek_nth(self->tracks, self->current_position); // Get the UUID of the current track
|
||||
//koto_indexed_track_save_to_playlist(track, playlist_uuid, (data == current_track) ? 1 : 0); // Call to save the playlist to the track
|
||||
g_free(playlist_uuid);
|
||||
g_free(current_track);
|
||||
}
|
||||
}
|
||||
|
||||
gint koto_playlist_compare_track_uuids(gconstpointer a, gconstpointer b) {
|
||||
gint koto_playlist_compare_track_uuids(
|
||||
gconstpointer a,
|
||||
gconstpointer b
|
||||
) {
|
||||
return g_strcmp0(a, b);
|
||||
}
|
||||
|
||||
gchar* koto_playlist_get_artwork(KotoPlaylist *self) {
|
||||
gchar * koto_playlist_get_artwork(KotoPlaylist * self) {
|
||||
return (self->art_path == NULL) ? NULL : g_strdup(self->art_path); // Return a duplicate of our art path
|
||||
}
|
||||
|
||||
KotoPreferredModelType koto_playlist_get_current_model(KotoPlaylist *self) {
|
||||
KotoPreferredModelType koto_playlist_get_current_model(KotoPlaylist * self) {
|
||||
return self->model;
|
||||
}
|
||||
|
||||
guint koto_playlist_get_current_position(KotoPlaylist *self) {
|
||||
guint koto_playlist_get_current_position(KotoPlaylist * self) {
|
||||
return self->current_position;
|
||||
}
|
||||
|
||||
gboolean koto_playlist_get_is_finalized(KotoPlaylist *self) {
|
||||
gboolean koto_playlist_get_is_finalized(KotoPlaylist * self) {
|
||||
return self->finalized;
|
||||
}
|
||||
|
||||
guint koto_playlist_get_length(KotoPlaylist *self) {
|
||||
guint koto_playlist_get_length(KotoPlaylist * self) {
|
||||
return g_queue_get_length(self->tracks); // Get the length of the tracks
|
||||
}
|
||||
|
||||
gchar* koto_playlist_get_name(KotoPlaylist *self) {
|
||||
gchar * koto_playlist_get_name(KotoPlaylist * self) {
|
||||
return (self->name == NULL) ? NULL : g_strdup(self->name);
|
||||
}
|
||||
|
||||
gint koto_playlist_get_position_of_track(KotoPlaylist *self, KotoIndexedTrack *track) {
|
||||
gint koto_playlist_get_position_of_track(
|
||||
KotoPlaylist * self,
|
||||
KotoIndexedTrack * track
|
||||
) {
|
||||
if (!KOTO_IS_PLAYLIST(self)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -396,17 +464,19 @@ gint koto_playlist_get_position_of_track(KotoPlaylist *self, KotoIndexedTrack *t
|
|||
gint position = -1;
|
||||
guint found_pos = 0;
|
||||
|
||||
if (g_list_store_find(self->store , track, &found_pos)) { // Found the item
|
||||
|
||||
if (g_list_store_find(self->store, track, &found_pos)) { // Found the item
|
||||
position = (gint) found_pos; // Cast our found position from guint to gint
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
gchar* koto_playlist_get_random_track(KotoPlaylist *self) {
|
||||
gchar *track_uuid = NULL;
|
||||
gchar * koto_playlist_get_random_track(KotoPlaylist * self) {
|
||||
gchar * track_uuid = NULL;
|
||||
guint tracks_len = g_queue_get_length(self->sorted_tracks);
|
||||
|
||||
|
||||
if (tracks_len == g_queue_get_length(self->played_tracks)) { // Played all tracks
|
||||
track_uuid = g_list_nth_data(self->sorted_tracks->head, 0); // Get the first
|
||||
g_queue_clear(self->played_tracks); // Clear our played tracks
|
||||
|
@ -414,10 +484,10 @@ gchar* koto_playlist_get_random_track(KotoPlaylist *self) {
|
|||
GRand* rando_calrissian = g_rand_new(); // Create a new RNG
|
||||
guint attempt = 0;
|
||||
|
||||
while (track_uuid == NULL) { // Haven't selected a track yet
|
||||
while (track_uuid == NULL) { // Haven't selected a track yet
|
||||
attempt++;
|
||||
gint32 selected_item = g_rand_int_range(rando_calrissian, 0, (gint32) tracks_len);
|
||||
gchar *selected_track = g_queue_peek_nth(self->sorted_tracks, (guint) selected_item); // Get the UUID of the selected item
|
||||
gchar * selected_track = g_queue_peek_nth(self->sorted_tracks, (guint) selected_item); // Get the UUID of the selected item
|
||||
|
||||
if (g_queue_index(self->played_tracks, selected_track) == -1) { // Haven't played the track
|
||||
self->current_position = (gint) selected_item;
|
||||
|
@ -436,25 +506,25 @@ gchar* koto_playlist_get_random_track(KotoPlaylist *self) {
|
|||
return track_uuid;
|
||||
}
|
||||
|
||||
GListStore* koto_playlist_get_store(KotoPlaylist *self) {
|
||||
GListStore * koto_playlist_get_store(KotoPlaylist * self) {
|
||||
return self->store;
|
||||
}
|
||||
|
||||
GQueue* koto_playlist_get_tracks(KotoPlaylist *self) {
|
||||
GQueue * koto_playlist_get_tracks(KotoPlaylist * self) {
|
||||
return self->tracks;
|
||||
}
|
||||
|
||||
gchar* koto_playlist_get_uuid(KotoPlaylist *self) {
|
||||
gchar * koto_playlist_get_uuid(KotoPlaylist * self) {
|
||||
return g_strdup(self->uuid);
|
||||
}
|
||||
|
||||
gchar* koto_playlist_go_to_next(KotoPlaylist *self) {
|
||||
gchar * koto_playlist_go_to_next(KotoPlaylist * self) {
|
||||
if (!KOTO_IS_PLAYLIST(self)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (self->is_shuffle_enabled) { // Shuffling enabled
|
||||
gchar *random_track_uuid = koto_playlist_get_random_track(self); // Get a random track
|
||||
gchar * random_track_uuid = koto_playlist_get_random_track(self); // Get a random track
|
||||
koto_playlist_add_to_played_tracks(self, random_track_uuid);
|
||||
return random_track_uuid;
|
||||
}
|
||||
|
@ -462,7 +532,7 @@ gchar* koto_playlist_go_to_next(KotoPlaylist *self) {
|
|||
if (!koto_utils_is_string_valid(self->current_uuid)) { // No valid UUID yet
|
||||
self->current_position++;
|
||||
} else { // Have a UUID currently
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, self->current_uuid);
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, self->current_uuid);
|
||||
|
||||
if (!KOTO_IS_INDEXED_TRACK(track)) {
|
||||
return NULL;
|
||||
|
@ -474,7 +544,7 @@ gchar* koto_playlist_go_to_next(KotoPlaylist *self) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
self->current_position = pos_of_song+1; // Increment our position based on position of song
|
||||
self->current_position = pos_of_song + 1; // Increment our position based on position of song
|
||||
}
|
||||
|
||||
self->current_uuid = g_queue_peek_nth(self->sorted_tracks, self->current_position);
|
||||
|
@ -483,7 +553,7 @@ gchar* koto_playlist_go_to_next(KotoPlaylist *self) {
|
|||
return self->current_uuid;
|
||||
}
|
||||
|
||||
gchar* koto_playlist_go_to_previous(KotoPlaylist *self) {
|
||||
gchar * koto_playlist_go_to_previous(KotoPlaylist * self) {
|
||||
if (self->is_shuffle_enabled) { // Shuffling enabled
|
||||
return koto_playlist_get_random_track(self); // Get a random track
|
||||
}
|
||||
|
@ -492,7 +562,8 @@ gchar* koto_playlist_go_to_previous(KotoPlaylist *self) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, self->current_uuid);
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, self->current_uuid);
|
||||
|
||||
|
||||
if (!KOTO_IS_INDEXED_TRACK(track)) {
|
||||
return NULL;
|
||||
|
@ -500,6 +571,7 @@ gchar* koto_playlist_go_to_previous(KotoPlaylist *self) {
|
|||
|
||||
gint pos_of_song = koto_playlist_get_position_of_track(self, track); // Get the position of the current track based on the current model
|
||||
|
||||
|
||||
if (pos_of_song == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -510,14 +582,14 @@ gchar* koto_playlist_go_to_previous(KotoPlaylist *self) {
|
|||
return self->current_uuid;
|
||||
}
|
||||
|
||||
void koto_playlist_mark_as_finalized(KotoPlaylist *self) {
|
||||
void koto_playlist_mark_as_finalized(KotoPlaylist * self) {
|
||||
if (self->finalized) { // Already finalized
|
||||
return;
|
||||
}
|
||||
|
||||
self->finalized = TRUE;
|
||||
koto_playlist_apply_model(self, self->model); // Re-apply our model to enforce mass sort
|
||||
|
||||
|
||||
g_signal_emit(
|
||||
self,
|
||||
playlist_signals[SIGNAL_TRACK_LOAD_FINALIZED],
|
||||
|
@ -525,24 +597,34 @@ void koto_playlist_mark_as_finalized(KotoPlaylist *self) {
|
|||
);
|
||||
}
|
||||
|
||||
gint koto_playlist_model_sort_by_uuid(gconstpointer first_item, gconstpointer second_item, gpointer data_list) {
|
||||
KotoIndexedTrack *first_track = koto_cartographer_get_track_by_uuid(koto_maps, (gchar*) first_item);
|
||||
KotoIndexedTrack *second_track = koto_cartographer_get_track_by_uuid(koto_maps, (gchar*) second_item);
|
||||
gint koto_playlist_model_sort_by_uuid(
|
||||
gconstpointer first_item,
|
||||
gconstpointer second_item,
|
||||
gpointer data_list
|
||||
) {
|
||||
KotoIndexedTrack * first_track = koto_cartographer_get_track_by_uuid(koto_maps, (gchar*) first_item);
|
||||
KotoIndexedTrack * second_track = koto_cartographer_get_track_by_uuid(koto_maps, (gchar*) second_item);
|
||||
|
||||
|
||||
return koto_playlist_model_sort_by_track(first_track, second_track, data_list);
|
||||
}
|
||||
|
||||
gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer second_item, gpointer data_list) {
|
||||
KotoIndexedTrack *first_track = (KotoIndexedTrack*) first_item;
|
||||
KotoIndexedTrack *second_track = (KotoIndexedTrack*) second_item;
|
||||
gint koto_playlist_model_sort_by_track(
|
||||
gconstpointer first_item,
|
||||
gconstpointer second_item,
|
||||
gpointer data_list
|
||||
) {
|
||||
KotoIndexedTrack * first_track = (KotoIndexedTrack*) first_item;
|
||||
KotoIndexedTrack * second_track = (KotoIndexedTrack*) second_item;
|
||||
|
||||
GList* ptr_list = data_list;
|
||||
KotoPlaylist *self = g_list_nth_data(ptr_list, 0); // First item in the GPtrArray is a pointer to our playlist
|
||||
KotoPlaylist * self = g_list_nth_data(ptr_list, 0); // First item in the GPtrArray is a pointer to our playlist
|
||||
KotoPreferredModelType model = GPOINTER_TO_UINT(g_list_nth_data(ptr_list, 1)); // Second item in the GPtrArray is a pointer to our KotoPreferredModelType
|
||||
|
||||
|
||||
if (
|
||||
(model == KOTO_PREFERRED_MODEL_TYPE_DEFAULT) || // Newest first model
|
||||
(model == KOTO_PREFERRED_MODEL_TYPE_OLDEST_FIRST) // Oldest first
|
||||
(model == KOTO_PREFERRED_MODEL_TYPE_DEFAULT) || // Newest first model
|
||||
(model == KOTO_PREFERRED_MODEL_TYPE_OLDEST_FIRST) // Oldest first
|
||||
) {
|
||||
gint first_track_pos = g_queue_index(self->tracks, koto_indexed_track_get_uuid(first_track));
|
||||
gint second_track_pos = g_queue_index(self->tracks, koto_indexed_track_get_uuid(second_track));
|
||||
|
@ -563,8 +645,8 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
}
|
||||
|
||||
if (model == KOTO_PREFERRED_MODEL_TYPE_SORT_BY_ALBUM) { // Sort by album name
|
||||
gchar *first_album_uuid = NULL;
|
||||
gchar *second_album_uuid = NULL;
|
||||
gchar * first_album_uuid = NULL;
|
||||
gchar * second_album_uuid = NULL;
|
||||
|
||||
g_object_get(
|
||||
first_track,
|
||||
|
@ -586,8 +668,8 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
return 0; // Don't get too granular, just consider them equal
|
||||
}
|
||||
|
||||
KotoIndexedAlbum *first_album = koto_cartographer_get_album_by_uuid(koto_maps, first_album_uuid);
|
||||
KotoIndexedAlbum *second_album = koto_cartographer_get_album_by_uuid(koto_maps, second_album_uuid);
|
||||
KotoIndexedAlbum * first_album = koto_cartographer_get_album_by_uuid(koto_maps, first_album_uuid);
|
||||
KotoIndexedAlbum * second_album = koto_cartographer_get_album_by_uuid(koto_maps, second_album_uuid);
|
||||
|
||||
g_free(first_album_uuid);
|
||||
g_free(second_album_uuid);
|
||||
|
@ -600,8 +682,8 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
}
|
||||
|
||||
if (model == KOTO_PREFERRED_MODEL_TYPE_SORT_BY_ARTIST) { // Sort by artist name
|
||||
gchar *first_artist_uuid = NULL;
|
||||
gchar *second_artist_uuid = NULL;
|
||||
gchar * first_artist_uuid = NULL;
|
||||
gchar * second_artist_uuid = NULL;
|
||||
|
||||
g_object_get(
|
||||
first_track,
|
||||
|
@ -617,8 +699,8 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
NULL
|
||||
);
|
||||
|
||||
KotoIndexedArtist *first_artist = koto_cartographer_get_artist_by_uuid(koto_maps, first_artist_uuid);
|
||||
KotoIndexedArtist *second_artist = koto_cartographer_get_artist_by_uuid(koto_maps, second_artist_uuid);
|
||||
KotoIndexedArtist * first_artist = koto_cartographer_get_artist_by_uuid(koto_maps, first_artist_uuid);
|
||||
KotoIndexedArtist * second_artist = koto_cartographer_get_artist_by_uuid(koto_maps, second_artist_uuid);
|
||||
|
||||
g_free(first_artist_uuid);
|
||||
g_free(second_artist_uuid);
|
||||
|
@ -631,8 +713,8 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
}
|
||||
|
||||
if (model == KOTO_PREFERRED_MODEL_TYPE_SORT_BY_TRACK_NAME) { // Track name
|
||||
gchar *first_track_name = NULL;
|
||||
gchar *second_track_name = NULL;
|
||||
gchar * first_track_name = NULL;
|
||||
gchar * second_track_name = NULL;
|
||||
|
||||
g_object_get(
|
||||
first_track,
|
||||
|
@ -658,28 +740,37 @@ gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer s
|
|||
return 0;
|
||||
}
|
||||
|
||||
void koto_playlist_remove_from_played_tracks(KotoPlaylist *self, gchar *uuid) {
|
||||
void koto_playlist_remove_from_played_tracks(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
) {
|
||||
g_queue_remove(self->played_tracks, uuid);
|
||||
}
|
||||
|
||||
void koto_playlist_remove_track_by_uuid(KotoPlaylist *self, gchar *uuid) {
|
||||
void koto_playlist_remove_track_by_uuid(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
) {
|
||||
if (!KOTO_IS_PLAYLIST(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gint file_index = g_queue_index(self->tracks, uuid); // Get the position of this uuid
|
||||
|
||||
|
||||
if (file_index != -1) { // Have in tracks
|
||||
g_queue_pop_nth(self->tracks, file_index); // Remove nth where it is the file index
|
||||
}
|
||||
|
||||
gint file_index_in_sorted = g_queue_index(self->sorted_tracks, uuid); // Get position in sorted tracks
|
||||
|
||||
|
||||
if (file_index_in_sorted != -1) { // Have in sorted tracks
|
||||
g_queue_pop_nth(self->sorted_tracks, file_index_in_sorted); // Remove nth where it is the index in sorted tracks
|
||||
}
|
||||
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, uuid); // Get the track
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, uuid); // Get the track
|
||||
|
||||
|
||||
if (!KOTO_IS_INDEXED_TRACK(track)) { // Is not a track
|
||||
return;
|
||||
|
@ -687,6 +778,7 @@ void koto_playlist_remove_track_by_uuid(KotoPlaylist *self, gchar *uuid) {
|
|||
|
||||
guint position = 0;
|
||||
|
||||
|
||||
if (g_list_store_find(self->store, track, &position)) { // Got the position
|
||||
g_list_store_remove(self->store, position); // Remove from the store
|
||||
}
|
||||
|
@ -701,13 +793,17 @@ void koto_playlist_remove_track_by_uuid(KotoPlaylist *self, gchar *uuid) {
|
|||
);
|
||||
}
|
||||
|
||||
void koto_playlist_set_artwork(KotoPlaylist *self, const gchar *path) {
|
||||
void koto_playlist_set_artwork(
|
||||
KotoPlaylist * self,
|
||||
const gchar * path
|
||||
) {
|
||||
if (path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
magic_t cookie = magic_open(MAGIC_MIME); // Create our magic cookie so we can validate if what we are setting is an image
|
||||
|
||||
|
||||
if (cookie == NULL) { // Failed to allocate
|
||||
return;
|
||||
}
|
||||
|
@ -716,7 +812,8 @@ void koto_playlist_set_artwork(KotoPlaylist *self, const gchar *path) {
|
|||
goto free_cookie;
|
||||
}
|
||||
|
||||
const gchar *mime_type = magic_file(cookie, path); // Get the mimetype for this file
|
||||
const gchar * mime_type = magic_file(cookie, path); // Get the mimetype for this file
|
||||
|
||||
|
||||
if ((mime_type == NULL) || !g_str_has_prefix(mime_type, "image/")) { // Failed to get our mimetype or not an image
|
||||
goto free_cookie;
|
||||
|
@ -737,10 +834,13 @@ void koto_playlist_set_artwork(KotoPlaylist *self, const gchar *path) {
|
|||
}
|
||||
|
||||
free_cookie:
|
||||
magic_close(cookie); // Close and free the cookie to the cookie monster
|
||||
magic_close(cookie); // Close and free the cookie to the cookie monster
|
||||
}
|
||||
|
||||
void koto_playlist_set_name(KotoPlaylist *self, const gchar *name) {
|
||||
void koto_playlist_set_name(
|
||||
KotoPlaylist * self,
|
||||
const gchar * name
|
||||
) {
|
||||
if (name == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -760,19 +860,29 @@ void koto_playlist_set_name(KotoPlaylist *self, const gchar *name) {
|
|||
}
|
||||
}
|
||||
|
||||
void koto_playlist_set_position(KotoPlaylist *self, gint position) {
|
||||
void koto_playlist_set_position(
|
||||
KotoPlaylist * self,
|
||||
gint position
|
||||
) {
|
||||
self->current_position = position;
|
||||
}
|
||||
|
||||
void koto_playlist_set_track_as_current(KotoPlaylist *self, gchar *track_uuid) {
|
||||
void koto_playlist_set_track_as_current(
|
||||
KotoPlaylist * self,
|
||||
gchar * track_uuid
|
||||
) {
|
||||
gint position_of_track = g_queue_index(self->sorted_tracks, track_uuid); // Get the position of the UUID in our tracks
|
||||
|
||||
|
||||
if (position_of_track != -1) { // In tracks
|
||||
self->current_position = position_of_track;
|
||||
}
|
||||
}
|
||||
|
||||
void koto_playlist_set_uuid(KotoPlaylist *self, const gchar *uuid) {
|
||||
void koto_playlist_set_uuid(
|
||||
KotoPlaylist * self,
|
||||
const gchar * uuid
|
||||
) {
|
||||
if (uuid == NULL) { // No actual UUID
|
||||
return;
|
||||
}
|
||||
|
@ -784,9 +894,13 @@ void koto_playlist_set_uuid(KotoPlaylist *self, const gchar *uuid) {
|
|||
self->uuid = g_strdup(uuid); // Set the new UUID
|
||||
}
|
||||
|
||||
void koto_playlist_tracks_queue_push_to_store(gpointer data, gpointer user_data) {
|
||||
gchar *track_uuid = (gchar *) data;
|
||||
KotoIndexedTrack *track = koto_cartographer_get_track_by_uuid(koto_maps, track_uuid);
|
||||
void koto_playlist_tracks_queue_push_to_store(
|
||||
gpointer data,
|
||||
gpointer user_data
|
||||
) {
|
||||
gchar * track_uuid = (gchar*) data;
|
||||
KotoIndexedTrack * track = koto_cartographer_get_track_by_uuid(koto_maps, track_uuid);
|
||||
|
||||
|
||||
if (!KOTO_IS_INDEXED_TRACK(track)) { // Not a track
|
||||
return;
|
||||
|
@ -795,20 +909,24 @@ void koto_playlist_tracks_queue_push_to_store(gpointer data, gpointer user_data)
|
|||
g_list_store_append(G_LIST_STORE(user_data), track);
|
||||
}
|
||||
|
||||
void koto_playlist_unmap(KotoPlaylist *self) {
|
||||
void koto_playlist_unmap(KotoPlaylist * self) {
|
||||
koto_cartographer_remove_playlist_by_uuid(koto_maps, self->uuid); // Remove from our cartographer
|
||||
}
|
||||
|
||||
KotoPlaylist* koto_playlist_new() {
|
||||
return g_object_new(KOTO_TYPE_PLAYLIST,
|
||||
"uuid", g_uuid_string_random(),
|
||||
KotoPlaylist * koto_playlist_new() {
|
||||
return g_object_new(
|
||||
KOTO_TYPE_PLAYLIST,
|
||||
"uuid",
|
||||
g_uuid_string_random(),
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
KotoPlaylist* koto_playlist_new_with_uuid(const gchar *uuid) {
|
||||
return g_object_new(KOTO_TYPE_PLAYLIST,
|
||||
"uuid", uuid,
|
||||
KotoPlaylist * koto_playlist_new_with_uuid(const gchar * uuid) {
|
||||
return g_object_new(
|
||||
KOTO_TYPE_PLAYLIST,
|
||||
"uuid",
|
||||
uuid,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ typedef enum {
|
|||
|
||||
/**
|
||||
* Type Definition
|
||||
**/
|
||||
**/
|
||||
|
||||
#define KOTO_TYPE_PLAYLIST koto_playlist_get_type()
|
||||
#define KOTO_PLAYLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KOTO_TYPE_PLAYLIST, KotoPlaylist))
|
||||
#define KOTO_PLAYLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), KOTO_TYPE_PLAYLIST, KotoPlaylist))
|
||||
#define KOTO_IS_PLAYLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), KOTO_TYPE_PLAYLIST))
|
||||
|
||||
typedef struct _KotoPlaylist KotoPlaylist;
|
||||
|
@ -46,41 +46,131 @@ GType koto_playlist_get_type(void) G_GNUC_CONST;
|
|||
|
||||
/**
|
||||
* Playlist Functions
|
||||
**/
|
||||
**/
|
||||
|
||||
KotoPlaylist* koto_playlist_new();
|
||||
KotoPlaylist* koto_playlist_new_with_uuid(const gchar *uuid);
|
||||
void koto_playlist_add_to_played_tracks(KotoPlaylist *self, gchar *uuid);
|
||||
void koto_playlist_add_track(KotoPlaylist *self, KotoIndexedTrack *track, gboolean current, gboolean commit_to_table);
|
||||
void koto_playlist_add_track_by_uuid(KotoPlaylist *self, gchar *uuid, gboolean current, gboolean commit_to_table);
|
||||
void koto_playlist_apply_model(KotoPlaylist *self, KotoPreferredModelType preferred_model);
|
||||
void koto_playlist_commit(KotoPlaylist *self);
|
||||
void koto_playlist_commit_tracks(gpointer data, gpointer user_data);
|
||||
gint koto_playlist_compare_track_uuids(gconstpointer a, gconstpointer b);
|
||||
gchar* koto_playlist_get_artwork(KotoPlaylist *self);
|
||||
KotoPreferredModelType koto_playlist_get_current_model(KotoPlaylist *self);
|
||||
guint koto_playlist_get_current_position(KotoPlaylist *self);
|
||||
guint koto_playlist_get_length(KotoPlaylist *self);
|
||||
gboolean koto_playlist_get_is_finalized(KotoPlaylist *self);
|
||||
gchar* koto_playlist_get_name(KotoPlaylist *self);
|
||||
gint koto_playlist_get_position_of_track(KotoPlaylist *self, KotoIndexedTrack *track);
|
||||
GListStore* koto_playlist_get_store(KotoPlaylist *self);
|
||||
GQueue* koto_playlist_get_tracks(KotoPlaylist *self);
|
||||
gchar* koto_playlist_get_uuid(KotoPlaylist *self);
|
||||
gchar* koto_playlist_go_to_next(KotoPlaylist *self);
|
||||
gchar* koto_playlist_go_to_previous(KotoPlaylist *self);
|
||||
void koto_playlist_mark_as_finalized(KotoPlaylist *self);
|
||||
gint koto_playlist_model_sort_by_uuid(gconstpointer first_item, gconstpointer second_item, gpointer data_list);
|
||||
gint koto_playlist_model_sort_by_track(gconstpointer first_item, gconstpointer second_item, gpointer model_ptr);
|
||||
void koto_playlist_remove_from_played_tracks(KotoPlaylist *self, gchar *uuid);
|
||||
void koto_playlist_remove_track_by_uuid(KotoPlaylist *self, gchar *uuid);
|
||||
void koto_playlist_set_artwork(KotoPlaylist *self, const gchar *path);
|
||||
void koto_playlist_save_state(KotoPlaylist *self);
|
||||
void koto_playlist_set_name(KotoPlaylist *self, const gchar *name);
|
||||
void koto_playlist_set_position(KotoPlaylist *self, gint position);
|
||||
void koto_playlist_set_track_as_current(KotoPlaylist *self, gchar *track_uuid);
|
||||
void koto_playlist_set_uuid(KotoPlaylist *self, const gchar *uuid);
|
||||
void koto_playlist_tracks_queue_push_to_store(gpointer data, gpointer user_data);
|
||||
void koto_playlist_unmap(KotoPlaylist *self);
|
||||
KotoPlaylist * koto_playlist_new();
|
||||
|
||||
KotoPlaylist * koto_playlist_new_with_uuid(const gchar * uuid);
|
||||
|
||||
void koto_playlist_add_to_played_tracks(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
);
|
||||
|
||||
void koto_playlist_add_track(
|
||||
KotoPlaylist * self,
|
||||
KotoIndexedTrack * track,
|
||||
gboolean current,
|
||||
gboolean commit_to_table
|
||||
);
|
||||
|
||||
void koto_playlist_add_track_by_uuid(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid,
|
||||
gboolean current,
|
||||
gboolean commit_to_table
|
||||
);
|
||||
|
||||
void koto_playlist_apply_model(
|
||||
KotoPlaylist * self,
|
||||
KotoPreferredModelType preferred_model
|
||||
);
|
||||
|
||||
void koto_playlist_commit(KotoPlaylist * self);
|
||||
|
||||
void koto_playlist_commit_tracks(
|
||||
gpointer data,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
gint koto_playlist_compare_track_uuids(
|
||||
gconstpointer a,
|
||||
gconstpointer b
|
||||
);
|
||||
|
||||
gchar * koto_playlist_get_artwork(KotoPlaylist * self);
|
||||
|
||||
KotoPreferredModelType koto_playlist_get_current_model(KotoPlaylist * self);
|
||||
|
||||
guint koto_playlist_get_current_position(KotoPlaylist * self);
|
||||
|
||||
guint koto_playlist_get_length(KotoPlaylist * self);
|
||||
|
||||
gboolean koto_playlist_get_is_finalized(KotoPlaylist * self);
|
||||
|
||||
gchar * koto_playlist_get_name(KotoPlaylist * self);
|
||||
|
||||
gint koto_playlist_get_position_of_track(
|
||||
KotoPlaylist * self,
|
||||
KotoIndexedTrack * track
|
||||
);
|
||||
|
||||
GListStore * koto_playlist_get_store(KotoPlaylist * self);
|
||||
|
||||
GQueue * koto_playlist_get_tracks(KotoPlaylist * self);
|
||||
|
||||
gchar * koto_playlist_get_uuid(KotoPlaylist * self);
|
||||
|
||||
gchar * koto_playlist_go_to_next(KotoPlaylist * self);
|
||||
|
||||
gchar * koto_playlist_go_to_previous(KotoPlaylist * self);
|
||||
|
||||
void koto_playlist_mark_as_finalized(KotoPlaylist * self);
|
||||
|
||||
gint koto_playlist_model_sort_by_uuid(
|
||||
gconstpointer first_item,
|
||||
gconstpointer second_item,
|
||||
gpointer data_list
|
||||
);
|
||||
|
||||
gint koto_playlist_model_sort_by_track(
|
||||
gconstpointer first_item,
|
||||
gconstpointer second_item,
|
||||
gpointer model_ptr
|
||||
);
|
||||
|
||||
void koto_playlist_remove_from_played_tracks(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
);
|
||||
|
||||
void koto_playlist_remove_track_by_uuid(
|
||||
KotoPlaylist * self,
|
||||
gchar * uuid
|
||||
);
|
||||
|
||||
void koto_playlist_set_artwork(
|
||||
KotoPlaylist * self,
|
||||
const gchar * path
|
||||
);
|
||||
|
||||
void koto_playlist_save_state(KotoPlaylist * self);
|
||||
|
||||
void koto_playlist_set_name(
|
||||
KotoPlaylist * self,
|
||||
const gchar * name
|
||||
);
|
||||
|
||||
void koto_playlist_set_position(
|
||||
KotoPlaylist * self,
|
||||
gint position
|
||||
);
|
||||
|
||||
void koto_playlist_set_track_as_current(
|
||||
KotoPlaylist * self,
|
||||
gchar * track_uuid
|
||||
);
|
||||
|
||||
void koto_playlist_set_uuid(
|
||||
KotoPlaylist * self,
|
||||
const gchar * uuid
|
||||
);
|
||||
|
||||
void koto_playlist_tracks_queue_push_to_store(
|
||||
gpointer data,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
void koto_playlist_unmap(KotoPlaylist * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue