@@ -32,7 +32,8 @@ var language = defaultLanguage;
3232export const model = {
3333 fileDirectory : '' ,
3434 filePath : '' ,
35- isOpen : false
35+ isOpen : false ,
36+ isModified : false
3637} ;
3738
3839export function getMenuTemplate ( ) {
@@ -147,9 +148,8 @@ export function getMenuTemplate () {
147148
148149// Open file system dialog and read file contents into model
149150function openModel ( ) {
150- if ( model . isOpen === true ) {
151- logger . log . debug ( 'Checking that the existing model is not modified' ) ;
152- logger . log . warn ( 'TODO check from renderer that existing open file is not modified' ) ;
151+ if ( guardModel ( ) === false ) {
152+ return ;
153153 }
154154 dialog . showOpenDialog ( {
155155 title : messages [ language ] . desktop . file . open ,
@@ -226,6 +226,9 @@ function saveModelDataAs (modelData, fileName) {
226226
227227// open a new model
228228function newModel ( ) {
229+ if ( guardModel ( ) === false ) {
230+ return ;
231+ }
229232 let newName = 'new-model.json' ;
230233 logger . log . debug ( messages [ language ] . desktop . file . new + ': ' + newName ) ;
231234 // prompt the renderer to open a new model
@@ -242,12 +245,38 @@ function printModel () {
242245
243246// close the model
244247function closeModel ( ) {
248+ if ( guardModel ( ) === false ) {
249+ return ;
250+ }
245251 logger . log . debug ( messages [ language ] . desktop . file . close + ': ' + model . filePath ) ;
246252 // prompt the renderer to close the model
247253 mainWindow . webContents . send ( 'close-model' , path . basename ( model . filePath ) ) ;
248254 modelClosed ( ) ;
249255}
250256
257+ // close the model
258+ export function guardModel ( ) {
259+ if ( model . isOpen === false || model . isModified === false ) {
260+ return true ;
261+ }
262+ logger . log . debug ( 'Check existing open and modified model can be closed' ) ;
263+ const dialogOptions = {
264+ title : messages [ language ] . forms . discardTitle ,
265+ message : messages [ language ] . forms . discardMessage ,
266+ buttons : [ messages [ language ] . forms . ok , messages [ language ] . forms . cancel ] ,
267+ type : 'warning' ,
268+ defaultId : 1 ,
269+ cancelId : 1
270+ } ;
271+ let guard = false ;
272+ let result = dialog . showMessageBoxSync ( mainWindow , dialogOptions ) ;
273+ if ( result === 0 ) {
274+ guard = true ;
275+ }
276+ logger . log . debug ( messages [ language ] . forms . discardTitle + ': ' + guard ) ;
277+ return guard ;
278+ }
279+
251280// read threat model from file, eg after open-file app module event
252281export function readModelData ( filePath ) {
253282 model . filePath = filePath ;
@@ -282,22 +311,6 @@ function saveModelData (modelData) {
282311 }
283312}
284313
285- // the renderer has requested to save the model with a filename
286- export const modelSaved = ( modelData , fileName ) => {
287- // if the filePath is empty then this is the first time a save has been requested
288- if ( ! model . filePath || model . filePath === '' ) {
289- saveModelDataAs ( modelData , fileName ) ;
290- } else {
291- saveModelData ( modelData ) ;
292- }
293- } ;
294-
295- // clear out the model, either by menu or by renderer request
296- export const modelClosed = ( ) => {
297- model . filePath = '' ;
298- model . isOpen = false ;
299- } ;
300-
301314// Open saveAs file system dialog and write contents as HTML
302315function saveHTMLReport ( htmlPath ) {
303316 htmlPath += '.html' ;
@@ -360,6 +373,25 @@ function savePDFReport (pdfPath) {
360373 } ) ;
361374}
362375
376+ // clear out the model, either by menu or by renderer request
377+ export const modelClosed = ( ) => {
378+ model . filePath = '' ;
379+ model . isOpen = false ;
380+ } ;
381+
382+ // the renderer has modified the model
383+ export const modelModified = ( modified ) => {
384+ model . isModified = modified ;
385+ } ;
386+
387+ // the renderer has opened a new model
388+ export const modelOpened = ( ) => {
389+ // for security reasons the renderer can not provide the full path
390+ // so wait for a save before filling in the file path
391+ model . filePath = '' ;
392+ model . isOpen = true ;
393+ } ;
394+
363395// the renderer has requested a report to be printed
364396export const modelPrint = ( printer ) => {
365397 let reportPath = path . join ( path . dirname ( model . filePath ) , path . basename ( model . filePath , '.json' ) ) ;
@@ -376,14 +408,17 @@ export const modelPrint = (printer) => {
376408 }
377409} ;
378410
379- // the renderer has opened a new model
380- export const modelOpened = ( ) => {
381- // for security reasons the renderer can not provide the full path
382- // so wait for a save before filling in the file path
383- model . filePath = '' ;
384- model . isOpen = true ;
411+ // the renderer has requested to save the model with a filename
412+ export const modelSaved = ( modelData , fileName ) => {
413+ // if the filePath is empty then this is the first time a save has been requested
414+ if ( ! model . filePath || model . filePath === '' ) {
415+ saveModelDataAs ( modelData , fileName ) ;
416+ } else {
417+ saveModelData ( modelData ) ;
418+ }
385419} ;
386420
421+ // the renderer has changed the language
387422export const setLocale = ( locale ) => {
388423 language = languages . includes ( locale ) ? locale : defaultLanguage ;
389424} ;
@@ -394,7 +429,9 @@ export const setMainWindow = (window) => {
394429
395430export default {
396431 getMenuTemplate,
432+ guardModel,
397433 modelClosed,
434+ modelModified,
398435 modelOpened,
399436 modelPrint,
400437 modelSaved,
0 commit comments