1 module dlangide.workspace.workspacesettings;
2 
3 import dlangui.core.settings;
4 import dlangui.core.i18n;
5 import ddebug.common.debugger;
6 import dlangide.workspace.project;
7 
8 import std.array : empty;
9 import std.algorithm : equal;
10 
11 /// local settings for workspace (not supposed to put under source control)
12 class WorkspaceSettings : SettingsFile {
13 
14     this(string filename) {
15         super(filename);
16     }
17 
18     private Breakpoint[] _breakpoints;
19     private EditorBookmark[] _bookmarks;
20     /// Last opened files in workspace
21     private WorkspaceFile[] _files;
22 
23     private string _startupProjectName;
24     @property string startupProjectName() {
25         return _startupProjectName;
26     }
27     @property void startupProjectName(string s) {
28         if (!s.equal(_startupProjectName)) {
29             _startupProjectName = s;
30             _setting["startupProject"] = s;
31             save();
32         }
33     }
34 
35     /// Last opened files in workspace    
36     @property WorkspaceFile[] files() {
37         return _files;
38     }
39     
40     /// Last opened files in workspace
41     @property void files(WorkspaceFile[] fs) {
42         _files = fs;
43         // Save to settings file
44         Setting obj = _setting.settingByPath("files", SettingType.ARRAY);
45         obj.clear(SettingType.ARRAY);
46         int index = 0;
47         foreach(file; fs) {
48             Setting single = new Setting();
49             single.setString("file", file.filename);
50             single.setInteger("column", file.column);
51             single.setInteger("row", file.row);
52             obj[index++] = single;
53         }
54     }
55 
56     /// list of expanded workspace explorer items
57     @property string[] expandedItems() {
58         Setting obj = _setting.settingByPath("expandedItems", SettingType.ARRAY);
59         return obj.strArray;
60     }
61 
62     /// update list of expanded workspace explorer items
63     @property void expandedItems(string[] items) {
64         Setting obj = _setting.settingByPath("expandedItems", SettingType.ARRAY);
65         obj.strArray = items;
66     }
67 
68     /// last selected workspace item in workspace explorer
69     @property string selectedWorkspaceItem() {
70         Setting obj = _setting.settingByPath("selectedWorkspaceItem", SettingType.STRING);
71         return obj.str;
72     }
73 
74     /// update last selected workspace item in workspace explorer
75     @property void selectedWorkspaceItem(string item) {
76         Setting obj = _setting.settingByPath("selectedWorkspaceItem", SettingType.STRING);
77         obj.str = item;
78     }
79 
80     /// get all breakpoints for project (for specified source file only, if specified)
81     Breakpoint[] getProjectBreakpoints(string projectName, string projectFilePath) {
82         Breakpoint[] res;
83         for (int i = cast(int)_breakpoints.length - 1; i >= 0; i--) {
84             Breakpoint bp = _breakpoints[i];
85             if (!bp.projectName.equal(projectName))
86                 continue;
87             if (!projectFilePath.empty && !bp.projectFilePath.equal(projectFilePath))
88                 continue;
89             res ~= bp;
90         }
91         return res;
92     }
93 
94     /// get all breakpoints for project (for specified source file only, if specified)
95     void setProjectBreakpoints(string projectName, string projectFilePath, Breakpoint[] bps) {
96         bool changed = false;
97         for (int i = cast(int)_breakpoints.length - 1; i >= 0; i--) {
98             Breakpoint bp = _breakpoints[i];
99             if (!bp.projectName.equal(projectName))
100                 continue;
101             if (!projectFilePath.empty && !bp.projectFilePath.equal(projectFilePath))
102                 continue;
103             for (auto j = i; j < _breakpoints.length - 1; j++)
104                 _breakpoints[j] = _breakpoints[j + 1];
105             _breakpoints.length--;
106             changed = true;
107         }
108         if (bps.length) {
109             changed = true;
110             foreach(bp; bps)
111                 _breakpoints ~= bp;
112         }
113         if (changed) {
114             setBreakpoints(_breakpoints);
115         }
116     }
117 
118     void setBreakpoints(Breakpoint[] bps) {
119         Setting obj = _setting.settingByPath("breakpoints", SettingType.ARRAY);
120         obj.clear(SettingType.ARRAY);
121         int index = 0;
122         foreach(bp; bps) {
123             Setting bpObj = new Setting();
124             bpObj.setInteger("id", bp.id);
125             bpObj.setString("file", bp.file);
126             bpObj.setInteger("line", bp.line);
127             bpObj.setBoolean("enabled", bp.enabled);
128             bpObj.setString("projectName", bp.projectName);
129             bpObj.setString("projectFilePath", bp.projectFilePath);
130             obj[index++] = bpObj;
131         }
132         _breakpoints = bps;
133         //save();
134     }
135 
136     /// get all bookmarks for project (for specified source file only, if specified)
137     EditorBookmark[] getProjectBookmarks(string projectName, string projectFilePath) {
138         EditorBookmark[] res;
139         for (int i = cast(int)_bookmarks.length - 1; i >= 0; i--) {
140             EditorBookmark bp = _bookmarks[i];
141             if (!bp.projectName.equal(projectName))
142                 continue;
143             if (!projectFilePath.empty && !bp.projectFilePath.equal(projectFilePath))
144                 continue;
145             res ~= bp;
146         }
147         return res;
148     }
149 
150     /// get all bookmarks for project (for specified source file only, if specified)
151     void setProjectBookmarks(string projectName, string projectFilePath, EditorBookmark[] bps) {
152         bool changed = false;
153         for (int i = cast(int)_bookmarks.length - 1; i >= 0; i--) {
154             EditorBookmark bp = _bookmarks[i];
155             if (!bp.projectName.equal(projectName))
156                 continue;
157             if (!projectFilePath.empty && !bp.projectFilePath.equal(projectFilePath))
158                 continue;
159             for (auto j = i; j < _bookmarks.length - 1; j++)
160                 _bookmarks[j] = _bookmarks[j + 1];
161             _bookmarks.length--;
162             changed = true;
163         }
164         if (bps.length) {
165             changed = true;
166             foreach(bp; bps)
167                 _bookmarks ~= bp;
168         }
169         if (changed) {
170             setBookmarks(_bookmarks);
171         }
172     }
173 
174     void setBookmarks(EditorBookmark[] bps) {
175         Setting obj = _setting.settingByPath("bookmarks", SettingType.ARRAY);
176         obj.clear(SettingType.ARRAY);
177         int index = 0;
178         foreach(bp; bps) {
179             Setting bpObj = new Setting();
180             bpObj.setString("file", bp.file);
181             bpObj.setInteger("line", bp.line);
182             bpObj.setString("projectName", bp.projectName);
183             bpObj.setString("projectFilePath", bp.projectFilePath);
184             obj[index++] = bpObj;
185         }
186         _bookmarks = bps;
187         //save();
188     }
189 
190     Breakpoint[] getBreakpoints() {
191         return _breakpoints;
192     }
193 
194     EditorBookmark[] getBookmarks() {
195         return _bookmarks;
196     }
197 
198     /// override to do something after loading - e.g. set defaults
199     override void afterLoad() {
200         _startupProjectName = _setting.getString("startupProject");
201         // Loading breakpoints
202         Setting obj = _setting.settingByPath("breakpoints", SettingType.ARRAY);
203         _breakpoints = null;
204         int maxBreakpointId = 0;
205         for (int i = 0; i < obj.length; i++) {
206             Breakpoint bp = new Breakpoint();
207             Setting item = obj[i];
208             bp.id = cast(int)item.getInteger("id");
209             bp.file = item.getString("file");
210             bp.projectName = item.getString("projectName");
211             bp.projectFilePath = item.getString("projectFilePath");
212             bp.line = cast(int)item.getInteger("line");
213             bp.enabled = item.getBoolean("enabled");
214             if (bp.id > maxBreakpointId)
215                 maxBreakpointId = bp.id;
216             _breakpoints ~= bp;
217         }
218         _nextBreakpointId = maxBreakpointId + 1;
219         // Loading bookmarks
220         obj = _setting.settingByPath("bookmarks", SettingType.ARRAY);
221         _bookmarks = null;
222         for (int i = 0; i < obj.length; i++) {
223             EditorBookmark bp = new EditorBookmark();
224             Setting item = obj[i];
225             bp.file = item.getString("file");
226             bp.projectName = item.getString("projectName");
227             bp.projectFilePath = item.getString("projectFilePath");
228             bp.line = cast(int)item.getInteger("line");
229             _bookmarks ~= bp;
230         }
231         // Loading files
232         _files = null;
233         obj = _setting.settingByPath("files", SettingType.ARRAY);
234         for (int i = 0; i < obj.length; i++) {
235             Setting item = obj[i];
236             WorkspaceFile file = new WorkspaceFile;
237             file.filename(item.getString("file"));
238             file.column(cast(int)item.getInteger("column"));
239             file.row(cast(int)item.getInteger("row"));
240             _files ~= file;
241         }
242     }
243 
244     override void updateDefaults() {
245     }
246 
247 }
248 
249 /// Description for workspace file
250 class WorkspaceFile {
251     /// File name with full path
252     private string _filename;
253     /// Cursor position column
254     private int _column;
255     /// Cursor position row
256     private int _row;
257     
258     @property string filename() {
259         return _filename;
260     }
261     @property void filename(string _fn) {
262         this._filename = _fn;
263     }
264     
265     @property int column() {
266         return _column;
267     }
268     @property void column(int col) {
269         _column = col;
270     }
271      
272     @property int row() {
273         return _row;
274     }
275     @property void row(int r) {
276         _row = r;
277     }
278 }