%% options copyright owner = Dirk Krause copyright year = 2018-xxxx SPDX-License-Identifier: BSD-3-Clause %% wx-gui type = dialog contents = sDialog [wxBoxSizer sDialog] direction = horizontal contents = $space(10) contents = verticalSizer contents = $space(10) [wxBoxSizer verticalSizer] direction = vertical grow = yes contents = $space(10) contents = lFilename left contents = $space(10) contents = lProcessingStep left contents = $space(10) contents = gProgress centered-x contents = $space(10) contents = bCancel centered-x contents = $space(10) [wxStaticText lFilename] text = sTexts[56] [wxStaticText lProcessingStep] text = sTexts[93] [wxGauge gProgress] range = 1000 value = 0 grow = yes [wxButton bCancel] id = wxID_CANCEL text = sTexts[96] tip = sTexts[97] %% header start /** @file Bmpp4Progress.h Progress dialog shown while processing. */ #ifndef DK4GRCO_H_INCLUDED #include #endif #ifndef DK4STO_H_INCLUDED #include #endif /** One input file to process. */ typedef struct { wxChar *infilename; /**< Input file name, allocated. */ wxChar *shortifn; /**< Short file name, in filename. */ dkChar *dkifn; /**< Input file name allocated. */ dkChar *dkofn; /**< Output file name, allocated. */ unsigned char mcheck; /**< Flag: Do make-operation check. */ } one_file_t; %% class start class Bmpp4Progress : public wxDialog { private: #if wxCHECK_VERSION(3,0,0) wxDECLARE_EVENT_TABLE(); #else DECLARE_EVENT_TABLE() #endif protected: /** Decision for next step to execute. */ enum { STEP_REPORT_ERROR = -1 , /**< Error occured initialization. */ STEP_START_NEW_FILE = 0 , /**< Retrieve next file name. */ STEP_GENERATE_OUTPUT , /**< Generate output for one frame. */ STEP_WRITE_FILE , /**< Write output to file. */ }; /** Protect variables against concurrent access. */ wxCriticalSection csProtect; /** Graphics output configuration. */ dk4_gra_conf_t graconf; /** Coordinates transformation. */ double cotra[8]; /** Directory name to process. */ wxString sDirname; /** Current file processed. */ one_file_t *curof; /** Bitmap image to read from. */ dk4_bif_t *pBif; /** Graphics object to create. */ dk4_gra_t *pGra; /** Application helper for encoding changes. */ Dk4WxApplicationHelper *pAppHelp; /** Localized texts for wxbmpp application. */ wxChar const * const *sTexts; /** String containing all the error messages. */ wxString *pErrors; /** Collection of file names to process. */ dk4_sto_t *sFiles; /** Iterator through file name collection. */ dk4_sto_it_t *iFiles; /** Current file to process. */ one_file_t *currentFile; /** Number of files in sFiles. */ size_t szFiles; /** Number of files already processed from sFiles. */ size_t usedFiles; /** Current frame number to process next. */ size_t currentFrame; /** Image width. */ size_t w; /** Image height. */ size_t h; /** Flags to use for document when opening graphics output. */ int docfl; /** Flags to use for pages when opening graphics output. */ int pagefl; /** Value to show in progress bar. */ int gaugeValue; /** Next step type, one from enumeration. */ int nst; /** No errors occured for current file. */ int graOkForFile; /** Flag: Critical variables are currently in use. */ bool bInUse; /** Indicate successful processing without errors. */ bool bSuccess; /** Run in make operating mode on directories. */ bool bMakeMode; /** Flag: Memory error already reported. */ bool bRepMem; protected: /** Execute one processing step. @param cc Flag: Can continue. @param rqm Flag: Require more idle events. @param upd Flag: Update dialog after step. */ void ProcessingStep(bool & cc, bool & rqm, bool & upd); /** Execute one processing step. @param cc Flag: Can continue. @param rqm Flag: Require more idle events. @param upd Flag: Update dialog after step. */ void ProcessingNewFile(bool & cc, bool & rqm, bool & upd); /** Execute one processing step. @param cc Flag: Can continue. @param rqm Flag: Require more idle events. @param upd Flag: Update dialog after step. */ void ProcessingGenerateOutput(bool & cc, bool & rqm, bool & upd); /** Execute one processing step. @param cc Flag: Can continue. @param rqm Flag: Require more idle events. @param upd Flag: Update dialog after step. */ void ProcessingWriteOutput(bool & upd); /** Add one input file name to storage. @param infilename Input candidate file. @param checkmake Flag: Check whether output file exists. @param ok Success variable to reset on errors. */ void AddNameToStorage( wxString & infilename, bool checkmake, bool & ok ); /** Check whether a file name is suitable as input file. @param infilename Input file name to check. @return True if the file can be used, false otherwise. */ bool CheckNameSuffix(wxChar const *infilename); %% class end public: /** Constructor. @param parent Parent window. @param pAH Application helper. @param localizedTexts Localized texts in users language. @param dirname Directory or file to process. @param grco Graphics configuration. @param makemode Bool: Operate like "make". @param errStr Error string to store error messages. */ Bmpp4Progress( wxFrame *parent, Dk4WxApplicationHelper *pAH, wxChar const * const *localizedTexts, wxString dirname, dk4_gra_conf_t const *grco, bool makemode, wxString *errStr ); /** Destructor. */ ~Bmpp4Progress(); /** Prepare data structures for processing. @return True on success, false on error. */ bool PrepareProcessing(void); /** Clean up data structures after processing. */ void Cleanup(void); /** Idle event handler, do processing step. @param event Event to process. */ void OnIdle(wxIdleEvent & event); /** Cancel button handler, abort processing. @param event Event to process. */ void OnCancel(wxCommandEvent & event); bool CanEnterCriticalSection(void); void LeaveCriticalSection(void); }; %% header end /* vim: set ai sw=4 ts=4 : */ %% module start #include "wxbmpp.h" #ifndef DK4STRD_H_INCLUDED #include "dk4strd.h" #endif #ifndef DK4PATHD_H_INCLUDED #include "dk4pathd.h" #endif #ifndef DK4UNUSED_H_INCLUDED #include "dk4unused.h" #endif #ifndef DK4MM_H_INCLUDED #include "dk4mm.h" #endif #ifndef DK4MATH_H_INCLUDED #include "dk4math.h" #endif #ifndef DK4MPL_H_INCLUDED #include "dk4mpl.h" #endif $!trace-include /** Event handler table. */ #if wxCHECK_VERSION(3,0,0) wxBEGIN_EVENT_TABLE(Bmpp4Progress,wxDialog) #else BEGIN_EVENT_TABLE(Bmpp4Progress,wxDialog) #endif EVT_IDLE(Bmpp4Progress::OnIdle) EVT_BUTTON(wxID_CANCEL,Bmpp4Progress::OnCancel) #if wxCHECK_VERSION(3,0,0) wxEND_EVENT_TABLE() #else END_EVENT_TABLE() #endif /** List of suffixes for input file names. */ static wxChar const * const input_suffixes[] = { $!string-table macro=wxT .png .jpg .jpeg .tif .tiff .pbm .pgm .ppm .pnm .pam $!end }; /** Output file name suffixes. */ dkChar const * const output_suffixes[] = { $!string-table macro=dkT .pdf .eps .ps $!end }; /** Release memory for one one_file_t structure. @param ptr Structure to release. */ static void one_file_free(one_file_t *ptr) { $? "+ one_file_free" if (NULL != ptr) { #if TRACE_DEBUG if (NULL != ptr->infilename) { $? ". wx ifn = \"%!ws\"", ptr->infilename } if (NULL != ptr->shortifn) { $? ". wx short = \"%!ws\"", ptr->shortifn } if (NULL != ptr->dkifn) { $? ". dk ifn = \"%!ds\"", ptr->dkifn } if (NULL != ptr->dkofn) { $? ". dk ofn = \"%!ds\"", ptr->dkofn } $? ". mcheck = %u", (unsigned)(ptr->mcheck) #endif dk4mem_release(ptr->infilename); dk4mem_release(ptr->dkifn); dk4mem_release(ptr->dkofn); ptr->shortifn = NULL; dk4mem_free(ptr); } $? "- one_file_free" } /** Create structure for one file to process. @param wxifn Input file name as wxChar string. @param dkifn Input file name as dkChar string. @param dkosu Output file name suffix as dkChar string. @param mcheck Flag: Use make-mode check. @return Valid pointer to new structure on success, NULL on error. */ static one_file_t * one_file_new( wxChar const *wxifn, dkChar const *dkifn, dkChar const *dkosu, unsigned char mcheck ) { one_file_t *back = NULL; wxChar *p1; wxChar *p2; int ok = 0; $? "+ one_file_new" $? ". wx ifn = \"%!ws\"", wxifn $? ". dk ifn = \"%!ds\"", dkifn $? ". suffix = \"%!ds\"", dkosu $? ". mcheck = %u", (unsigned)mcheck back = dk4mem_new(one_file_t,1,NULL); if (NULL != back) { back->infilename = NULL; back->shortifn = NULL; back->dkifn = NULL; back->dkofn = NULL; back->mcheck = mcheck; back->infilename = dk4strx_dup(wxifn, NULL); if (NULL != back->infilename) { back->dkifn = dk4str_dup(dkifn, NULL); if (NULL != back->dkifn) { back->dkofn = dk4path_dup_change_suffix(dkifn, dkosu, NULL); if (NULL != back->dkofn) { $? ". dk ofn = \"%!ds\"", back->dkofn /* All allocations succeeded */ ok = 1; /* Set pointer to short file name */ back->shortifn = back->infilename; p1 = back->infilename; p2 = NULL; while (wxT('\0') != *p1) { #if DK4_HAVE_BACKSLASH_AS_SEP if (wxT('\\') == *p1) { p2 = p1; } #else if (wxT('/') == *p1) { p2 = p1; } #endif p1++; } if (NULL != p2) { p2++; back->shortifn = p2; } $? ". wx shortifn = \"%!ws\"", back->shortifn } } } /* Destroy structure and return NULL if one of the allocations failed */ if (0 == ok) { one_file_free(back); back = NULL; } } $? "- one_file_new %d", TR_IPTR(back) return back; } /** Compare two one_file_t structures by infilename component. @param l Left structure. @param r Right structure. @param cr Comparison criteria (ignored). @return Comparison result: 1 for l>r, 0 for l=r, -1 for linfilename) { if (NULL != pr->infilename) { back = dk4strx_pathcmp(pl->infilename, pr->infilename); } else { back = 1; } } else { if (NULL != pr->infilename) { back = -1; } } } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } bool Bmpp4Progress::CheckNameSuffix(wxChar const *infilename) { wxChar const *fns; bool back = false; $? "+ CheckNameSuffix \"%!ws\"", infilename fns = dk4strx_get_path_suffix(infilename, NULL); if (NULL != fns) { switch ( dk4strx_array_index(input_suffixes, fns, 0) ) { case 0 : { #if DK4_HAVE_PNG_H back = true; #endif } break; case 1 : case 2 : { #if DK4_HAVE_JPEGLIB_H back = true; #endif } break; case 3 : case 4 : { #if DK4_HAVE_TIFF_H back = true; #endif } break; case 5 : case 6 : case 7 : case 8 : case 9 : { back = true; } break; } } $? "- CheckNameSuffix %d", (back ? 1 : 0) return back; } void Bmpp4Progress::AddNameToStorage( wxString & infilename, bool checkmake, bool & ok ) { dkChar dkifn[DK4_MAX_PATH]; dk4_er_t er; dkChar const *osu; one_file_t *onefile; size_t szdkifn = DK4_SIZEOF(dkifn,dkChar); $? "+ AddNameToStorage" #if 0 $? ". wx infilename = \"%!ws\"", (const wxChar *)(infilename.c_str()) #endif wxCStrData infnamestrdata = infilename.c_str(); if (CheckNameSuffix((wxChar const *)infnamestrdata)) { dk4error_init(&er); if ( pAppHelp->StringToDk( dkifn, szdkifn, (wxChar const *)infnamestrdata, &er ) ) { if (SIZE_MAX > szFiles) { osu = output_suffixes[0]; switch (graconf.driver) { case DK4_GRA_DRIVER_EPS : { osu = output_suffixes[1]; } break; case DK4_GRA_DRIVER_PS : { osu = output_suffixes[2]; } break; } onefile = one_file_new( (wxChar const *)infnamestrdata, dkifn, osu, ((bMakeMode && checkmake) ? (0x01) : (0x00)) ); if (NULL != onefile) { if (0 != dk4sto_add(sFiles, onefile, NULL)) { szFiles++; } else { one_file_free(onefile); /* ERROR: Memory */ if (!(bRepMem)) { pErrors->Append(sTexts[112]); bRepMem = true; } ok = false; bSuccess = false; } } else { /* ERROR: Memory */ if (!(bRepMem)) { pErrors->Append(sTexts[112]); bRepMem = true; } ok = false; bSuccess = false; } } } else { switch (er.ec) { case DK4_E_SYNTAX : { /* ERROR: Unconvertable character */ pErrors->Append(infilename); pErrors->Append(sTexts[113]); } break; default : { /* ERROR: Name too long */ pErrors->Append(infilename); pErrors->Append(sTexts[114]); } break; } ok = false; bSuccess = false; } } $? "- AddNameToStorage" } %% constructor start Bmpp4Progress::Bmpp4Progress( wxFrame *parent, Dk4WxApplicationHelper *pAH, wxChar const * const *localizedTexts, wxString dirname, dk4_gra_conf_t const *grco, bool makemode, wxString *errStr ) : wxDialog( parent, wxID_ANY, localizedTexts[98], wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE ) { $? "+ Bmpp4Progress" pAppHelp = pAH; sTexts = localizedTexts; bSuccess = true; bInUse = false; sDirname = dirname; DK4_MEMCPY(&graconf,grco,sizeof(dk4_gra_conf_t)); bMakeMode = makemode; sFiles = NULL; iFiles = NULL; pBif = NULL; pGra = NULL; szFiles = 0; usedFiles = 0; currentFile = NULL; pErrors = errStr; nst = STEP_REPORT_ERROR; gaugeValue = 0; docfl = 0; pagefl = 0; w = 0; h = 0; curof = NULL; bRepMem = false; for (size_t i = 0; i < 8; i++) { cotra[i] = 0.0; } %% constructor end $? "- Bmpp4Progress" } %% module end Bmpp4Progress::~Bmpp4Progress() { $? "+ ~Bmpp4Progress" $? "- ~Bmpp4Progress" } bool Bmpp4Progress::PrepareProcessing(void) { wxArrayString allfilenames; /* All files in sDirname directory */ size_t numfiles; /* Number of files in allfilenames */ size_t i; /* Traverse all files */ bool back = false; $? "+ PrepareProcessing" sFiles = dk4sto_open(NULL); if (NULL != sFiles) { dk4sto_set_comp(sFiles, one_file_compare, 0); iFiles = dk4sto_it_open(sFiles, NULL); if (NULL != iFiles) { if (wxDir::Exists(sDirname)) { $? ". directory" numfiles = wxDir::GetAllFiles( sDirname, &allfilenames, wxEmptyString, (wxDIR_FILES | wxDIR_HIDDEN) ); if (0 < numfiles) { $? ". numfiles = %u", (unsigned)numfiles back = true; for (i = 0; ((back) && (i < numfiles)); i++) { AddNameToStorage(allfilenames.Item(i), true, back); } } else { bSuccess = false; /* ERROR: No file found */ pErrors->Append(sDirname); pErrors->Append(sTexts[115]); } } else { $? ". single file" back = true; AddNameToStorage(sDirname, false, back); } } else { bSuccess = false; /* ERROR: Memory */ pErrors->Append(sDirname); pErrors->Append(sTexts[116]); } } else { bSuccess = false; /* ERROR: Memory */ pErrors->Append(sDirname); pErrors->Append(sTexts[116]); } if (back) { nst = STEP_START_NEW_FILE; } $? ". number of files %u", (unsigned)szFiles $? "- PrepareProcessing %d", (back ? 1 : 0) return back; } void Bmpp4Progress::Cleanup(void) { one_file_t *ptr; $? "+ Cleanup" /* Close input bitmap and output graphics */ if (NULL != pBif) { dk4bif_close(pBif); pBif = NULL; } if (NULL != pGra) { dk4gra_close(pGra); pGra = NULL; } /* Release collection of files to process */ if (NULL != sFiles) { if (NULL != iFiles) { dk4sto_it_reset(iFiles); do { ptr = (one_file_t *)dk4sto_it_next(iFiles); if (NULL != ptr) { one_file_free(ptr); } } while(NULL != ptr); dk4sto_it_close(iFiles); } dk4sto_close(sFiles); } sFiles = NULL; iFiles = NULL; szFiles = 0; usedFiles = 0; currentFile = NULL; $? "- Cleanup" } void Bmpp4Progress::ProcessingNewFile(bool & cc, bool & rqm, bool & upd) { one_file_t *onefile; double xres; double yres; int res; int ngv; bool mustProcess; $? "+ ProcessingNewFile" /* Remove artefacts from previous files, if any */ if (NULL != pGra) { dk4gra_close(pGra); pGra = NULL; } if (NULL != pBif) { dk4bif_close(pBif); pBif = NULL; } /* Get and process next file */ if (NULL != iFiles) { $? ". iFiles" onefile = (one_file_t *)dk4sto_it_next(iFiles); if (NULL != onefile) { $? ". onefile" curof = onefile; /* Set file name. */ lFilename->SetLabel(onefile->shortifn); lProcessingStep->SetLabel(sTexts[93]); upd = true; /* Check whether processing is necessary */ mustProcess = true; if (0x00 != onefile->mcheck) { $? ". make mode, check" res = dk4makemode_must_rebuild( onefile->dkofn, onefile->dkifn ); if (0 == res) { $? ". output file exists" mustProcess = false; } } /* Start processing */ if (mustProcess) { $? ". must process" /* Create data structures to process file. */ Refresh(); Update(); graOkForFile = 1; pBif = dk4bif_open(onefile->dkifn, 0, &(graconf.ctx), NULL); if (NULL != pBif) { $? ". pBif" currentFrame = 0; docfl = dk4gra_conf_flags_document(&graconf); pagefl = dk4gra_conf_flags_image(&graconf); pagefl |= DK4_GRA_IMG_FLAG_ONLY_PAGE_CONTENTS; if (DK4_GRA_PURPOSE_DOCUMENT == graconf.purpose) { /* Document */ $? ". produce document" pagefl &= (~(DK4_GRA_IMG_FLAG_IGNORE_ASPECT_RATIO)); #if 0 pagefl &= (~(DK4_GRA_IMG_FLAG_ALLOW_ROTATION)); #endif if (DK4_GRA_DRIVER_PDF == graconf.driver) { pagefl |= DK4_GRA_IMG_FLAG_FILL_BACKGROUND; } w = (size_t)ceil(graconf.media.w); h = (size_t)ceil(graconf.media.h); } else { /* Object or image */ $? ". produce image" docfl |= DK4_GRA_PAGE_FLAG_NO_BG; if (DK4_GRA_PURPOSE_OBJECT == graconf.purpose) { pagefl &= (~(DK4_GRA_IMG_FLAG_FILL_BACKGROUND)); } else { pagefl |= DK4_GRA_IMG_FLAG_FILL_BACKGROUND; } if ((0.0 < graconf.xres) && (0.0 < graconf.yres)) { dk4bif_set_res( pBif, graconf.xres, graconf.yres, NULL ); } w = (size_t)dk4bif_get_width(pBif); h = (size_t)dk4bif_get_height(pBif); cotra[3] = (double)w; cotra[4] = (double)h; if (0 == graconf.img_ign_res) { xres = dk4bif_get_xres(pBif); yres = dk4bif_get_yres(pBif); if ((0.0 < xres) && (0.0 < yres)) { if ( (1.0e-5 < fabs(xres - 72.0)) || (1.0e-5 < fabs(yres - 72.0)) ) { xres = (72.0 * (double)w) / xres; yres = (72.0 * (double)h) / yres; if (0 != dk4ma_is_finite(xres)) { if (0 != dk4ma_is_finite(yres)) { if ((double)(SIZE_MAX) > xres) { if((double)(SIZE_MAX) > yres) { w = (size_t)ceil(xres); h = (size_t)ceil(yres); cotra[0] = ((double)w - xres) / 2.0; cotra[1] = ((double)h - yres) / 2.0; cotra[3] = xres; cotra[4] = yres; if (0.0 > cotra[0]) { cotra[0] = 0.0; } if (0.0 > cotra[1]) { cotra[1] = 0.0; } if ( 1.0e-5 > fabs(cotra[0]) ) { cotra[0] = 0.0; } if ( 1.0e-5 > fabs(cotra[1]) ) { cotra[1] = 0.0; } } } } } } } } /* Dimensions and transformations calculated */ } $? ". w = %lu", (unsigned long)w $? ". h = %lu", (unsigned long)h switch (graconf.driver) { case DK4_GRA_DRIVER_PS : case DK4_GRA_DRIVER_EPS : { pGra = dk4gra_open_ps(onefile->dkofn, w, h, docfl, NULL); } break; case DK4_GRA_DRIVER_PGF : { pGra = dk4gra_open_pgf(onefile->dkofn, w, h, docfl, 1, NULL); } break; default : { /* PDF */ pGra = dk4gra_open_pdf(onefile->dkofn, w, h, docfl, NULL); } break; } if (NULL != pGra) { graOkForFile = 1; nst = STEP_GENERATE_OUTPUT; lProcessingStep->SetLabel(sTexts[94]); } else { /* ERROR: Failed to open graphics output */ pErrors->Append(onefile->infilename); pErrors->Append(sTexts[118]); bSuccess = false; usedFiles++; lProcessingStep->SetLabel(sTexts[101]); if (0 < szFiles) { ngv = ((size_t)1000 * usedFiles) / szFiles; if (1000 < ngv) { ngv = 1000; } if (ngv != gaugeValue) { gaugeValue = ngv; gProgress->SetValue(ngv); } } } } else { $? "! failed to read input image file" /* ERROR: Failed to read input file */ pErrors->Append(onefile->infilename); pErrors->Append(sTexts[117]); bSuccess = false; usedFiles++; lProcessingStep->SetLabel(sTexts[101]); if (0 < szFiles) { ngv = ((size_t)1000 * usedFiles) / szFiles; if (1000 < ngv) { ngv = 1000; } if (ngv != gaugeValue) { gaugeValue = ngv; gProgress->SetValue(ngv); } } } } else { $? ". no need to process" /* No need to process file, destination file up to date */ usedFiles++; lProcessingStep->SetLabel(sTexts[101]); if (0 < szFiles) { ngv = ((size_t)1000 * usedFiles) / szFiles; if (1000 < ngv) { ngv = 1000; } if (ngv != gaugeValue) { gaugeValue = ngv; gProgress->SetValue(ngv); } } } } else { /* No more files, finished successfully */ cc = rqm = false; } } else { cc = rqm = false; } $? "- ProcessingNewFile" } void Bmpp4Progress::ProcessingGenerateOutput(bool & cc, bool & rqm, bool & upd) { double xl; /* Left y position */ double xr; /* Right x position */ double yb; /* Bottom y position */ double yt; /* Top y position */ $? "+ ProcessingGenerateOutput" if ((NULL != pGra) && (NULL != pBif)) { if ( ( (DK4_GRA_PURPOSE_DOCUMENT == graconf.purpose) && (dk4bif_get_number_of_frames(pBif) > currentFrame) ) || (0 == currentFrame) ) { if (0 != dk4bif_set_current_frame(pBif, currentFrame)) { if (DK4_GRA_PURPOSE_DOCUMENT == graconf.purpose) { /* Produce page in a document */ if ((0.0 < graconf.xres) && (0.0 < graconf.yres)) { dk4bif_set_res(pBif, graconf.xres, graconf.yres, NULL); } xl = graconf.media.i; xr = graconf.media.w - graconf.media.o; yb = graconf.media.b; yt = graconf.media.h - graconf.media.t; if ((size_t)0U != (currentFrame % (size_t)2U)) { $? ". even page tumble/duplex" if (0 != graconf.doc_tumble) { yb = graconf.media.t; yt = graconf.media.h - graconf.media.b; } else { if (0 != graconf.doc_duplex) { xl = graconf.media.o; xr = graconf.media.w - graconf.media.i; } } } dk4gra_page(pGra, &graOkForFile, NULL); dk4gra_bif_image( pGra, xl, xr, yb, yt, pBif, curof->dkifn, currentFrame, pagefl, NULL, &graOkForFile, NULL ); } else { /* Produce object or image */ dk4gra_page(pGra, &graOkForFile, NULL); dk4gra_bif_cotra_image( pGra,cotra,pBif,curof->dkifn,0,pagefl,&graOkForFile,NULL ); } } else { /* ERROR: Failed to set frame */ pErrors->Append(curof->infilename); pErrors->Append(sTexts[119]); bSuccess = false; } currentFrame++; if (DK4_GRA_PURPOSE_DOCUMENT == graconf.purpose) { if (dk4bif_get_number_of_frames(pBif) <= currentFrame) { nst = STEP_WRITE_FILE; dk4bif_close(pBif); pBif = NULL; lProcessingStep->SetLabel(sTexts[95]); upd = true; } } else { nst = STEP_WRITE_FILE; dk4bif_close(pBif); pBif = NULL; } } else { nst = STEP_WRITE_FILE; dk4bif_close(pBif); pBif = NULL; } } else { /* ##### BUG */ cc = rqm = false; } $? "- ProcessingGenerateOutput" } void Bmpp4Progress::ProcessingWriteOutput(bool & upd) { int ngv; /* New value for gauge */ $? "+ ProcessingWriteOutput" if (NULL != pGra) { $? ". pGra" if (0 != graOkForFile) { $? ". graOkForFile" dk4gra_write_and_close(pGra, &graOkForFile, NULL); if (0 == graOkForFile) { $? "! error wile writing" /* ERROR: Failed to write */ pErrors->Append(curof->infilename); pErrors->Append(sTexts[120]); bSuccess = false; } } else { $? "! graOkForFile" dk4gra_close(pGra); } pGra = NULL; usedFiles++; if (0 < szFiles) { ngv = ((size_t)1000 * usedFiles) / szFiles; if (1000 < ngv) { ngv = 1000; } if (ngv != gaugeValue) { gaugeValue = ngv; gProgress->SetValue(ngv); lProcessingStep->SetLabel(sTexts[93]); upd = true; } } } #if TRACE_DEBUG else { $? "! pGra" /* ##### BUG */ #if 0 cc = rqm = false; #endif } #endif nst = STEP_START_NEW_FILE; $? "- ProcessingWriteOutput" } void Bmpp4Progress::ProcessingStep(bool & cc, bool & rqm, bool & upd) { $? "+ ProcessingStep" switch (nst) { case STEP_START_NEW_FILE : { /* Start processing for next input file candidate */ ProcessingNewFile(cc, rqm, upd); } break; case STEP_GENERATE_OUTPUT : { /* Prepare output for next frame */ ProcessingGenerateOutput(cc, rqm, upd); } break; case STEP_WRITE_FILE : { /* Write output to file */ ProcessingWriteOutput(upd); } break; case STEP_REPORT_ERROR : { /* Report error and skip processing */ cc = rqm = false; } break; } $? "- ProcessingStep" } void Bmpp4Progress::OnIdle(wxIdleEvent & event) { bool rqm = true; /* Request more idle events */ bool cc = true; /* Can continue */ bool upd = true; /* Must update window */ $? "+ OnIdle" if (CanEnterCriticalSection()) { ProcessingStep(cc, rqm, upd); if (cc) { LeaveCriticalSection(); if (upd) { Refresh(); Update(); } } else { if(IsModal()) { EndModal((bSuccess) ? wxID_OK : wxID_CANCEL); } else { SetReturnCode((bSuccess) ? wxID_OK : wxID_CANCEL); Show(false); } } if (rqm) { event.RequestMore(); } } else { } $? "- OnIdle" event.Skip(); } void Bmpp4Progress::OnCancel(wxCommandEvent & WXUNUSED(event)) { bool done = false; $? "+ OnCancel" /* First wait until other code sections accessing critical variables are done, deny other code to enter critical sections */ do { wxCriticalSectionLocker lock(csProtect); if (!(bInUse)) { bInUse = true; done = true; bSuccess = false; } } while (!(done)); pErrors->Append(sTexts[121]); /* Now close the dialog */ if(IsModal()) { EndModal((bSuccess) ? wxID_OK : wxID_CANCEL); } else { SetReturnCode((bSuccess) ? wxID_OK : wxID_CANCEL); Show(false); } $? "- OnCancel" } bool Bmpp4Progress::CanEnterCriticalSection(void) { bool back = false; { wxCriticalSectionLocker lock(csProtect); if (!(bInUse)) { bInUse = true; back = true; } } return back; } void Bmpp4Progress::LeaveCriticalSection(void) { wxCriticalSectionLocker lock(csProtect); bInUse = false; } /* vim: set ai sw=4 ts=4 : */