00001
00002
00003 #ifdef HAVE_CONFIG_H
00004 # include <config.h>
00005 #endif
00006
00007 #include "cprogress_p.h"
00008 #include "cgui_l.h"
00009
00010 #include <gwenhywfar/inherit.h>
00011 #include <gwenhywfar/debug.h>
00012 #include <gwenhywfar/misc.h>
00013
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <unistd.h>
00017 #include <fcntl.h>
00018 #include <errno.h>
00019 #include <string.h>
00020
00021
00022
00023 GWEN_LIST_FUNCTIONS(GWEN_GUI_CPROGRESS, GWEN_Gui_CProgress)
00024
00025
00026
00027 GWEN_GUI_CPROGRESS *GWEN_Gui_CProgress_new(GWEN_GUI *gui,
00028 uint32_t id,
00029 uint32_t progressFlags,
00030 const char *title,
00031 const char *text,
00032 uint64_t total) {
00033 GWEN_GUI_CPROGRESS *cp;
00034
00035 GWEN_NEW_OBJECT(GWEN_GUI_CPROGRESS, cp);
00036 GWEN_LIST_INIT(GWEN_GUI_CPROGRESS, cp);
00037 cp->gui=gui;
00038 cp->id=id;
00039 cp->startTime=time(0);
00040 cp->flags=progressFlags;
00041 if (title)
00042 cp->title=strdup(title);
00043 if (text)
00044 cp->text=strdup(text);
00045 cp->total=total;
00046 cp->logBuf=GWEN_Buffer_new(0, 256, 0, 1);
00047
00048 if (!(cp->flags & GWEN_GUI_PROGRESS_DELAY)) {
00049 fprintf(stderr, "%s: Started.\n", cp->title);
00050 cp->shown=1;
00051 }
00052
00053 return cp;
00054 }
00055
00056
00057
00058 void GWEN_Gui_CProgress_free(GWEN_GUI_CPROGRESS *cp) {
00059 if (cp) {
00060 GWEN_LIST_FINI(GWEN_GUI_CPROGRESS, cp);
00061 GWEN_Buffer_free(cp->logBuf);
00062 free(cp->text);
00063 free(cp->title);
00064 GWEN_FREE_OBJECT(cp);
00065 }
00066 }
00067
00068
00069
00070 GWEN_GUI *GWEN_Gui_CProgress_GetGui(const GWEN_GUI_CPROGRESS *cp) {
00071 assert(cp);
00072 return cp->gui;
00073 }
00074
00075
00076
00077 uint32_t GWEN_Gui_CProgress_GetId(const GWEN_GUI_CPROGRESS *cp) {
00078 assert(cp);
00079 return cp->id;
00080 }
00081
00082
00083
00084 const char *GWEN_Gui_CProgress_GetTitle(const GWEN_GUI_CPROGRESS *cp) {
00085 assert(cp);
00086 return cp->title;
00087 }
00088
00089
00090
00091 const char *GWEN_Gui_CProgress_GetText(const GWEN_GUI_CPROGRESS *cp) {
00092 assert(cp);
00093 return cp->text;
00094 }
00095
00096
00097
00098 uint64_t GWEN_Gui_CProgress_GetTotal(const GWEN_GUI_CPROGRESS *cp) {
00099 assert(cp);
00100 return cp->total;
00101 }
00102
00103
00104
00105 uint64_t GWEN_Gui_CProgress_GetCurrent(const GWEN_GUI_CPROGRESS *cp) {
00106 assert(cp);
00107 return cp->current;
00108 }
00109
00110
00111
00112 const char *GWEN_Gui_CProgress_GetLogBuf(const GWEN_GUI_CPROGRESS *cp) {
00113 assert(cp);
00114 assert(cp->logBuf);
00115 return GWEN_Buffer_GetStart(cp->logBuf);
00116 }
00117
00118
00119
00120 int GWEN_Gui_CProgress_GetAborted(const GWEN_GUI_CPROGRESS *cp) {
00121 assert(cp);
00122 return cp->aborted;
00123 }
00124
00125
00126
00127
00128
00129
00130 int GWEN_Gui_CProgress_Advance(GWEN_GUI_CPROGRESS *cp, uint64_t progress) {
00131 #ifndef OS_WIN32
00132 int fl;
00133 #endif
00134
00135 assert(cp);
00136 if (!cp->shown) {
00137 time_t t1;
00138
00139 t1=time(0);
00140 if (difftime(t1, cp->startTime)>GWEN_GUI_DELAY_SECS) {
00141 if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE))
00142 fprintf(stderr, "%s: Started.\n", cp->title);
00143 cp->shown=1;
00144 }
00145 }
00146
00147 if (progress==GWEN_GUI_PROGRESS_ONE)
00148 progress=cp->current+1;
00149 if (progress!=GWEN_GUI_PROGRESS_NONE) {
00150 if (progress!=cp->current) {
00151 if (cp->shown) {
00152 if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE)) {
00153 if (cp->total==GWEN_GUI_PROGRESS_NONE)
00154 fprintf(stderr, "%s: %llu\n", cp->title,
00155 (long long unsigned)progress);
00156 else
00157 fprintf(stderr, "%s: %llu of %llu\n",
00158 cp->title,
00159 (long long unsigned)progress,
00160 (long long unsigned)cp->total);
00161 }
00162 }
00163 cp->current=progress;
00164 }
00165 }
00166 if (cp->aborted)
00167 return GWEN_ERROR_USER_ABORTED;
00168
00169 #ifndef OS_WIN32
00170 if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE)) {
00171
00172 fl=fcntl(fileno(stdin), F_GETFL);
00173 if (fl!=-1) {
00174 int chr;
00175
00176
00177 if (fcntl(fileno(stdin), F_SETFL, fl | O_NONBLOCK)) {
00178 DBG_INFO(GWEN_LOGDOMAIN, "fcntl(stdin): %s", strerror(errno));
00179 return 0;
00180 }
00181
00182 chr=getchar();
00183
00184 fcntl(fileno(stdin), F_SETFL, fl);
00185 if (chr==GWEN_GUI_CPROGRESS_CHAR_ABORT) {
00186 fprintf(stderr, "------> ABORTED BY USER\n");
00187 cp->aborted=1;
00188 return GWEN_ERROR_USER_ABORTED;
00189 }
00190 }
00191 }
00192 #endif
00193
00194 return 0;
00195 }
00196
00197
00198
00199 int GWEN_Gui_CProgress_Log(GWEN_GUI_CPROGRESS *cp,
00200 GWEN_UNUSED GWEN_LOGGER_LEVEL level,
00201 const char *text) {
00202 assert(cp);
00203 assert(text);
00204
00205 if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE)) {
00206 GWEN_BUFFER *tbuf;
00207 const char *t;
00208
00209 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
00210 GWEN_Gui_GetRawText(cp->gui, text, tbuf);
00211 t=GWEN_Buffer_GetStart(tbuf);
00212 if (t[strlen(t)-1]!='\n')
00213 GWEN_Buffer_AppendByte(tbuf, '\n');
00214 fprintf(stderr, "%s", t);
00215
00216 GWEN_Buffer_AppendString(cp->logBuf, GWEN_Buffer_GetStart(tbuf));
00217 GWEN_Buffer_free(tbuf);
00218 tbuf=0;
00219 if (cp->aborted)
00220 return GWEN_ERROR_USER_ABORTED;
00221 }
00222 return 0;
00223 }
00224
00225
00226
00227 int GWEN_Gui_CProgress_End(GWEN_GUI_CPROGRESS *cp) {
00228 assert(cp);
00229
00230 if (cp->shown) {
00231 if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE))
00232 fprintf(stderr, "%s: Finished.\n", cp->title);
00233 }
00234 if (cp->aborted)
00235 return GWEN_ERROR_USER_ABORTED;
00236
00237 return 0;
00238 }
00239
00240
00241
00242