Skip to content

Commit 626f751

Browse files
authored
Warn users before discarding their unsaved scripts (#3852)
* Warn users before discarding their unsaved scripts This closes #3846.
1 parent e6b9b0f commit 626f751

File tree

7 files changed

+48
-1
lines changed

7 files changed

+48
-1
lines changed

Diff for: fontforge/views.h

+1
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ typedef struct fontview {
476476
struct lookup_subtable *cur_subtable;
477477
struct qg_data *qg;
478478
GPid pid_webfontserver;
479+
bool script_unsaved; // Whether or not there's an unsaved script in script dialog
479480
} FontView;
480481

481482
typedef struct findsel {

Diff for: fontforgeexe/fontview.c

+20
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ char *script_filenames[SCRIPT_MENU_MAX];
8080
extern int onlycopydisplayed, copymetadata, copyttfinstr, add_char_to_name_list;
8181
int home_char='A';
8282
int compact_font_on_open=0;
83+
bool warn_script_unsaved = true;
8384
int navigation_mask = 0; /* Initialized in startui.c */
8485

8586
static char *fv_fontnames = MONO_UI_FAMILIES;
@@ -534,6 +535,22 @@ static int AskChanged(SplineFont *sf) {
534535
return( ret );
535536
}
536537

538+
static int AskScriptChanged() {
539+
int ret;
540+
char *buts[4];
541+
542+
buts[0] = _("_Yes");
543+
buts[1] = _("Yes, and don't _remind me again");
544+
buts[2] = _("_No");
545+
buts[3] = NULL;
546+
ret = gwwv_ask( _("Unsaved script"),(const char **) buts,0,2,_("You have an unsaved script in the «Execute Script» dialog. Do you intend to discard it?"));
547+
if (ret == 1) {
548+
warn_script_unsaved = false;
549+
SavePrefs(true);
550+
}
551+
return( ret );
552+
}
553+
537554
int _FVMenuGenerate(FontView *fv,int family) {
538555
FVFlattenAllBitmapSelections(fv);
539556
return( SFGenerateFont(fv->b.sf,fv->b.active_layer,family,fv->b.normal==NULL?fv->b.map:fv->b.normal) );
@@ -858,6 +875,9 @@ return( false );
858875

859876
if ( fv->b.nextsame!=NULL || fv->b.sf->fv!=&fv->b ) {
860877
/* There's another view, can close this one with no problems */
878+
} else if ( warn_script_unsaved && fv->script_unsaved &&
879+
AskScriptChanged()==2 ) {
880+
return false;
861881
} else if ( SFAnyChanged(sf) ) {
862882
i = AskChanged(fv->b.sf);
863883
if ( i==2 ) /* Cancel */

Diff for: fontforgeexe/prefs.c

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ extern int prefs_cv_outline_thickness; /* from charview.c */
194194

195195
extern float OpenTypeLoadHintEqualityTolerance; /* autohint.c */
196196
extern float GenerateHintWidthEqualityTolerance; /* splinesave.c */
197+
extern bool warn_script_unsaved; /* fontview.c */
197198
extern NameList *force_names_when_opening;
198199
extern NameList *force_names_when_saving;
199200
extern NameList *namelist_for_new_fonts;
@@ -311,6 +312,7 @@ static struct prefs_list {
311312
{ N_("AutoSaveFrequency"), pr_int, &AutoSaveFrequency, NULL, NULL, '\0', NULL, 0, N_( "The number of seconds between autosaves. If you set this to 0 there will be no autosaves.") },
312313
{ N_("RevisionsToRetain"), pr_int, &prefRevisionsToRetain, NULL, NULL, '\0', NULL, 0, N_( "When Saving, keep this number of previous versions of the file. file.sfd-01 will be the last saved file, file.sfd-02 will be the file saved before that, and so on. If you set this to 0 then no revisions will be retained.") },
313314
{ N_("UndoRedoLimitToSave"), pr_int, &UndoRedoLimitToSave, NULL, NULL, '\0', NULL, 0, N_( "The number of undo and redo operations which will be saved in sfd files.\nIf you set this to 0 undo/redo information is not saved to sfd files.\nIf set to -1 then all available undo/redo information is saved without limit.") },
315+
{ N_("WarnScriptUnsaved"), pr_bool, &warn_script_unsaved, NULL, NULL, '\0', NULL, 0, N_( "Whether or not to warn you if you have an unsaved script in the «Execute Script» dialog.") },
314316
PREFS_LIST_EMPTY
315317
},
316318
new_list[] = {

Diff for: fontforgeexe/scriptingdlg.c

+4
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ return( true );
189189

190190
if ( event->type==et_close ) {
191191
SD_DoCancel( sd );
192+
} else if ( event->type==et_controlevent && event->u.control.subtype==et_textchanged ) {
193+
sd->fv->script_unsaved = !GTextFieldIsEmpty(GWidgetGetControl(sd->gw,CID_Script));
194+
} else if ( event->type==et_controlevent && event->u.control.subtype==et_save ) {
195+
sd->fv->script_unsaved = false;
192196
} else if ( event->type==et_char ) {
193197
if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
194198
help("scripting.html");

Diff for: gdraw/gtextfield.c

+19
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,19 @@ static void GTextFieldChanged(GTextField *gt,int src) {
215215
GDrawPostEvent(&e);
216216
}
217217

218+
static void GTextFieldSaved(GTextField *gt) {
219+
GEvent e;
220+
221+
e.type = et_controlevent;
222+
e.w = gt->g.base;
223+
e.u.control.subtype = et_save;
224+
e.u.control.g = &gt->g;
225+
if ( gt->g.handle_controlevent != NULL )
226+
(gt->g.handle_controlevent)(&gt->g,&e);
227+
else
228+
GDrawPostEvent(&e);
229+
}
230+
218231
static void GTextFieldFocusChanged(GTextField *gt,int gained) {
219232
GEvent e;
220233

@@ -878,6 +891,11 @@ static unichar_t txt[] = { '*','.','{','t','x','t',',','p','y','}', '\0' };
878891
static unichar_t errort[] = { 'C','o','u','l','d',' ','n','o','t',' ','o','p','e','n', '\0' };
879892
static unichar_t error[] = { 'C','o','u','l','d',' ','n','o','t',' ','o','p','e','n',' ','%','.','1','0','0','h','s', '\0' };
880893

894+
bool GTextFieldIsEmpty(GGadget *g) {
895+
GTextField *gt = (GTextField *) g;
896+
return gt->text == NULL || *gt->text == '\0';
897+
}
898+
881899
static void GTextFieldImport(GTextField *gt) {
882900
unichar_t *ret;
883901
char *cret;
@@ -970,6 +988,7 @@ return;
970988
}
971989
}
972990
fclose(file);
991+
GTextFieldSaved(gt);
973992
}
974993

975994
#define MID_Cut 1

Diff for: inc/gdraw.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ enum et_subtype { et_buttonpress, et_buttonactivate, et_radiochanged,
120120
et_listselected, et_listdoubleclick,
121121
et_scrollbarchange,
122122
et_textchanged, et_textfocuschanged,
123-
et_lastsubtype };
123+
et_save, et_lastsubtype };
124124

125125
enum sb { et_sb_top, et_sb_uppage, et_sb_up, et_sb_left=et_sb_up,
126126
et_sb_down, et_sb_right=et_sb_down, et_sb_downpage,

Diff for: inc/ggadget.h

+1
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ GGadgetHandler GGadgetGetHandler(GGadget *g);
406406
void GTextFieldSelect(GGadget *g,int sel_start, int sel_end);
407407
void GTextFieldShow(GGadget *g,int pos);
408408
void GTextFieldReplace(GGadget *g,const unichar_t *txt);
409+
bool GTextFieldIsEmpty(GGadget *g);
409410
void GCompletionFieldSetCompletion(GGadget *g,GTextCompletionHandler completion);
410411
void GCompletionFieldSetCompletionMode(GGadget *g,int enabled);
411412
void GGadgetClearList(GGadget *g);

0 commit comments

Comments
 (0)