2021-02-16 17:15:10 +02:00
|
|
|
/* koto-utils.c
|
|
|
|
*
|
|
|
|
* Copyright 2021 Joshua Strobl
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <glib-2.0/glib.h>
|
2021-02-24 20:17:18 +02:00
|
|
|
#include <gtk-4.0/gtk/gtk.h>
|
2021-06-22 16:48:13 +03:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
2021-07-08 18:37:52 +03:00
|
|
|
#include "koto-utils.h"
|
2021-02-24 20:17:18 +02:00
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
extern GtkWindow * main_window;
|
2021-05-07 16:45:57 +03:00
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
GtkFileChooserNative * koto_utils_create_image_file_chooser(gchar * file_chooser_label) {
|
2021-05-27 16:58:28 +03:00
|
|
|
GtkFileChooserNative * chooser = gtk_file_chooser_native_new(
|
2021-05-07 16:45:57 +03:00
|
|
|
file_chooser_label,
|
|
|
|
main_window,
|
|
|
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
|
|
"Choose",
|
|
|
|
"Cancel"
|
|
|
|
);
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
GtkFileFilter * image_filter = gtk_file_filter_new(); // Create our file filter
|
|
|
|
|
2021-05-07 16:45:57 +03:00
|
|
|
gtk_file_filter_add_mime_type(image_filter, "image/*"); // Only allow for images
|
|
|
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(chooser), image_filter); // Only allow picking images
|
|
|
|
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(chooser), FALSE);
|
|
|
|
|
|
|
|
return chooser;
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
GtkWidget * koto_utils_create_image_from_filepath(
|
|
|
|
gchar * filepath,
|
|
|
|
gchar * fallback_icon,
|
|
|
|
guint width,
|
|
|
|
guint height
|
|
|
|
) {
|
2021-05-27 16:58:28 +03:00
|
|
|
GtkWidget * image = NULL;
|
2021-05-11 20:05:04 +03:00
|
|
|
|
2021-03-10 13:44:08 +02:00
|
|
|
if ((filepath != NULL) && (strcmp(filepath, "") != 0)) { // If we have a filepath
|
2021-02-24 20:17:18 +02:00
|
|
|
if (g_file_test(filepath, G_FILE_TEST_EXISTS)) { // File exists
|
|
|
|
image = gtk_image_new_from_file(filepath); // Load from the filepath
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GTK_IS_IMAGE(image)) { // If we failed to get the image or never passed a valid filepath to begin with
|
|
|
|
image = gtk_image_new_from_icon_name(fallback_icon); // Set to the fallback icon
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_image_set_icon_size(GTK_IMAGE(image), GTK_ICON_SIZE_INHERIT);
|
2021-02-25 18:15:36 +02:00
|
|
|
gtk_image_set_pixel_size(GTK_IMAGE(image), width);
|
2021-02-24 20:17:18 +02:00
|
|
|
gtk_widget_set_size_request(image, width, height);
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
2021-02-16 17:15:10 +02:00
|
|
|
|
2021-05-27 12:56:36 +03:00
|
|
|
gchar * koto_utils_gboolean_to_string(gboolean b) {
|
|
|
|
return g_strdup(b ? "true" : "false");
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * koto_utils_get_filename_without_extension(gchar * filename) {
|
2021-06-22 16:48:13 +03:00
|
|
|
gchar * trimmed_file_name = g_strdup(g_path_get_basename(filename)); // Ensure the filename provided is the base name of any possible path and duplicate it
|
|
|
|
gchar ** split = g_strsplit(trimmed_file_name, ".", -1); // Split every time we see .
|
2021-05-11 20:05:04 +03:00
|
|
|
|
2021-02-16 17:15:10 +02:00
|
|
|
g_free(trimmed_file_name);
|
|
|
|
guint len_of_extension_split = g_strv_length(split);
|
|
|
|
|
|
|
|
if (len_of_extension_split == 2) { // Only have two elements
|
|
|
|
trimmed_file_name = g_strdup(split[0]); // Get the first element
|
|
|
|
} else {
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * new_parsed_name = "";
|
2021-02-16 17:15:10 +02:00
|
|
|
for (guint i = 0; i < len_of_extension_split - 1; i++) { // Iterate over everything except the last item
|
|
|
|
if (g_strcmp0(new_parsed_name, "") == 0) { // Currently empty
|
|
|
|
new_parsed_name = g_strdup(split[i]); // Just duplicate this string
|
|
|
|
} else {
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * tmp_copy = g_strdup(new_parsed_name);
|
2021-02-16 17:15:10 +02:00
|
|
|
g_free(new_parsed_name); // Free the old
|
2021-03-09 11:45:44 +02:00
|
|
|
new_parsed_name = g_strjoin(".", tmp_copy, split[i], NULL); // Join the two strings with a . again and duplicate it, setting it to our new_parsed_name
|
2021-02-16 17:15:10 +02:00
|
|
|
g_free(tmp_copy); // Free our temporary copy
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trimmed_file_name = g_strdup(new_parsed_name);
|
|
|
|
g_free(new_parsed_name);
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * stripped_file_name = g_strstrip(g_strdup(trimmed_file_name)); // Strip leading and trailing whitespace
|
|
|
|
|
2021-02-16 17:15:10 +02:00
|
|
|
g_free(trimmed_file_name);
|
2021-08-10 19:18:46 +03:00
|
|
|
g_strfreev(split);
|
2021-02-16 17:15:10 +02:00
|
|
|
return stripped_file_name;
|
|
|
|
}
|
2021-03-09 11:45:44 +02:00
|
|
|
|
2021-07-08 18:37:52 +03:00
|
|
|
gchar * koto_utils_join_string_list (
|
|
|
|
GList * list,
|
|
|
|
gchar * sep
|
|
|
|
) {
|
|
|
|
gchar * liststring = NULL;
|
|
|
|
GList * cur_list;
|
|
|
|
for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { // For each item in the list
|
|
|
|
gchar * current_item = cur_list->data;
|
2021-08-10 19:18:46 +03:00
|
|
|
if (!koto_utils_string_is_valid(current_item)) { // Not a valid string
|
2021-07-08 18:37:52 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar * item_plus_sep = g_strdup_printf("%s%s", current_item, sep);
|
|
|
|
|
2021-08-10 19:18:46 +03:00
|
|
|
if (koto_utils_string_is_valid(liststring)) { // Is a valid string
|
2021-07-08 18:37:52 +03:00
|
|
|
gchar * new_string = g_strconcat(liststring, item_plus_sep, NULL);
|
|
|
|
g_free(liststring);
|
|
|
|
liststring = new_string;
|
|
|
|
} else { // Don't have any content yet
|
|
|
|
liststring = item_plus_sep;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (liststring == NULL) ? g_strdup("") : liststring;
|
|
|
|
}
|
2021-06-22 16:48:13 +03:00
|
|
|
void koto_utils_mkdir(gchar * path) {
|
|
|
|
mkdir(path, 0755);
|
|
|
|
chown(path, getuid(), getgid());
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
void koto_utils_push_queue_element_to_store(
|
|
|
|
gpointer data,
|
|
|
|
gpointer user_data
|
|
|
|
) {
|
2021-05-07 16:45:57 +03:00
|
|
|
g_list_store_append(G_LIST_STORE(user_data), data);
|
|
|
|
}
|
|
|
|
|
2021-08-10 19:18:46 +03:00
|
|
|
gchar * koto_utils_seconds_to_time_format(guint64 seconds) {
|
|
|
|
GDateTime * date = g_date_time_new_from_unix_utc(seconds); // Add our seconds after UTC
|
|
|
|
gchar * date_string = g_date_time_format(date, (g_date_time_get_hour(date) != 0) ? "%H:%M:%S" : "%M:%S");
|
|
|
|
g_date_time_unref(date);
|
|
|
|
return date_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean koto_utils_string_contains_substring(
|
|
|
|
gchar * s,
|
|
|
|
gchar * sub
|
|
|
|
) {
|
|
|
|
gchar ** separated_string = g_strsplit(s, sub, -1); // Split on our substring
|
|
|
|
gboolean contains = (g_strv_length(separated_string) > 1);
|
|
|
|
g_strfreev(separated_string);
|
|
|
|
return contains;
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar * koto_utils_string_get_valid(gchar * str) {
|
|
|
|
return koto_utils_string_is_valid(str) ? str : g_strdup(""); // Return string if a string, otherwise return an empty string
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean koto_utils_string_is_valid(const gchar * str) {
|
|
|
|
return ((str != NULL) && (g_strcmp0(str, "") != 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar * koto_utils_string_replace_all(
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * str,
|
|
|
|
gchar * find,
|
|
|
|
gchar * repl
|
|
|
|
) {
|
2021-08-10 19:18:46 +03:00
|
|
|
if (!koto_utils_string_is_valid(str)) { // Not a valid string
|
2021-07-08 19:58:54 +03:00
|
|
|
return g_strdup("");
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar ** split = g_strsplit(str, find, -1); // Split on find
|
|
|
|
|
2021-07-08 18:37:52 +03:00
|
|
|
guint split_len = g_strv_length(split);
|
|
|
|
|
|
|
|
if (split_len == 1) { // Only one item
|
|
|
|
g_strfreev(split);
|
|
|
|
return g_strdup(str); // Just set to the string we were provided
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_strdup(g_strjoinv(repl, split));
|
|
|
|
}
|
|
|
|
|
|
|
|
GList * koto_utils_string_to_string_list(
|
|
|
|
gchar * s,
|
|
|
|
gchar * sep
|
|
|
|
) {
|
|
|
|
GList * list = NULL;
|
2021-08-10 19:18:46 +03:00
|
|
|
if (!koto_utils_string_is_valid(s)) { // Provided string is not valid
|
2021-07-08 19:58:54 +03:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2021-07-08 18:37:52 +03:00
|
|
|
gchar ** separated_strings = g_strsplit(s, sep, -1); // Split on separator for the string
|
|
|
|
|
|
|
|
for (guint i = 0; i < g_strv_length(separated_strings); i++) { // Iterate over each item
|
|
|
|
gchar * item = separated_strings[i];
|
2021-08-10 19:18:46 +03:00
|
|
|
if (g_strcmp0(item, "") != 0) { // Not an empty string
|
|
|
|
list = g_list_append(list, g_strdup(item));
|
|
|
|
}
|
2021-04-06 10:41:15 +03:00
|
|
|
}
|
|
|
|
|
2021-07-08 18:37:52 +03:00
|
|
|
g_strfreev(separated_strings); // Free our strings
|
|
|
|
return list;
|
2021-04-06 10:41:15 +03:00
|
|
|
}
|
|
|
|
|
2021-08-10 19:18:46 +03:00
|
|
|
gchar * koto_utils_string_title(const gchar * s) {
|
|
|
|
if (!koto_utils_string_is_valid(s)) { // Not a valid string
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
glong len = g_utf8_strlen(s, -1);
|
|
|
|
|
|
|
|
if (len == 0) { // Empty string
|
|
|
|
return g_strdup(s); // Just duplicate itself
|
|
|
|
} else if (len == 1) { // One char
|
|
|
|
return g_utf8_strup(s, -1); // Uppercase all relevant cases
|
|
|
|
} else {
|
|
|
|
gchar * first_char = g_utf8_substring(s, 0, 1);
|
|
|
|
gchar * rest_of_string = g_utf8_substring(s, 1, len); // Rest of string
|
|
|
|
gchar * titled_string = g_strdup_printf("%s%s", g_utf8_strup(first_char, -1), rest_of_string);
|
|
|
|
|
|
|
|
g_free(first_char);
|
|
|
|
g_free(rest_of_string);
|
|
|
|
return titled_string;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar * koto_utils_string_unquote(gchar * s) {
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar * new_s = NULL;
|
|
|
|
|
2021-08-10 19:18:46 +03:00
|
|
|
if (!koto_utils_string_is_valid(s)) { // Not a valid string
|
2021-07-08 19:58:54 +03:00
|
|
|
new_s = g_strdup("");
|
|
|
|
return new_s;
|
|
|
|
}
|
|
|
|
|
2021-03-09 11:45:44 +02:00
|
|
|
if (g_str_has_prefix(s, "'") && g_str_has_suffix(s, "'")) { // Begins and ends with '
|
2021-05-11 20:05:04 +03:00
|
|
|
new_s = g_utf8_substring(s, 1, g_utf8_strlen(s, -1) - 1); // Start at 1 and end at n-1
|
2021-03-09 11:45:44 +02:00
|
|
|
} else {
|
|
|
|
new_s = g_strdup(s);
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:05:04 +03:00
|
|
|
gchar ** split_on_double_single = g_strsplit(new_s, "''", -1); // Split on instances of ''
|
|
|
|
|
2021-03-09 11:45:44 +02:00
|
|
|
new_s = g_strjoinv("'", split_on_double_single); // Rejoin as '
|
|
|
|
g_strfreev(split_on_double_single); // Free our array
|
|
|
|
|
|
|
|
return new_s;
|
|
|
|
}
|