Get to the point where we are fairly happy with our uncrustify config. Fixes #6.

This commit is contained in:
Joshua Strobl 2021-05-11 20:05:04 +03:00
parent d07d3dfe50
commit 62de9c2032
58 changed files with 4811 additions and 1946 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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
);
}

View file

@ -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