Advertisement
Guest User

Untitled

a guest
Jul 28th, 2024
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.75 KB | Software | 0 0
  1. #include <gtk/gtk.h>
  2. #include <gio/gio.h>
  3. #include <gdk/gdkx.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #define DESKTOP_PATH g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)
  9.  
  10. enum {
  11.     COL_DISPLAY_NAME,
  12.     COL_PIXBUF,
  13.     COL_FILE_PATH,
  14.     NUM_COLS
  15. };
  16.  
  17. typedef struct {
  18.     GtkWidget *window;
  19.     GtkWidget *icon_view;
  20.     GtkWidget *scrolled_window;
  21.     GtkListStore *store;
  22. } DesktopManager;
  23.  
  24. static void set_background_color(GtkWidget *widget) {
  25.     GdkRGBA color;
  26.     GtkStyleContext *context;
  27.    GtkCssProvider *provider;
  28.    
  29.    provider = gtk_css_provider_new();
  30.   gtk_css_provider_load_from_data(provider,
  31.        "iconview.view { background-color: #316da5; color: #fff }", -1, NULL);
  32.  
  33.     context = gtk_widget_get_style_context(widget);
  34.     gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
  35. }
  36.  
  37. static void create_desktop_icon(DesktopManager *dm, const char *filename);
  38. static void on_item_activated(GtkIconView *icon_view, GtkTreePath *path, gpointer user_data);
  39. static void load_desktop_icons(DesktopManager *dm);
  40. static GdkPixbuf *load_icon_from_desktop_file(const char *desktop_file_path, int size);
  41. static char *get_desktop_file_name(const char *desktop_file_path);
  42.  
  43. static GdkPixbuf *load_icon_from_desktop_file(const char *desktop_file_path, int size) {
  44.     GKeyFile *key_file;
  45.     GdkPixbuf *pixbuf = NULL;
  46.     char *icon_name;
  47.     GError *error = NULL;
  48.  
  49.     key_file = g_key_file_new();
  50.     if (!g_key_file_load_from_file(key_file, desktop_file_path, G_KEY_FILE_NONE, &error)) {
  51.         g_print("Error loading .desktop file: %s\n", error->message);
  52.         g_error_free(error);
  53.         g_key_file_free(key_file);
  54.         return NULL;
  55.     }
  56.  
  57.     icon_name = g_key_file_get_string(key_file, "Desktop Entry", "Icon", NULL);
  58.     if (icon_name) {
  59.         GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
  60.         if (g_path_is_absolute(icon_name)) {
  61.             pixbuf = gdk_pixbuf_new_from_file_at_size(icon_name, size, size, NULL);
  62.         } else {
  63.             pixbuf = gtk_icon_theme_load_icon(icon_theme, icon_name, size, 0, NULL);
  64.         }
  65.         g_free(icon_name);
  66.     }
  67.  
  68.     g_key_file_free(key_file);
  69.     return pixbuf;
  70. }
  71.  
  72. static char *get_desktop_file_name(const char *desktop_file_path) {
  73.     GKeyFile *key_file;
  74.     char *name = NULL;
  75.     GError *error = NULL;
  76.  
  77.     key_file = g_key_file_new();
  78.     if (g_key_file_load_from_file(key_file, desktop_file_path, G_KEY_FILE_NONE, &error)) {
  79.         name = g_key_file_get_string(key_file, "Desktop Entry", "Name", NULL);
  80.     }
  81.  
  82.     if (error) {
  83.         g_error_free(error);
  84.     }
  85.  
  86.     g_key_file_free(key_file);
  87.     return name ? name : g_strdup(g_filename_display_basename(desktop_file_path));
  88. }
  89.  
  90. static void create_desktop_icon(DesktopManager *dm, const char *filename) {
  91.     GtkTreeIter iter;
  92.     GFile *file;
  93.     GFileInfo *file_info;
  94.     GIcon *gicon;
  95.     GdkPixbuf *pixbuf = NULL;
  96.     char *file_path;
  97.     char *display_name;
  98.  
  99.     file_path = g_build_filename(DESKTOP_PATH, filename, NULL);
  100.     file = g_file_new_for_path(file_path);
  101.     file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL);
  102.     gicon = g_file_info_get_icon(file_info);
  103.    display_name = g_strdup(g_file_info_get_display_name(file_info));
  104.    
  105.     if (g_str_has_suffix(filename, ".desktop")) {
  106.        pixbuf = load_icon_from_desktop_file(file_path, 48);
  107.         char *desktop_name = get_desktop_file_name(file_path);
  108.        if (desktop_name) {
  109.             g_free(display_name);
  110.             display_name = desktop_name;
  111.         } else {
  112.             display_name = g_strndup(display_name, strlen(display_name) - 8);  // Remove ".desktop"
  113.         }
  114.     }
  115.  
  116.     if (!pixbuf) {
  117.         GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
  118.        pixbuf = gtk_icon_theme_load_icon(icon_theme, "text-x-generic", 48, 0, NULL);
  119.  
  120.         if (G_IS_THEMED_ICON(gicon)) {
  121.             const gchar* const* icon_names = g_themed_icon_get_names(G_THEMED_ICON(gicon));
  122.             if (icon_names) {
  123.                 int i;
  124.                 for (i = 0; icon_names[i] != NULL; i++) {
  125.                     GdkPixbuf *temp_pixbuf = gtk_icon_theme_load_icon(icon_theme, icon_names[i], 48, 0, NULL);
  126.                     if (temp_pixbuf) {
  127.                         if (pixbuf) g_object_unref(pixbuf);
  128.                        pixbuf = temp_pixbuf;
  129.                         break;
  130.                     }
  131.                 }
  132.             }
  133.         }
  134.     }
  135.  
  136.     gtk_list_store_append(dm->store, &iter);
  137.     gtk_list_store_set(dm->store, &iter,
  138.                        COL_DISPLAY_NAME, filename,
  139.                        COL_PIXBUF, pixbuf,
  140.                        COL_FILE_PATH, file_path,
  141.                        -1);
  142.  
  143.     g_object_unref(file);
  144.     g_object_unref(file_info);
  145.     g_object_unref(pixbuf);
  146.     g_free(file_path);
  147. }
  148.  
  149. static void on_item_activated(GtkIconView *icon_view, GtkTreePath *path, gpointer user_data) {
  150.     GtkTreeModel *model;
  151.     GtkTreeIter iter;
  152.     gchar *file_path;
  153.  
  154.     model = gtk_icon_view_get_model(icon_view);
  155.     if (gtk_tree_model_get_iter(model, &iter, path)) {
  156.         gtk_tree_model_get(model, &iter, COL_FILE_PATH, &file_path, -1);
  157.        
  158.         gchar *file_extension = strrchr(file_path, '.');
  159.         if (file_extension) {
  160.             file_extension = g_ascii_strdown(file_extension, -1);
  161.            
  162.             if (g_strcmp0(file_extension, ".desktop") == 0) {
  163.                  gchar *command = g_strdup_printf("gio launch \"%s\"", file_path);
  164.                 system(command);
  165.                 g_free(command);
  166.             } else if (g_strcmp0(file_extension, ".jpg") == 0 || g_strcmp0(file_extension, ".jpeg") == 0) {
  167.                 gchar *command = g_strdup_printf("eom \"%s\"", file_path);
  168.                 system(command);
  169.                 g_free(command);
  170.             } else if (g_strcmp0(file_extension, ".html") == 0 || g_strcmp0(file_extension, ".htm") == 0) {
  171.                 gchar *command = g_strdup_printf("firefox \"%s\"", file_path);
  172.                 system(command);
  173.                 g_free(command);
  174.             } else {
  175.                 gchar *command = g_strdup_printf("xdg-open \"%s\"", file_path);
  176.                 system(command);
  177.                 g_free(command);
  178.             }
  179.            
  180.             g_free(file_extension);
  181.         } else {
  182.             // If no file extension, use xdg-open
  183.             gchar *command = g_strdup_printf("xdg-open \"%s\"", file_path);
  184.             system(command);
  185.             g_free(command);
  186.         }
  187.        
  188.         g_free(file_path);
  189.     }
  190. }
  191.  
  192.  
  193.  
  194. static gint sort_items(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) {
  195.     gchar *name_a, *name_b;
  196.     gint result;
  197.  
  198.     gtk_tree_model_get(model, a, COL_DISPLAY_NAME, &name_a, -1);
  199.     gtk_tree_model_get(model, b, COL_DISPLAY_NAME, &name_b, -1);
  200.  
  201.     result = g_utf8_collate(name_a, name_b);
  202.  
  203.     g_free(name_a);
  204.     g_free(name_b);
  205.  
  206.     return result;
  207. }
  208.  
  209. static void load_desktop_icons(DesktopManager *dm) {
  210.     GDir *dir;
  211.     const gchar *filename;
  212.  
  213.     dir = g_dir_open(DESKTOP_PATH, 0, NULL);
  214.     if (dir == NULL) {
  215.         g_print("Failed to open desktop directory\n");
  216.         return;
  217.     }
  218.  
  219.     while ((filename = g_dir_read_name(dir)) != NULL) {
  220.         char *file_path = g_build_filename(DESKTOP_PATH, filename, NULL);
  221.         if (g_file_test(file_path, G_FILE_TEST_IS_REGULAR)) {
  222.             create_desktop_icon(dm, filename);
  223.         }
  224.         g_free(file_path);
  225.     }
  226.  
  227.     g_dir_close(dir);
  228.  
  229.     // Sort the items
  230.     gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(dm->store), COL_DISPLAY_NAME, sort_items, NULL, NULL);
  231.     gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dm->store), COL_DISPLAY_NAME, GTK_SORT_ASCENDING);
  232. }
  233.  
  234. static void activate(GtkApplication *app, gpointer user_data) {
  235.     DesktopManager *dm = g_new(DesktopManager, 1);
  236.  
  237.     dm->window = gtk_application_window_new(app);
  238.     gtk_window_set_title(GTK_WINDOW(dm->window), "Desktop Manager");
  239.     gtk_window_maximize(GTK_WINDOW(dm->window));
  240.     gtk_window_set_type_hint(GTK_WINDOW(dm->window), GDK_WINDOW_TYPE_HINT_DESKTOP);
  241.    
  242.      dm->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  243.     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dm->scrolled_window),
  244.                                    GTK_POLICY_AUTOMATIC,
  245.                                    GTK_POLICY_ALWAYS);
  246.     gtk_container_add(GTK_CONTAINER(dm->window), dm->scrolled_window);
  247.     gtk_widget_show(dm->scrolled_window);
  248.  
  249.  
  250.     dm->store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING);
  251.     dm->icon_view = gtk_icon_view_new_with_model(GTK_TREE_MODEL(dm->store));
  252.  
  253.     gtk_icon_view_set_text_column(GTK_ICON_VIEW(dm->icon_view), COL_DISPLAY_NAME);
  254.     gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(dm->icon_view), COL_PIXBUF);
  255.     gtk_icon_view_set_item_width(GTK_ICON_VIEW(dm->icon_view), 80);
  256.     gtk_icon_view_set_column_spacing(GTK_ICON_VIEW(dm->icon_view), 20);
  257.     gtk_icon_view_set_row_spacing(GTK_ICON_VIEW(dm->icon_view), 20);
  258.  
  259.     g_signal_connect(dm->icon_view, "item-activated", G_CALLBACK(on_item_activated), NULL);
  260.    
  261.      set_background_color(dm->icon_view);
  262.  
  263.     gtk_container_add(GTK_CONTAINER(dm->scrolled_window), dm->icon_view);
  264.  
  265.     load_desktop_icons(dm);
  266.  
  267.     gtk_widget_show_all(dm->window);
  268. }
  269.  
  270. int main(int argc, char **argv) {
  271.     GtkApplication *app;
  272.     int status;
  273.  
  274.     app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  275.     g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
  276.     status = g_application_run(G_APPLICATION(app), argc, argv);
  277.     g_object_unref(app);
  278.  
  279.     return status;
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement