void *ADM_ocrUiSetup(void) { // Create UI && prepare callback dialog=NULL; mainDisplay=NULL; smallDisplay=NULL; drawing=NULL; sdata=NULL; clipW=0; clipH=0; dialog=DIA_ocr(); gtk_register_dialog(dialog); #define ASSOCIATE(x,y) gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y) ASSOCIATE(buttonOk, actionAccept); ASSOCIATE(buttonSkip, actionSkip); ASSOCIATE(buttonSkipAll, actionSkipAll); ASSOCIATE(buttonIgnore, actionIgnore); ASSOCIATE(buttonCalibrate, actionCalibrate); gtk_widget_show(dialog); // // disable mainDisplay=WID(drawingareaBitmap); smallDisplay=WID(drawingareaSmall); CONNECT(drawingareaBitmap,expose_event,gui_draw); CONNECT(drawingareaSmall,expose_event,gui_draw_small); CONNECT(entry,activate,cb_accept); return (void *)dialog; }
uint8_t DIA_animated(ANIMATED_PARAM *param) { uint8_t ret=0; GtkWidget *dialog; const char *entries[MAX_VIGNETTE]={"spinbuttonTC0","spinbuttonTC1","spinbuttonTC2", "spinbuttonTC3","spinbuttonTC4","spinbuttonTC5" }; dialog=create_dialog1(); gtk_register_dialog(dialog); CHECK_SET(checkbuttonStd,isNTSC); SPIN_SET(spinbuttonvignetteW,vignetteW); SPIN_SET(spinbuttonvignetteH,vignetteH); if(param->backgroundImg) ENTRY_SET(entryBgd,param->backgroundImg); for(int i=0;i<MAX_VIGNETTE;i++) { gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(dialog,entries[i])), (gfloat)param->timecode[i]) ; } ASSOCIATE(button1,LOAD_BGD); //gtk_widget_show(dialog); int action; while(1) { action=gtk_dialog_run(GTK_DIALOG(dialog)); if(action==LOAD_BGD) { char *nw; GUI_FileSelRead(_("Select background picture"), &nw); if(nw) { ENTRY_SET(entryBgd,nw); ADM_dealloc(nw); } continue; } break; } if(action==GTK_RESPONSE_OK) { CHECK_GET(checkbuttonStd,isNTSC); SPIN_GET(spinbuttonvignetteW,vignetteW); SPIN_GET(spinbuttonvignetteH,vignetteH); if(param->backgroundImg) ADM_dealloc(param->backgroundImg); param->backgroundImg=NULL; ENTRY_GET(entryBgd,param->backgroundImg); for(int i=0;i<MAX_VIGNETTE;i++) { param->timecode[i]=(uint32_t)gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(dialog,entries[i]))) ; } ret=1; } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); return ret; }
uint8_t DIA_ass(ASSParams *param) { uint8_t r=0; GtkWidget *dialog=create_dialog1(); gtk_register_dialog(dialog); SPIN_SET(spinbuttonScale,font_scale); SPIN_SET(spinbuttonSpacing,line_spacing); SPIN_SET(spinbuttonTop,top_margin); SPIN_SET(spinbuttonBottom,bottom_margin); if(param->subfile) { int r; char *s=(char *)(param->subfile); gtk_editable_delete_text(GTK_EDITABLE(WID(entrySub)), 0,-1); gtk_editable_insert_text(GTK_EDITABLE(WID(entrySub)), s, strlen(s), &r); } ASSOCIATE(button1,LOADSUB); /* Upload */ int x=0,d; while(!x) { d=gtk_dialog_run(GTK_DIALOG(dialog)); switch(d) { case LOADSUB: { char *name=NULL; GUI_FileSelRead("Select ASS/SSA file",&name); if(name) { int r; gtk_editable_delete_text(GTK_EDITABLE(WID(entrySub)), 0,-1); gtk_editable_insert_text(GTK_EDITABLE(WID(entrySub)), name, strlen(name), &r); ADM_dealloc(name); } } break; case GTK_RESPONSE_OK: case GTK_RESPONSE_APPLY: { SPIN_GET(spinbuttonScale,font_scale); SPIN_GET(spinbuttonSpacing,line_spacing); SPIN_GETI(spinbuttonTop,top_margin); SPIN_GETI(spinbuttonBottom,bottom_margin); char *n; if(param->subfile) { ADM_dealloc(param->subfile); param->subfile=NULL; } n=gtk_editable_get_chars(GTK_EDITABLE (WID(entrySub)), 0, -1); printf("Name :%s\n",n); param->subfile=(ADM_filename *)ADM_strdup(n); r=1; x=1; break; } default: r=0; x=1; break; } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); return r; }
uint8_t DIA_job(uint32_t nb, char **name) { GtkListStore *store; GtkTreeViewColumn *column,*column2,*column3; GtkCellRenderer *renderer; int ret=0; GtkWidget *dialog; dialog=create_dialog1(); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gtk_register_dialog(dialog); store=gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,G_TYPE_STRING); // initialize our job structure jobs.dialog=dialog; jobs.nb=nb; jobs.name=name; jobs.status=new ADM_Job_Descriptor[nb]; jobs.store=store; memset(jobs.status,0,jobs.nb*sizeof(ADM_Job_Descriptor)); gtk_tree_view_set_model(GTK_TREE_VIEW(WID(treeview1)),GTK_TREE_MODEL (store)); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(WID(treeview1))); // Add columns renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (QT_TR_NOOP(" Job Name "), renderer, "markup", (GdkModifierType) 0, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (WID(treeview1)), column); column2 = gtk_tree_view_column_new_with_attributes (QT_TR_NOOP("Started at"), renderer, "markup", (GdkModifierType) 1, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (WID(treeview1)), column2); column3 = gtk_tree_view_column_new_with_attributes (QT_TR_NOOP("Finished at"), renderer, "markup", (GdkModifierType) 2, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (WID(treeview1)), column3); // #define ASSOCIATE(x,y) gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y) ASSOCIATE(buttonDelete,COMMAND_DELETE); ASSOCIATE(buttonDeleteAll,COMMAND_DELETE_ALL); ASSOCIATE(buttonRunAll,COMMAND_RUN_ALL); ASSOCIATE(buttonRun,COMMAND_RUN); // int running=1; gtk_widget_set_usize(WID(treeview1), 180, 300); while(running) { int sel=0,event; updateStatus(); switch(event=gtk_dialog_run(GTK_DIALOG(dialog))) { case GTK_RESPONSE_OK : running=0;break; case GTK_RESPONSE_APPLY : running=0;break; case GTK_RESPONSE_CANCEL : case GTK_RESPONSE_DELETE_EVENT: running=0;break; case COMMAND_DELETE_ALL: if(GUI_Confirmation_HIG(QT_TR_NOOP("Sure!"),QT_TR_NOOP("Delete ALL jobs"),QT_TR_NOOP("Are you sure you want to delete all jobs ?"))) { for(int i=0;i<jobs.nb;i++) jobs.status[i].status=STATUS_DELETED; } break; case COMMAND_RUN: sel=getSelection(jobs.dialog); if(sel>=jobs.nb) break; jobs.status[sel].status=STATUS_RUNNING; updateStatus(); GUI_Quiet(); TLK_getDate(&(jobs.status[sel].startDate)); if(parseECMAScript(jobs.name[sel])) jobs.status[sel].status=STATUS_SUCCEED; else jobs.status[sel].status=STATUS_FAILED; TLK_getDate(&(jobs.status[sel].endDate)); updateStatus(); GUI_Verbose(); break; case COMMAND_RUN_ALL: GUI_Quiet(); for(int i=0;i<jobs.nb;i++) { if(jobs.status[i].status==STATUS_DELETED) continue; if(jobs.status[i].status==STATUS_SUCCEED) continue; jobs.status[i].status=STATUS_RUNNING; TLK_getDate(&(jobs.status[i].startDate)); updateStatus(); if(parseECMAScript(jobs.name[i])) jobs.status[i].status=STATUS_SUCCEED; else jobs.status[i].status=STATUS_FAILED; TLK_getDate(&(jobs.status[i].endDate)); } updateStatus(); GUI_Verbose(); break; case COMMAND_DELETE: sel=getSelection(jobs.dialog); if(sel>=jobs.nb) break; if(GUI_Confirmation_HIG(QT_TR_NOOP("Sure!"),QT_TR_NOOP("Delete job"),QT_TR_NOOP("Are you sure you want to delete %s job ?"),ADM_GetFileName(jobs.name[sel]))) { jobs.status[sel].status=STATUS_DELETED; } break; default: printf("Event:%d\n",event); GUI_Error_HIG("Jobs",QT_TR_NOOP("Unknown event"));break; } } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); // Now delete the "deleted" jobs for(int i=0;i<jobs.nb;i++) { if(jobs.status[i].status==STATUS_DELETED) { unlink(jobs.name[i]); } } delete [] jobs.status; return ret; }
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Main +++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ uint8_t ADM_ocr_engine( void) { // uint32_t nbSub=0; FILE *out=NULL; head.next=NULL; ADMVideoVobSub *vobsub=NULL; uint32_t startTime,endTime; uint32_t w,h,oldw=0,oldh=0; uint32_t oldbitmapw=0; uint32_t oldbitmaph=0; uint32_t first,last; uint32_t seqNum; char text[1024]; lang_index=0; nbGlyphs=0; ReplyType reply; // Create UI && prepare callback dialog=DIA_ocr(); gtk_register_dialog(dialog); #define ASSOCIATE(x,y) gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y) ASSOCIATE(buttonStart,actionGo); ASSOCIATE(buttonOk, actionAccept); ASSOCIATE(buttonSkip, actionSkip); ASSOCIATE(buttonSkipAll, actionSkipAll); ASSOCIATE(buttonIgnore, actionIgnore); ASSOCIATE(buttonCalibrate, actionCalibrate); ASSOCIATE(buttonGlyphLoad, actionLoadGlyph); ASSOCIATE(buttonGlyphSave, actionSaveGlyph); ASSOCIATE(buttonVobsub, actionLoadVob); ASSOCIATE(buttonSrt, actionSaveSub); gtk_widget_show(dialog); // disable mainDisplay=WID(drawingareaBitmap); smallDisplay=WID(drawingareaSmall); CONNECT(drawingareaBitmap,expose_event,gui_draw); CONNECT(drawingareaSmall,expose_event,gui_draw_small); CONNECT(entry,activate,cb_accept); _again: reply=setup(); if(reply==ReplyClose) goto endIt; printf("Go go go\n"); // Everything ready go go go redraw_x=redraw_y=0; GTK_PURGE; // Time to go // Inactivate frame1=glyph frame2=in/out buttonStart gtk_widget_set_sensitive(WID(buttonStart),0); gtk_widget_set_sensitive(WID(frameGlyph),0); gtk_widget_set_sensitive(WID(frameLoad),0); gtk_widget_set_sensitive(WID(frameBitmap),1); gtk_widget_set_sensitive(WID(buttonStart),0); char *fileout; fileout=(char *)gtk_label_get_text(GTK_LABEL(WID(labelSrt))); if(!fileout) { GUI_Error_HIG(_("Incorrect output file"), NULL); goto _again; } out=fopen(fileout,"wb"); if(!out) { GUI_Error_HIG(_("Output file error"), _("Could not open \"%s\" for writing."), fileout); goto _again; } vobsub=new ADMVideoVobSub(subparam.subname,subparam.index); nbSub=vobsub->getNbImage(); if(!nbSub) { GUI_Error_HIG(_("Problem loading sub"), NULL); delete vobsub; vobsub=NULL; goto _again; } seqNum=1; // Sub number in srt file oldw=oldh=0; //****************** // Load all bitmaps //****************** for(uint32_t i=0;i<nbSub;i++) { first=last=0; bitmap=vobsub->getBitmap(i,&startTime, &endTime,&first,&last); ADM_assert(last>=first); // something ? if(!bitmap) continue; if(first==last) continue; // If the bitmap size changed or does not exist yet... if(!workArea || oldbitmapw!=bitmap->_width || oldbitmaph!=bitmap->_height) { if(workArea) { delete [] workArea; workArea=NULL; } // Workarea is actually bigger than what we use workArea=new uint8_t[bitmap->_width*(bitmap->_height)]; memset(workArea,0,bitmap->_width*(bitmap->_height)); } oldbitmaph=bitmap->_height; oldbitmapw=bitmap->_width; // w=bitmap->_width; h=last-first+1; redraw_x=w; redraw_y=h; //** // Build againPlease: mergeBitmap(bitmap->_bitmap+first*w, workArea, bitmap->_alphaMask+first*w, w, h); if(oldw!=w || oldh !=h) { GTK_PURGE; // Force redaw } // Merge GTK_PURGE; gui_draw(); GTK_PURGE; // OCR reply=ocrBitmap(workArea,w,h); if(reply==ReplyClose) goto endIt; if(reply==ReplyCalibrate) { // //printf("TADA!!!!\n"); int val; #if 0 val=minAlpha; if(DIA_GetIntegerValue(&val, 3, 7, "Minimum alpha value", "Enter new minimum alpha")) { minAlpha=val; } #endif val=minThreshold; if(DIA_GetIntegerValue(&val, 0x30, 0x80, "Minimum pixel value", "Enter new minimum pixel")) { minThreshold=val; } goto againPlease; } // gtk_label_set_text(GTK_LABEL(WID(labelText)),decodedString); fprintf(out,"%d\n",seqNum++); uint16_t hh,mm,ss,ms; ms2time(startTime, &hh, &mm, &ss, &ms); fprintf(out,"%02d:%02d:%02d,%03d --> ",hh,mm,ss,ms); ms2time(endTime, &hh, &mm, &ss, &ms); fprintf(out,"%02d:%02d:%02d,%03d\n",hh,mm,ss,ms); fprintf(out,"%s\n\n",decodedString); // oldw=w; oldh=h; // Update infos sprintf(text,"%03d/%03d",i+1,nbSub); gtk_label_set_text(GTK_LABEL(WID(labelNbLines)),text); sprintf(text,"%03d",nbGlyphs); gtk_label_set_text(GTK_LABEL(WID(labelNbGlyphs)),text); } endIt: // Final round gtk_widget_set_sensitive(WID(frameGlyph),1); gtk_widget_set_sensitive(WID(frameLoad),0); gtk_widget_set_sensitive(WID(buttonStart),0); gtk_widget_set_sensitive(WID(frameBitmap),0); // gtk_widget_set_sensitive(WID(Current_Glyph),0); if(nbGlyphs && actionSaveGlyph==gtk_dialog_run(GTK_DIALOG(dialog))) saveGlyph(); if(vobsub) delete vobsub; vobsub=NULL; if(out) fclose(out); out=NULL; gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); if(head.next) destroyGlyphTree(&head); head.next=NULL; return 1; }
/** \fn DIA_glyphEdit \brief Dialog to edit glyph */ uint8_t DIA_glyphEdit(void) { char *glyphName; admGlyph head(1,1); uint32_t nbGlyph=0; uint8_t ret=0; // First select a file GUI_FileSelRead(QT_TR_NOOP("Select GlyphFile to edit"), &glyphName); if(!glyphName) return 0; // Try to load it if(!loadGlyph(glyphName,&head,&nbGlyph) || !nbGlyph) { destroyGlyphTree(&head); return 0; } // Convert the linear glyph to glyph array admGlyph *glyphArray[nbGlyph]; admGlyph *cur=head.next; uint32_t idx=0; while(cur) { glyphArray[idx++]=cur; cur=cur->next; } ADM_assert(idx<=nbGlyph); nbGlyph=idx; // Glyph loaded, here we go currentGlyph=head.next; dialog=create_dialog1 (); gtk_register_dialog(dialog); // Register callbacks #define ASSOCIATE(x,y) gtk_dialog_add_action_widget (GTK_DIALOG (dialog), WID(x),y) #define CONNECT(x,y,z) gtk_signal_connect(GTK_OBJECT(WID(x)), #y,GTK_SIGNAL_FUNC(z), NULL); #define ACTION_PREV 10 #define ACTION_NEXT 20 #define ACTION_PREV_EMPTY 30 #define ACTION_NEXT_EMPTY 40 #define ACTION_SAVE 50 #define ACTION_DELETE 60 #define ACTION_ACTIVATE 70 #define ACTION_SEARCH 80 #define ACTION_REWIND 90 ASSOCIATE(buttonPrev,ACTION_PREV); ASSOCIATE(buttonNext,ACTION_NEXT); ASSOCIATE(buttonEmptyPrev,ACTION_PREV_EMPTY); ASSOCIATE(buttonNextEmpty,ACTION_NEXT_EMPTY); ASSOCIATE(buttonSave,ACTION_SAVE); ASSOCIATE(buttonDelete,ACTION_DELETE); ASSOCIATE(buttonSearch,ACTION_SEARCH); ASSOCIATE(buttonRewind,ACTION_REWIND); CONNECT(drawingarea1,expose_event,glyphDraw); CONNECT(entry1,activate,glyphActivate); gtk_widget_show(dialog); glyphUpdate(); while(1) { gint b=gtk_dialog_run(GTK_DIALOG(dialog)); switch(b) { case ACTION_REWIND: currentGlyph=head.next; glyphUpdate(); continue; case ACTION_SEARCH: { char *tomatch=NULL; { // Dialog Factory to the rescue ! diaElemText txt(&tomatch,QT_TR_NOOP("String"),NULL); diaElem *elems[]={&txt}; if(!diaFactoryRun(QT_TR_NOOP("Search string"),1,elems)) { continue; break; } } printf("Searched string <%s>\n",tomatch); while(currentGlyph->next) { currentGlyph=currentGlyph->next; glyphUpdate(); if(currentGlyph->code) { printf("%s vs %s\n",currentGlyph->code,tomatch); if(!strcmp(currentGlyph->code,tomatch)) { glyphUpdate(); break; } } } ADM_dezalloc(tomatch); if(!currentGlyph->next) GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs")); } continue; break; ; case ACTION_PREV: printf("PREV\n"); if(currentGlyph!=head.next) { admGlyph *father; father=glyphSearchFather(currentGlyph,&head); if(father) { currentGlyph=father; glyphUpdate(); } } continue;break; case ACTION_NEXT: printf("NEXT\n"); if(currentGlyph->next) { currentGlyph=currentGlyph->next; glyphUpdate(); } continue;break; case ACTION_NEXT_EMPTY: printf("NEXT EMPTY\n"); while(1) { if(currentGlyph->next) { currentGlyph=currentGlyph->next; glyphUpdate(); if(!currentGlyph->code || !*(currentGlyph->code)) { break; } } else { GUI_Error_HIG(QT_TR_NOOP("End reached"),QT_TR_NOOP("No more glyphs")); break; } } continue;break; case ACTION_PREV_EMPTY: printf("PREV EMPTY\n"); while(1) { if(currentGlyph!=head.next) { admGlyph *father; father=glyphSearchFather(currentGlyph,&head); if(father) { currentGlyph=father; glyphUpdate(); if(!currentGlyph->code || !*(currentGlyph->code)) { break; } continue; } } GUI_Error_HIG(QT_TR_NOOP("Head reached"),QT_TR_NOOP("No more glyphs")); break; } continue;break; case ACTION_SAVE: saveGlyph(glyphName,&head,nbGlyph); continue;break; case ACTION_DELETE: { admGlyph *father; father=glyphSearchFather(currentGlyph,&head); ADM_assert(father); father->next=currentGlyph->next; delete currentGlyph; currentGlyph=father; if(father==&head && head.next) currentGlyph=head.next; nbGlyph--; glyphUpdate(); continue;break; } case ACTION_ACTIVATE: { const gchar *old; if(currentGlyph->code) delete [] currentGlyph->code; currentGlyph->code=NULL; // Retrieve new one old=gtk_entry_get_text (GTK_ENTRY (WID(entry1))); if(old && strlen(old)) { currentGlyph->code=new char[strlen(old)+1]; strcpy(currentGlyph->code,old); } } continue;break; } break; // exit while(1) } gtk_unregister_dialog(dialog); gtk_widget_destroy(dialog); destroyGlyphTree(&head); return ret; }