/** * @file search-progress-dlg.cc * @brief Part of GNOME Commander - A GNOME based file manager * * @copyright (C) 2006 Assaf Gordon\n * @copyright (C) 2007-2012 Piotr Eljasiak\n * @copyright (C) 2013-2023 Uwe Scholz\n * * @copyright This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * @copyright This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * @copyright You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include #include "libgviewer.h" using namespace std; static GtkDialogClass *parent_class = nullptr; static void search_progress_dlg_destroy (GtkObject *object); static void search_progress_dlg_action_response(GtkDialog *dlg, gint arg1, GViewerSearchProgressDlg *sdlg); struct GViewerSearchProgressDlgPrivate { GtkWidget *label, *progressbar; gdouble progress; gint *abort_indicator; gint *progress_value; gint *completed_indicator; }; static void search_progress_dlg_action_response(GtkDialog *dlg, gint arg1, GViewerSearchProgressDlg *sdlg) { g_return_if_fail (sdlg != nullptr); g_return_if_fail (sdlg->priv != nullptr); g_return_if_fail (sdlg->priv->abort_indicator != nullptr); g_atomic_int_add(sdlg->priv->abort_indicator, 1); } static void search_progress_dlg_class_init(GViewerSearchProgressDlgClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; parent_class = (GtkDialogClass *) gtk_type_class (gtk_dialog_get_type ()); object_class->destroy = search_progress_dlg_destroy; } static void search_progress_dlg_init (GViewerSearchProgressDlg *sdlg) { sdlg->priv = g_new0 (GViewerSearchProgressDlgPrivate, 1); GtkDialog *dlg = GTK_DIALOG(sdlg); // sdlg->priv->progress = 0; gtk_window_set_title (GTK_WINDOW (dlg), _("Searching…")); gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); gtk_dialog_add_button (dlg, GTK_STOCK_STOP, 12); g_signal_connect_swapped (GTK_WIDGET (dlg), "response", G_CALLBACK (search_progress_dlg_action_response), sdlg); // Text Label sdlg->priv->label = gtk_label_new(""); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (dlg)), sdlg->priv->label, FALSE, TRUE, 5); // Progress Bar sdlg->priv->progressbar = gtk_progress_bar_new(); #if defined (__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" #endif gtk_progress_bar_set_text(GTK_PROGRESS_BAR (sdlg->priv->progressbar), "0.0"); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (sdlg->priv->progressbar), 0.0); #if defined (__GNUC__) #pragma GCC diagnostic pop #endif gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (dlg)), sdlg->priv->progressbar, TRUE, TRUE, 0); gtk_widget_show_all(gtk_dialog_get_content_area (dlg)); gtk_widget_show (GTK_WIDGET (dlg)); } static void search_progress_dlg_destroy (GtkObject *object) { g_return_if_fail (IS_GVIEWER_SEARCH_PROGRESS_DLG (object)); GViewerSearchProgressDlg *w = GVIEWER_SEARCH_PROGRESS_DLG (object); g_free (w->priv); w->priv = nullptr; if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } GType gviewer_search_progress_dlg_get_type () { static GType ttt_type = 0; if (!ttt_type) { static const GTypeInfo ttt_info = { sizeof (GViewerSearchProgressDlgClass), nullptr, // base_init nullptr, // base_finalize (GClassInitFunc) search_progress_dlg_class_init, nullptr, // class_finalize nullptr, // class_data sizeof (GViewerSearchProgressDlg), 0, // n_preallocs (GInstanceInitFunc) search_progress_dlg_init, }; ttt_type = g_type_register_static (GTK_TYPE_DIALOG, "GViewerSearchProgressDlg", &ttt_info, (GTypeFlags) 0); } return ttt_type; } static GtkWidget *gviewer_search_progress_dlg_new (GtkWindow *parent) { auto dlg = static_cast (g_object_new (gviewer_search_progress_dlg_get_type(), NULL)); return GTK_WIDGET (dlg); } static gboolean search_progress_dlg_timeout(gpointer data) { g_return_val_if_fail (IS_GVIEWER_SEARCH_PROGRESS_DLG (data), FALSE); gdouble progress; gchar text[20]; GViewerSearchProgressDlg *w = GVIEWER_SEARCH_PROGRESS_DLG (data); progress = g_atomic_int_get (w->priv->progress_value); g_snprintf(text, sizeof(text), "%3.1f%%", progress/10.0); #if defined (__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" #endif gtk_progress_bar_set_text(GTK_PROGRESS_BAR (w->priv->progressbar), text); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (w->priv->progressbar), progress/1000.0); #if defined (__GNUC__) #pragma GCC diagnostic pop #endif if (g_atomic_int_get (w->priv->completed_indicator)!=0) { gtk_dialog_response(GTK_DIALOG(w), GTK_RESPONSE_CANCEL); return FALSE; } return TRUE; } void gviewer_show_search_progress_dlg(GtkWindow *parent, const gchar *searching_text, gint *abort, gint *complete, gint *progress) { g_return_if_fail (abort != nullptr); g_return_if_fail (complete != nullptr); g_return_if_fail (progress != nullptr); g_return_if_fail (searching_text != nullptr); gdouble dprogress; gchar text[20]; GtkWidget *w = gviewer_search_progress_dlg_new(parent); GViewerSearchProgressDlg *dlg = GVIEWER_SEARCH_PROGRESS_DLG (w); gchar *str = g_strdup_printf (_("Searching for “%s”"), searching_text); gtk_label_set_text (GTK_LABEL (dlg->priv->label), str); dlg->priv->abort_indicator = abort; dlg->priv->progress_value = progress; dlg->priv->completed_indicator = complete; gint timeout_source_id = g_timeout_add (300, search_progress_dlg_timeout, (gpointer) dlg); dprogress = g_atomic_int_get (dlg->priv->progress_value); g_snprintf(text, sizeof(text), "%3.1f%%", dprogress/10.0); #if defined (__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" #endif gtk_progress_bar_set_text(GTK_PROGRESS_BAR (dlg->priv->progressbar), text); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (dlg->priv->progressbar), dprogress/1000.0); #if defined (__GNUC__) #pragma GCC diagnostic pop #endif gtk_dialog_run(GTK_DIALOG(dlg)); GSource *src = g_main_context_find_source_by_id(nullptr, timeout_source_id); if (src) g_source_destroy(src); g_free (str); gtk_widget_destroy (GTK_WIDGET (dlg)); }