File : core/TravelEditor.js

1
/*
2
Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
*/
18
/*
19
Changes:
20
    - v4.0.0:
21
        - created from v3.6.0
22
Doc reviewed 202208
23
 */
24
25
import theTranslator from './uiLib/Translator.js';
26
import theTravelNotesData from '../data/TravelNotesData.js';
27
import theConfig from '../data/Config.js';
28
import theErrorsUI from '../uis/errorsUI/ErrorsUI.js';
29
import theRouteEditor from './RouteEditor.js';
30
import theUtilities from './uiLib/Utilities.js';
31
import Travel from '../data/Travel.js';
32
import theEventDispatcher from './lib/EventDispatcher.js';
33
import FileCompactor from './lib/FileCompactor.js';
34
import theProfileDialogsManager from './ProfileDialogsManager.js';
35
import { INVALID_OBJ_ID, SAVE_STATUS } from '../main/Constants.js';
36
import theMouseUI from '../uis/mouseUI/MouseUI.js';
37
import SaveAsDialog from '../dialogs/saveAsDialog/SaveAsDialog.js';
38
import theDevice from './lib/Device.js';
39
40
/* ------------------------------------------------------------------------------------------------------------------------- */
41
/**
42
This class contains methods fot Travel creation or modifications
43
See theTravelEditor for the one and only one instance of this class
44
*/
45
/* ------------------------------------------------------------------------------------------------------------------------- */
46
47
class TravelEditor {
48
49
    /**
50
    This method save the travel to a file, removing notes and maneuvers, depending of the user choice.
51
    @param {SaveAsDialogData} saveAsDialogData an object describing witch data must be saved
52
    */
53
54
    #saveAsTravel ( saveAsDialogData ) {
55
56
        const saveAsTravel = new Travel ( );
57
        saveAsTravel.jsonObject = theTravelNotesData.travel.jsonObject;
58
        saveAsTravel.name += '-partial';
59
        let routesIterator = saveAsTravel.routes.iterator;
60
        while ( ! routesIterator.done ) {
61
            routesIterator.value.hidden = false;
62
        }
63
        if ( saveAsDialogData.removeTravelNotes ) {
64
            saveAsTravel.notes.removeAll ( );
65
        }
66
        if ( saveAsDialogData.removeRoutesNotes ) {
67
            routesIterator = saveAsTravel.routes.iterator;
68
            while ( ! routesIterator.done ) {
69
                routesIterator.value.notes.removeAll ( );
70
            }
71
        }
72
        if ( saveAsDialogData.removeManeuvers ) {
73
            routesIterator = saveAsTravel.routes.iterator;
74
            while ( ! routesIterator.done ) {
75
                routesIterator.value.itinerary.maneuvers.removeAll ( );
76
            }
77
        }
78
        const compressedSaveAsTravel = new FileCompactor ( ).compress ( saveAsTravel );
79
        theUtilities.saveFile (
80
            compressedSaveAsTravel.name + '.' +
81
                ( theDevice.isTouch ? theConfig.files.writeTouch : theConfig.files.writeOthers ),
82
            JSON.stringify ( compressedSaveAsTravel ),
83
            'application/json'
84
        );
85
    }
86
87
    /**
88
    Verify that the travel have a name.
89
    Show an error and the TravelPropertiesDialog if no name
90
    @return {Boolean} true when the travel is named
91
    */
92
93
    #verifyTravelName ( ) {
94
        if ( '' === theTravelNotesData.travel.name ) {
95
            theErrorsUI.showError ( theTranslator.getText ( 'TravelEditor - Gives a name to the travel' ) );
96
            theEventDispatcher.dispatch ( 'showtravelproperties' );
97
            return false;
98
        }
99
        return true;
100
    }
101
102
    /**
103
    The constructor
104
    */
105
106
    constructor ( ) {
107
        Object.freeze ( this );
108
    }
109
110
    /**
111
    This method is called when a route is dropped in the TravelUI and then routes reordered.
112
    @param {Number} draggedRouteObjId The objId of the dragged route
113
    @param {Number} targetRouteObjId The objId of the route on witch the drop was executed
114
    @param {Boolean} draggedBefore when true the dragged route is moved before the target route
115
    when false after
116
    */
117
118
    routeDropped ( draggedRouteObjId, targetRouteObjId, draggedBefore ) {
119
        const newDraggedRouteObjId =
120
            draggedRouteObjId === theTravelNotesData.travel.editedRoute.objId
121
                ?
122
                theTravelNotesData.editedRouteObjId
123
                :
124
                draggedRouteObjId;
125
126
        const newTargetRouteObjId =
127
            targetRouteObjId === theTravelNotesData.travel.editedRoute.objId
128
                ?
129
                theTravelNotesData.editedRouteObjId
130
                :
131
                targetRouteObjId;
132
133
        theTravelNotesData.travel.routes.moveTo ( newDraggedRouteObjId, newTargetRouteObjId, draggedBefore );
134
        theRouteEditor.chainRoutes ( );
135
        theEventDispatcher.dispatch ( 'updatetravelproperties' );
136
        theEventDispatcher.dispatch ( 'updateroadbook' );
137
    }
138
139
    /**
140
    This method save the current travel to a file. The user can choose to save the notes and the maneuvers
141
    */
142
143
    saveAsTravel ( ) {
144
        if ( ! this.#verifyTravelName ( ) ) {
145
            return;
146
        }
147
        if ( INVALID_OBJ_ID !== theTravelNotesData.editedRouteObjId ) {
148
            theErrorsUI.showError (
149
                theTranslator.getText ( 'TravelEditor - Not possible to partial save when a route is edited.' )
150
            );
151
            theEventDispatcher.dispatch ( 'showtravelproperties' );
152
            return;
153
        }
154
155
        new SaveAsDialog ( ).show ( )
156
            .then ( removeData => { this.#saveAsTravel ( removeData ); } )
157
            .catch (
158
                err => {
159
                    if ( err instanceof Error ) {
160
                        console.error ( err );
161
                    }
162
                }
163
            );
164
    }
165
166
    /**
167
    This method save the current travel to a file
168
    */
169
170
    saveTravel ( ) {
171
        if ( ! this.#verifyTravelName ( ) ) {
172
            return;
173
        }
174
        const routesIterator = theTravelNotesData.travel.routes.iterator;
175
        while ( ! routesIterator.done ) {
176
            routesIterator.value.hidden = false;
177
        }
178
        const compressedTravel = new FileCompactor ( ).compress ( theTravelNotesData.travel );
179
        theUtilities.saveFile (
180
            compressedTravel.name + '.' +
181
            ( theDevice.isTouch ? theConfig.files.writeTouch : theConfig.files.writeOthers ),
182
            JSON.stringify ( compressedTravel ),
183
            'application/json'
184
        );
185
        theMouseUI.saveStatus = SAVE_STATUS.saved;
186
    }
187
188
    /**
189
    This method clear the current travel and start a new travel
190
    */
191
192
    newTravel ( ) {
193
        if (
194
            theConfig.travelNotes.haveBeforeUnloadWarning &&
195
            ( ! window.confirm ( theTranslator.getText (
196
                'TravelEditor - This page ask to close; data are perhaps not saved.' ) ) )
197
        ) {
198
            return;
199
        }
200
        theProfileDialogsManager.deleteAllProfiles ( );
201
        theEventDispatcher.dispatch ( 'removeallobjects' );
202
203
        theTravelNotesData.editedRouteObjId = INVALID_OBJ_ID;
204
        theTravelNotesData.travel.jsonObject = new Travel ( ).jsonObject;
205
206
        theEventDispatcher.dispatch ( 'updatetravelproperties' );
207
        theEventDispatcher.dispatch ( 'updateroadbook' );
208
        theEventDispatcher.dispatch ( 'updatetravelnotes' );
209
        if ( theConfig.travelNotes.startupRouteEdition ) {
210
            theRouteEditor.editRoute ( theTravelNotesData.travel.routes.first.objId );
211
        }
212
        theMouseUI.saveStatus = SAVE_STATUS.saved;
213
    }
214
}
215
216
/* ------------------------------------------------------------------------------------------------------------------------- */
217
/**
218
The one and only one instance of TravelEditor class
219
@type {TravelEditor}
220
*/
221
/* ------------------------------------------------------------------------------------------------------------------------- */
222
223
const theTravelEditor = new TravelEditor ( );
224
225
export default theTravelEditor;
226
227
/* --- End of file --------------------------------------------------------------------------------------------------------- */
228