statusbar.c (4816B)
1 /* 2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client 3 * Copyright (C) 1999-2022 the Claws Mail team and Hiroyuki Yamamoto 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <glib.h> 20 #include <glib/gi18n.h> 21 #include <gtk/gtk.h> 22 #include <stdarg.h> 23 24 #include "mainwindow.h" 25 #include "statusbar.h" 26 #include "gtkutils.h" 27 #include "utils.h" 28 #include "log.h" 29 #include "hooks.h" 30 31 #define BUFFSIZE 1024 32 33 static GList *statusbar_list = NULL; 34 static gulong statusbar_puts_all_hook_id = HOOK_NONE; 35 36 GtkWidget *statusbar_create(void) 37 { 38 GtkWidget *statusbar; 39 GtkWidget *child; 40 GtkWidget *parent; 41 GtkWidget *hbox; 42 43 statusbar = gtk_statusbar_new(); 44 45 gtk_widget_set_margin_top(GTK_WIDGET(statusbar), 0); 46 gtk_widget_set_margin_bottom(GTK_WIDGET(statusbar), 0); 47 statusbar_list = g_list_append(statusbar_list, statusbar); 48 gtk_container_set_border_width(GTK_CONTAINER(statusbar), 1); 49 child = gtk_statusbar_get_message_area(GTK_STATUSBAR(statusbar)); 50 gtk_widget_set_margin_top(GTK_WIDGET(child), 0); 51 gtk_widget_set_margin_bottom(GTK_WIDGET(child), 0); 52 gtk_widget_set_margin_start(GTK_WIDGET(child), 0); 53 gtk_widget_set_margin_end(GTK_WIDGET(child), 0); 54 parent = gtk_widget_get_parent(child); 55 gtk_container_remove(GTK_CONTAINER(parent), g_object_ref(child)); 56 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 57 gtk_container_add(GTK_CONTAINER(parent), hbox); 58 gtk_widget_show(hbox); 59 gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 0); 60 g_object_unref(child); 61 62 return statusbar; 63 } 64 65 void statusbar_puts(GtkStatusbar *statusbar, const gchar *str) 66 { 67 gint cid; 68 gchar *buf; 69 gchar *tmp; 70 71 tmp = g_strdup(str); 72 strretchomp(tmp); 73 buf = trim_string(tmp, 76); 74 g_free(tmp); 75 76 cid = gtk_statusbar_get_context_id(statusbar, "Standard Output"); 77 gtk_statusbar_pop(statusbar, cid); 78 gtk_statusbar_push(statusbar, cid, buf); 79 80 g_free(buf); 81 } 82 83 void statusbar_puts_all(const gchar *str) 84 { 85 GList *cur; 86 87 for (cur = statusbar_list; cur != NULL; cur = cur->next) 88 statusbar_puts(GTK_STATUSBAR(cur->data), str); 89 } 90 91 void statusbar_print_all(const gchar *format, ...) 92 { 93 va_list args; 94 gchar buf[BUFFSIZE]; 95 GList *cur; 96 97 va_start(args, format); 98 g_vsnprintf(buf, sizeof(buf), format, args); 99 va_end(args); 100 101 for (cur = statusbar_list; cur != NULL; cur = cur->next) 102 statusbar_puts(GTK_STATUSBAR(cur->data), buf); 103 } 104 105 void statusbar_pop_all(void) 106 { 107 GList *cur; 108 gint cid; 109 110 for (cur = statusbar_list; cur != NULL; cur = cur->next) { 111 cid = gtk_statusbar_get_context_id(GTK_STATUSBAR(cur->data), 112 "Standard Output"); 113 gtk_statusbar_pop(GTK_STATUSBAR(cur->data), cid); 114 } 115 } 116 117 static gboolean statusbar_puts_all_hook (gpointer source, gpointer data) 118 { 119 LogText *logtext = (LogText *) source; 120 121 cm_return_val_if_fail(logtext != NULL, TRUE); 122 cm_return_val_if_fail(logtext->text != NULL, TRUE); 123 124 statusbar_pop_all(); 125 if (logtext->type == LOG_NORMAL) { 126 statusbar_puts_all(logtext->text + LOG_TIME_LEN); 127 } else if (logtext->type == LOG_MSG) { 128 statusbar_puts_all(logtext->text); 129 } 130 131 return FALSE; 132 } 133 134 void statusbar_verbosity_set(gboolean verbose) 135 { 136 if (verbose && (statusbar_puts_all_hook_id == HOOK_NONE)) { 137 statusbar_puts_all_hook_id = 138 hooks_register_hook(LOG_APPEND_TEXT_HOOKLIST, statusbar_puts_all_hook, NULL); 139 } else if (!verbose && (statusbar_puts_all_hook_id != HOOK_NONE)) { 140 hooks_unregister_hook(LOG_APPEND_TEXT_HOOKLIST, statusbar_puts_all_hook_id); 141 statusbar_puts_all_hook_id = HOOK_NONE; 142 statusbar_pop_all(); 143 } 144 } 145 146 void statusbar_progress_all (gint done, gint total, gint step) 147 { 148 GtkProgressBar *progressbar = GTK_PROGRESS_BAR( 149 mainwindow_get_mainwindow()->progressbar); 150 gchar buf[32]; 151 152 if (total && done % step == 0) { 153 const gchar *format = "%d / %d"; 154 g_snprintf(buf, sizeof(buf), format, done, total); 155 gtk_progress_bar_set_show_text(progressbar, TRUE); 156 gtk_progress_bar_set_text(progressbar, buf); 157 gtk_progress_bar_set_fraction(progressbar, 158 (gfloat)done / (gfloat)total); 159 if (!gtk_widget_get_visible(GTK_WIDGET(progressbar))) 160 gtk_widget_show(GTK_WIDGET(progressbar)); 161 } else if (total == 0) { 162 gtk_progress_bar_set_text(progressbar, ""); 163 gtk_progress_bar_set_fraction(progressbar, 0.0); 164 gtk_widget_hide(GTK_WIDGET(progressbar)); 165 } 166 }