summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2009-08-16 19:54:43 +0200
committerGravatar waker <wakeroid@gmail.com>2009-08-16 19:54:43 +0200
commit41e7d953fc641c3285f09b07f2210c2895003040 (patch)
treeb8424fc1e6878434f8e9a20dcfd219144491af1b
parent97da31bb0e0b426f06eb8ba4c35d60b11ceca24a (diff)
added playlist_add abortion and progress window wrapper
-rw-r--r--Jamfile2
-rw-r--r--callbacks.c1
-rw-r--r--callbacks.h9
-rw-r--r--deadbeef.glade80
-rw-r--r--gtkplaylist.c92
-rw-r--r--interface.c55
-rw-r--r--interface.h1
-rw-r--r--main.c3
-rw-r--r--playlist.c21
-rw-r--r--playlist.h4
-rw-r--r--progress.c79
-rw-r--r--progress.h37
12 files changed, 307 insertions, 77 deletions
diff --git a/Jamfile b/Jamfile
index 7ae5203d..c0a7e3a0 100644
--- a/Jamfile
+++ b/Jamfile
@@ -22,7 +22,7 @@ HDRS += $(ROOT)/sidplay-libs-2.1.0/libsidplay/include ;
HDRS += $(ROOT)/sidplay-libs-2.1.0/builders/resid-builder/include ;
Main deadbeef :
- codec.c cvorbis.c cmp3.c cgme.c cdumb.c cwav.c cflac.c csid.cpp playlist.c palsa.c streamer.c md5/md5.c main.c support.c interface.c callbacks.c threading_pthread.c messagepump.c gtkplaylist.c search.c ;
+ codec.c cvorbis.c cmp3.c cgme.c cdumb.c cwav.c cflac.c csid.cpp playlist.c palsa.c streamer.c md5/md5.c main.c support.c interface.c callbacks.c threading_pthread.c messagepump.c gtkplaylist.c search.c progress.c ;
LINKLIBS on deadbeef = -lm -lvorbis -logg -lvorbisfile -lmad -lFLAC -lsamplerate -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lgthread-2.0 -lstdc++ -lasound ;
diff --git a/callbacks.c b/callbacks.c
index 44c428ca..65a62eb7 100644
--- a/callbacks.c
+++ b/callbacks.c
@@ -1098,3 +1098,4 @@ on_mainwin_delete_event (GtkWidget *widget,
}
+
diff --git a/callbacks.h b/callbacks.h
index 4694af5f..ccf0e0d2 100644
--- a/callbacks.h
+++ b/callbacks.h
@@ -468,3 +468,12 @@ void
volumebar_expose (GtkWidget *widget, int x, int y, int w, int h);
+
+void
+on_progress_abort (GtkButton *button,
+ gpointer user_data);
+
+gboolean
+on_addprogress_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
diff --git a/deadbeef.glade b/deadbeef.glade
index 18aea2da..9c98a6de 100644
--- a/deadbeef.glade
+++ b/deadbeef.glade
@@ -1543,4 +1543,84 @@ Public License instead of this License. But first, please read
</child>
</widget>
+<widget class="GtkWindow" id="addprogress">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Adding files...</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <signal name="delete_event" handler="on_addprogress_delete_event" last_modification_time="Sun, 16 Aug 2009 17:20:03 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="vbox6">
+ <property name="border_width">4</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkEntry" id="progresstitle">
+ <property name="width_request">500</property>
+ <property name="visible">True</property>
+ <property name="editable">False</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox7">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <placeholder/>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="width_request">83</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Abort</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <signal name="clicked" handler="on_progress_abort" last_modification_time="Sun, 16 Aug 2009 17:17:12 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">2</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
</glade-interface>
diff --git a/gtkplaylist.c b/gtkplaylist.c
index 2cecbbeb..f9f947c9 100644
--- a/gtkplaylist.c
+++ b/gtkplaylist.c
@@ -40,6 +40,7 @@
#include "messages.h"
#include "streamer.h"
#include "search.h"
+#include "progress.h"
// orange on dark color scheme
float colo_dark_orange[COLO_COUNT][3] = {
@@ -1109,32 +1110,27 @@ strcopy_special (char *dest, const char *src, int len) {
int
gtkpl_add_file_info_cb (playItem_t *it, void *data) {
- static int countdown = 0;
- //if (countdown == 0)
- {
+ if (progress_is_aborted ()) {
+ return -1;
+ }
+ GDK_THREADS_ENTER();
+ progress_settext (it->fname);
+ GDK_THREADS_LEAVE();
+#if 0
GtkEntry *e = (GtkEntry *)data;
GDK_THREADS_ENTER();
gtk_entry_set_text (GTK_ENTRY (e), it->fname);
GDK_THREADS_LEAVE();
usleep (100);
countdown = 10;
- }
- countdown--;
+#endif
return 0;
}
void
gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y) {
GDK_THREADS_ENTER();
- extern GtkWidget *mainwin;
- gtk_widget_set_sensitive (mainwin, FALSE);
- GtkWidget *d = gtk_dialog_new ();
- GtkWidget *e = gtk_entry_new ();
- gtk_widget_set_size_request (e, 500, -1);
- gtk_widget_set_sensitive (GTK_WIDGET (e), FALSE);
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), e);
- gtk_widget_show_all (d);
- gtk_window_present (GTK_WINDOW (d));
+ progress_show ();
GDK_THREADS_LEAVE();
int drop_row = drop_y / rowheight + ps->scrollpos;
@@ -1157,9 +1153,10 @@ gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y
strcopy_special (fname, p, pe-p);
//strncpy (fname, p, pe - p);
//fname[pe - p] = 0;
- playItem_t *inserted = pl_insert_dir (after, fname + 7, gtkpl_add_file_info_cb, e);
- if (!inserted) {
- inserted = pl_insert_file (after, fname + 7, gtkpl_add_file_info_cb, e);
+ int abort = 0;
+ playItem_t *inserted = pl_insert_dir (after, fname + 7, &abort, gtkpl_add_file_info_cb, NULL);
+ if (!inserted && !abort) {
+ inserted = pl_insert_file (after, fname + 7, &abort, gtkpl_add_file_info_cb, NULL);
}
if (inserted) {
after = inserted;
@@ -1172,18 +1169,11 @@ gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y
}
}
free (ptr);
- // invalidate entire cache - slow, but rare
- memset (ps->fmtcache, 0, sizeof (int16_t) * 3 * pl_ncolumns * ps->nvisiblerows);
+
GDK_THREADS_ENTER();
- gtk_widget_destroy (d);
- gtk_widget_set_sensitive (mainwin, TRUE);
- gtkpl_setup_scrollbar (ps);
- GtkWidget *widget = ps->playlist;
- gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- search_refresh ();
+ progress_hide ();
+ playlist_refresh ();
GDK_THREADS_LEAVE();
-
}
void
@@ -1405,30 +1395,14 @@ on_header_button_release_event (GtkWidget *widget,
void
gtkpl_add_dir (gtkplaylist_t *ps, char *folder) {
- // create window
GDK_THREADS_ENTER();
- extern GtkWidget *mainwin;
- gtk_widget_set_sensitive (mainwin, FALSE);
- GtkWidget *d = gtk_dialog_new ();
- GtkWidget *e = gtk_entry_new ();
- gtk_widget_set_size_request (e, 500, -1);
- gtk_widget_set_sensitive (GTK_WIDGET (e), FALSE);
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), e);
- gtk_widget_show_all (d);
- gtk_window_present (GTK_WINDOW (d));
+ progress_show ();
GDK_THREADS_LEAVE();
- pl_add_dir (folder, gtkpl_add_file_info_cb, e);
+ pl_add_dir (folder, gtkpl_add_file_info_cb, NULL);
g_free (folder);
GDK_THREADS_ENTER();
- gtk_widget_destroy (d);
- gtk_widget_set_sensitive (mainwin, TRUE);
- // invalidate entire cache - slow, but rare
- memset (ps->fmtcache, 0, sizeof (int16_t) * 3 * pl_ncolumns * ps->nvisiblerows);
- gtkpl_setup_scrollbar (ps);
- GtkWidget *widget = ps->playlist;
- gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- search_refresh ();
+ progress_hide ();
+ playlist_refresh ();
GDK_THREADS_LEAVE();
}
@@ -1440,30 +1414,14 @@ gtkpl_addfile_cb (gpointer data, gpointer userdata) {
void
gtkpl_add_files (gtkplaylist_t *ps, GSList *lst) {
- // create window
GDK_THREADS_ENTER();
- extern GtkWidget *mainwin;
- gtk_widget_set_sensitive (mainwin, FALSE);
- GtkWidget *d = gtk_dialog_new ();
- GtkWidget *e = gtk_entry_new ();
- gtk_widget_set_size_request (e, 500, -1);
- gtk_widget_set_sensitive (GTK_WIDGET (e), FALSE);
- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), e);
- gtk_widget_show_all (d);
- gtk_window_present (GTK_WINDOW (d));
+ progress_show ();
GDK_THREADS_LEAVE();
- g_slist_foreach(lst, gtkpl_addfile_cb, e);
+ g_slist_foreach(lst, gtkpl_addfile_cb, NULL);
g_slist_free (lst);
GDK_THREADS_ENTER();
- gtk_widget_destroy (d);
- gtk_widget_set_sensitive (mainwin, TRUE);
- // invalidate entire cache - slow, but rare
- memset (ps->fmtcache, 0, sizeof (int16_t) * 3 * pl_ncolumns * ps->nvisiblerows);
- gtkpl_setup_scrollbar (ps);
- GtkWidget *widget = ps->playlist;
- gtkpl_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- gtkpl_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height);
- search_refresh ();
+ progress_hide ();
+ playlist_refresh ();
GDK_THREADS_LEAVE();
}
diff --git a/interface.c b/interface.c
index ebc16526..93a92da0 100644
--- a/interface.c
+++ b/interface.c
@@ -842,3 +842,58 @@ create_traymenu (void)
return traymenu;
}
+GtkWidget*
+create_addprogress (void)
+{
+ GtkWidget *addprogress;
+ GtkWidget *vbox6;
+ GtkWidget *progresstitle;
+ GtkWidget *hbox7;
+ GtkWidget *button1;
+
+ addprogress = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (addprogress), "Adding files...");
+ gtk_window_set_position (GTK_WINDOW (addprogress), GTK_WIN_POS_CENTER_ON_PARENT);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (addprogress), TRUE);
+ gtk_window_set_skip_pager_hint (GTK_WINDOW (addprogress), TRUE);
+
+ vbox6 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox6);
+ gtk_container_add (GTK_CONTAINER (addprogress), vbox6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox6), 4);
+
+ progresstitle = gtk_entry_new ();
+ gtk_widget_show (progresstitle);
+ gtk_box_pack_start (GTK_BOX (vbox6), progresstitle, TRUE, FALSE, 0);
+ gtk_widget_set_size_request (progresstitle, 500, -1);
+ GTK_WIDGET_UNSET_FLAGS (progresstitle, GTK_CAN_FOCUS);
+ gtk_editable_set_editable (GTK_EDITABLE (progresstitle), FALSE);
+ gtk_entry_set_invisible_char (GTK_ENTRY (progresstitle), 8226);
+
+ hbox7 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox7);
+ gtk_box_pack_start (GTK_BOX (vbox6), hbox7, FALSE, TRUE, 2);
+
+ button1 = gtk_button_new_with_mnemonic ("Abort");
+ gtk_widget_show (button1);
+ gtk_box_pack_start (GTK_BOX (hbox7), button1, FALSE, FALSE, 0);
+ gtk_widget_set_size_request (button1, 83, -1);
+ GTK_WIDGET_UNSET_FLAGS (button1, GTK_CAN_FOCUS);
+
+ g_signal_connect ((gpointer) addprogress, "delete_event",
+ G_CALLBACK (on_addprogress_delete_event),
+ NULL);
+ g_signal_connect ((gpointer) button1, "clicked",
+ G_CALLBACK (on_progress_abort),
+ NULL);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT_NO_REF (addprogress, addprogress, "addprogress");
+ GLADE_HOOKUP_OBJECT (addprogress, vbox6, "vbox6");
+ GLADE_HOOKUP_OBJECT (addprogress, progresstitle, "progresstitle");
+ GLADE_HOOKUP_OBJECT (addprogress, hbox7, "hbox7");
+ GLADE_HOOKUP_OBJECT (addprogress, button1, "button1");
+
+ return addprogress;
+}
+
diff --git a/interface.h b/interface.h
index 1b3c93c5..943cf0fc 100644
--- a/interface.h
+++ b/interface.h
@@ -6,3 +6,4 @@ GtkWidget* create_mainwin (void);
GtkWidget* create_aboutdialog (void);
GtkWidget* create_searchwin (void);
GtkWidget* create_traymenu (void);
+GtkWidget* create_addprogress (void);
diff --git a/main.c b/main.c
index 9c9d930c..9f094b91 100644
--- a/main.c
+++ b/main.c
@@ -40,6 +40,7 @@
#include "codec.h"
#include "streamer.h"
#include "search.h"
+#include "progress.h"
GtkWidget *mainwin;
GtkWidget *searchwin;
@@ -526,6 +527,8 @@ main (int argc, char *argv[]) {
extern void search_playlist_init (GtkWidget *widget);
search_playlist_init (lookup_widget (searchwin, "searchlist"));
+ progress_init ();
+
if (argc > 1) {
int res = exec_command_line (cmdline, size, 0);
if (res == -1) {
diff --git a/playlist.c b/playlist.c
index 4b1e3860..fb318824 100644
--- a/playlist.c
+++ b/playlist.c
@@ -256,7 +256,7 @@ pl_insert_cue (playItem_t *after, const char *cuename, const char *ftype) {
}
playItem_t *
-pl_insert_file (playItem_t *after, const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
+pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
if (!fname) {
return NULL;
}
@@ -278,7 +278,9 @@ pl_insert_file (playItem_t *after, const char *fname, int (*cb)(playItem_t *it,
playItem_t *inserted = NULL;
if ((inserted = codecs[i]->insert (after, fname)) != NULL) {
if (cb) {
- cb (inserted, user_data);
+ if (cb (inserted, user_data) < 0) {
+ *pabort = 1;
+ }
}
return inserted;
}
@@ -291,7 +293,7 @@ pl_insert_file (playItem_t *after, const char *fname, int (*cb)(playItem_t *it,
}
playItem_t *
-pl_insert_dir (playItem_t *after, const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data) {
+pl_insert_dir (playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
struct stat buf;
lstat (dirname, &buf);
if (S_ISLNK(buf.st_mode)) {
@@ -319,13 +321,16 @@ pl_insert_dir (playItem_t *after, const char *dirname, int (*cb)(playItem_t *it,
strcpy (fullname, dirname);
strncat (fullname, "/", 1024);
strncat (fullname, namelist[i]->d_name, 1024);
- playItem_t *inserted = pl_insert_dir (after, fullname, cb, user_data);
+ playItem_t *inserted = pl_insert_dir (after, fullname, pabort, cb, user_data);
if (!inserted) {
- inserted = pl_insert_file (after, fullname, cb, user_data);
+ inserted = pl_insert_file (after, fullname, pabort, cb, user_data);
}
if (inserted) {
after = inserted;
}
+ if (*pabort) {
+ break;
+ }
}
free (namelist[i]);
}
@@ -336,7 +341,8 @@ pl_insert_dir (playItem_t *after, const char *dirname, int (*cb)(playItem_t *it,
int
pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data) {
- if (pl_insert_file (playlist_tail[PL_MAIN], fname, cb, user_data)) {
+ int abort = 0;
+ if (pl_insert_file (playlist_tail[PL_MAIN], fname, &abort, cb, user_data)) {
return 0;
}
return -1;
@@ -344,7 +350,8 @@ pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *use
int
pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data) {
- if (pl_insert_dir (playlist_tail[PL_MAIN], dirname, cb, user_data)) {
+ int abort = 0;
+ if (pl_insert_dir (playlist_tail[PL_MAIN], dirname, &abort, cb, user_data)) {
return 0;
}
return -1;
diff --git a/playlist.h b/playlist.h
index 5c315c2d..f3de1022 100644
--- a/playlist.h
+++ b/playlist.h
@@ -58,10 +58,10 @@ int
pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data);
playItem_t *
-pl_insert_dir (playItem_t *after, const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data);
+pl_insert_dir (playItem_t *after, const char *dirname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
playItem_t *
-pl_insert_file (playItem_t *after, const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data);
+pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data);
playItem_t *
pl_insert_item (playItem_t *after, playItem_t *it);
diff --git a/progress.c b/progress.c
new file mode 100644
index 00000000..4eed4f06
--- /dev/null
+++ b/progress.c
@@ -0,0 +1,79 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include "interface.h"
+#include "callbacks.h"
+#include "support.h"
+#include "progress.h"
+
+static GtkWidget *progressdlg;
+static GtkWidget *progressitem;
+static int progress_aborted;
+
+void
+progress_init (void) {
+ extern GtkWidget *mainwin;
+ progressdlg = create_addprogress ();
+ gtk_window_set_transient_for (GTK_WINDOW (progressdlg), GTK_WINDOW (mainwin));
+ progressitem = lookup_widget (progressdlg, "progresstitle");
+}
+
+void
+progress_show (void) {
+ progress_aborted = 0;
+ progress_settext ("");
+ gtk_widget_show_all (progressdlg);
+ gtk_window_present (GTK_WINDOW (progressdlg));
+}
+
+void
+progress_hide (void) {
+ printf ("progress_hide\n");
+ gtk_widget_hide (progressdlg);
+}
+
+void
+progress_settext (const char *text) {
+ gtk_entry_set_text (GTK_ENTRY (progressitem), text);
+}
+
+void
+on_progress_abort (GtkButton *button,
+ gpointer user_data)
+{
+ progress_aborted = 1;
+}
+
+int
+progress_is_aborted (void) {
+ return progress_aborted;
+}
+
+
+gboolean
+on_addprogress_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ progress_aborted = 1;
+ return gtk_widget_hide_on_delete (widget);
+}
diff --git a/progress.h b/progress.h
new file mode 100644
index 00000000..cacd21aa
--- /dev/null
+++ b/progress.h
@@ -0,0 +1,37 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009 Alexey Yakovenko
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __PROGRESS_H
+#define __PROGRESS_H
+
+void
+progress_init (void);
+
+void
+progress_show (void);
+
+void
+progress_hide (void);
+
+void
+progress_settext (const char *text);
+
+int
+progress_is_aborted (void);
+
+#endif // __PROGRESS_H