windowcapture
исходный код / Models/TitlePageData.cs

TitlePageData.cs

348 строк · 12,746 байт · модуль Models
  1using System;
  2using System.Collections.Generic;
  3using System.IO;
  4using System.Runtime.Serialization;
  5using System.Runtime.Serialization.Json;
  6using System.Text;
  7
  8namespace WindowCapture.Models
  9{
 10    /// <summary>
 11    /// Stores title page template data and field values
 12    /// Saved as JSON to %AppData%\WindowCapture\titlepage_data.json
 13    /// </summary>
 14    [DataContract]
 15    public class TitlePageData
 16    {
 17        private static string dataPath;
 18        private static TitlePageData instance;
 19
 20        static TitlePageData()
 21        {
 22            dataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "titlepage_data.json");
 23        }
 24
 25        [DataMember]
 26        public string TemplatePath { get; set; }
 27
 28        [DataMember]
 29        public string LastWorkNumber { get; set; }
 30
 31        [DataMember]
 32        public List<string> Disciplines { get; set; }
 33
 34        [DataMember]
 35        public List<string> Topics { get; set; }
 36
 37        [DataMember]
 38        public List<string> Students { get; set; }
 39
 40        [DataMember]
 41        public List<string> Groups { get; set; }
 42
 43        [DataMember]
 44        public List<string> Teachers { get; set; }
 45
 46        [DataMember]
 47        public LastSelectedIndices LastSelected { get; set; }
 48
 49        [DataMember]
 50        public string GeminiApiKey { get; set; }
 51
 52        [DataMember]
 53        public GeminiSettings Gemini { get; set; }
 54
 55        [DataMember]
 56        public AudioPlayerSettings AudioPlayer { get; set; }
 57
 58        public TitlePageData()
 59        {
 60            TemplatePath = "";
 61            LastWorkNumber = "1";
 62            Disciplines = new List<string>();
 63            Topics = new List<string>();
 64            Students = new List<string>();
 65            Groups = new List<string>();
 66            Teachers = new List<string>();
 67            LastSelected = new LastSelectedIndices();
 68            GeminiApiKey = "";
 69            Gemini = new GeminiSettings();
 70            AudioPlayer = new AudioPlayerSettings();
 71        }
 72
 73        /// <summary>
 74        /// Get singleton instance (loads from file if not loaded)
 75        /// </summary>
 76        public static TitlePageData Instance
 77        {
 78            get
 79            {
 80                if (instance == null)
 81                {
 82                    instance = Load();
 83                }
 84                return instance;
 85            }
 86        }
 87
 88        /// <summary>
 89        /// Load data from JSON file
 90        /// </summary>
 91        public static TitlePageData Load()
 92        {
 93            try
 94            {
 95                if (File.Exists(dataPath))
 96                {
 97                    var json = File.ReadAllText(dataPath, Encoding.UTF8);
 98                    var serializer = new DataContractJsonSerializer(typeof(TitlePageData));
 99                    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
100                    {
101                        var data = (TitlePageData)serializer.ReadObject(ms);
102                        if (data != null)
103                        {
104                            // Ensure lists are not null
105                            if (data.Disciplines == null) data.Disciplines = new List<string>();
106                            if (data.Topics == null) data.Topics = new List<string>();
107                            if (data.Students == null) data.Students = new List<string>();
108                            if (data.Groups == null) data.Groups = new List<string>();
109                            if (data.Teachers == null) data.Teachers = new List<string>();
110                            if (data.LastSelected == null) data.LastSelected = new LastSelectedIndices();
111                            if (data.Gemini == null) data.Gemini = new GeminiSettings();
112                            if (data.AudioPlayer == null) data.AudioPlayer = new AudioPlayerSettings();
113                            return data;
114                        }
115                    }
116                }
117            }
118            catch (Exception ex)
119            {
120                System.Diagnostics.Debug.WriteLine("Failed to load title page data: " + ex.Message);
121            }
122            return new TitlePageData();
123        }
124
125        /// <summary>
126        /// Save data to JSON file
127        /// </summary>
128        public void Save()
129        {
130            try
131            {
132                var dir = Path.GetDirectoryName(dataPath);
133                if (!Directory.Exists(dir))
134                    Directory.CreateDirectory(dir);
135
136                var serializer = new DataContractJsonSerializer(typeof(TitlePageData));
137                using (var ms = new MemoryStream())
138                {
139                    serializer.WriteObject(ms, this);
140                    var json = Encoding.UTF8.GetString(ms.ToArray());
141                    File.WriteAllText(dataPath, json, Encoding.UTF8);
142                }
143            }
144            catch (Exception ex)
145            {
146                System.Diagnostics.Debug.WriteLine("Failed to save title page data: " + ex.Message);
147            }
148        }
149
150        /// <summary>
151        /// Export settings to file (without API keys)
152        /// </summary>
153        public bool ExportSettings(string filePath)
154        {
155            try
156            {
157                // Create a copy without API keys
158                var exportData = new TitlePageData
159                {
160                    TemplatePath = this.TemplatePath,
161                    LastWorkNumber = this.LastWorkNumber,
162                    Disciplines = this.Disciplines != null ? new List<string>(this.Disciplines) : new List<string>(),
163                    Topics = this.Topics != null ? new List<string>(this.Topics) : new List<string>(),
164                    Students = this.Students != null ? new List<string>(this.Students) : new List<string>(),
165                    Groups = this.Groups != null ? new List<string>(this.Groups) : new List<string>(),
166                    Teachers = this.Teachers != null ? new List<string>(this.Teachers) : new List<string>(),
167                    LastSelected = this.LastSelected,
168                    GeminiApiKey = null, // Don't export API key
169                    Gemini = new GeminiSettings
170                    {
171                        Model = this.Gemini.Model,
172                        ThinkingBudget = this.Gemini.ThinkingBudget,
173                        MediaResolution = this.Gemini.MediaResolution,
174                        SystemInstruction = this.Gemini.SystemInstruction,
175                        ModelStatuses = null, // Don't export statuses
176                        ApiKeys = null, // Don't export API keys
177                        CurrentApiKeyIndex = 0,
178                        LastWorkingModel = null
179                    },
180                    AudioPlayer = this.AudioPlayer
181                };
182
183                var serializer = new DataContractJsonSerializer(typeof(TitlePageData));
184                using (var ms = new MemoryStream())
185                {
186                    serializer.WriteObject(ms, exportData);
187                    var json = Encoding.UTF8.GetString(ms.ToArray());
188                    File.WriteAllText(filePath, json, Encoding.UTF8);
189                }
190                return true;
191            }
192            catch (Exception ex)
193            {
194                System.Diagnostics.Debug.WriteLine("Failed to export settings: " + ex.Message);
195                return false;
196            }
197        }
198
199        /// <summary>
200        /// Import settings from file (preserves API keys)
201        /// </summary>
202        public bool ImportSettings(string filePath)
203        {
204            try
205            {
206                if (!File.Exists(filePath))
207                    return false;
208
209                var json = File.ReadAllText(filePath, Encoding.UTF8);
210                var serializer = new DataContractJsonSerializer(typeof(TitlePageData));
211                using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
212                {
213                    var importData = (TitlePageData)serializer.ReadObject(ms);
214                    if (importData == null)
215                        return false;
216
217                    // Import all except API keys
218                    this.TemplatePath = importData.TemplatePath;
219                    this.LastWorkNumber = importData.LastWorkNumber;
220
221                    // Merge lists (add new items, keep existing)
222                    MergeLists(this.Disciplines, importData.Disciplines);
223                    MergeLists(this.Topics, importData.Topics);
224                    MergeLists(this.Students, importData.Students);
225                    MergeLists(this.Groups, importData.Groups);
226                    MergeLists(this.Teachers, importData.Teachers);
227
228                    if (importData.LastSelected != null)
229                        this.LastSelected = importData.LastSelected;
230
231                    // Import Gemini settings (except API keys)
232                    if (importData.Gemini != null)
233                    {
234                        this.Gemini.Model = importData.Gemini.Model;
235                        this.Gemini.ThinkingBudget = importData.Gemini.ThinkingBudget;
236                        this.Gemini.MediaResolution = importData.Gemini.MediaResolution;
237                        this.Gemini.SystemInstruction = importData.Gemini.SystemInstruction;
238                        // Keep existing API keys and statuses
239                    }
240
241                    if (importData.AudioPlayer != null)
242                    {
243                        this.AudioPlayer.Width = importData.AudioPlayer.Width;
244                        this.AudioPlayer.Height = importData.AudioPlayer.Height;
245                    }
246
247                    Save();
248                    return true;
249                }
250            }
251            catch (Exception ex)
252            {
253                System.Diagnostics.Debug.WriteLine("Failed to import settings: " + ex.Message);
254                return false;
255            }
256        }
257
258        private void MergeLists(List<string> target, List<string> source)
259        {
260            if (source == null) return;
261            if (target == null) return;
262
263            foreach (var item in source)
264            {
265                if (!string.IsNullOrEmpty(item) && !target.Contains(item))
266                    target.Add(item);
267            }
268        }
269
270        /// <summary>
271        /// Add item to a list if not already present
272        /// </summary>
273        public bool AddToList(string listName, string value)
274        {
275            if (string.IsNullOrWhiteSpace(value)) return false;
276
277            List<string> list = GetList(listName);
278            if (list == null) return false;
279
280            if (!list.Contains(value))
281            {
282                list.Add(value);
283                Save();
284                return true;
285            }
286            return false;
287        }
288
289        /// <summary>
290        /// Get list by name
291        /// </summary>
292        public List<string> GetList(string listName)
293        {
294            switch (listName.ToLower())
295            {
296                case "discipline":
297                case "disciplines":
298                    return Disciplines;
299                case "topic":
300                case "topics":
301                    return Topics;
302                case "student":
303                case "students":
304                    return Students;
305                case "group":
306                case "groups":
307                    return Groups;
308                case "teacher":
309                case "teachers":
310                    return Teachers;
311                default:
312                    return null;
313            }
314        }
315
316        /// <summary>
317        /// Get last selected index for a field
318        /// </summary>
319        public int GetLastSelectedIndex(string fieldName)
320        {
321            switch (fieldName.ToLower())
322            {
323                case "discipline": return LastSelected.Discipline;
324                case "topic": return LastSelected.Topic;
325                case "student": return LastSelected.Student;
326                case "group": return LastSelected.Group;
327                case "teacher": return LastSelected.Teacher;
328                default: return 0;
329            }
330        }
331
332        /// <summary>
333        /// Set last selected index for a field
334        /// </summary>
335        public void SetLastSelectedIndex(string fieldName, int index)
336        {
337            switch (fieldName.ToLower())
338            {
339                case "discipline": LastSelected.Discipline = index; break;
340                case "topic": LastSelected.Topic = index; break;
341                case "student": LastSelected.Student = index; break;
342                case "group": LastSelected.Group = index; break;
343                case "teacher": LastSelected.Teacher = index; break;
344            }
345            Save();
346        }
347    }
348}