Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Data.Views/3.3/Path Views/TextFileView.cs @ 10166

Last change on this file since 10166 was 9961, checked in by mkommend, 11 years ago

#2081: Merged path data types into stable.

File size: 9.1 KB
RevLine 
[9671]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.IO;
25using System.Windows.Forms;
26using HeuristicLab.MainForm;
[9961]27using HeuristicLab.PluginInfrastructure;
[9671]28
[9680]29namespace HeuristicLab.Data.Views {
[9671]30  [View("TextFileView")]
[9714]31  [Content(typeof(TextFileValue), true)]
[9961]32  public sealed partial class TextFileView : FileValueView {
33    private bool fileContentChanged;
34    private bool FileContentChanged {
35      get { return fileContentChanged; }
[9671]36      set {
[9961]37        if (fileContentChanged != value) {
38          fileContentChanged = value;
39          OnFileContentChanged();
[9671]40        }
41      }
42    }
43
[9714]44    public new TextFileValue Content {
45      get { return (TextFileValue)base.Content; }
[9671]46      set { base.Content = value; }
47    }
48
49    public TextFileView() {
50      InitializeComponent();
[9961]51      fileContentChanged = false;
[9671]52    }
53
54    protected override void RegisterContentEvents() {
55      base.RegisterContentEvents();
[9961]56      Content.StringValue.ValueChanged += Content_FilePathChanged;
[9671]57    }
58    protected override void DeregisterContentEvents() {
[9961]59      Content.StringValue.ValueChanged -= Content_FilePathChanged;
[9671]60      fileSystemWatcher.EnableRaisingEvents = false;
61      base.DeregisterContentEvents();
62    }
63    protected override void SetEnabledStateOfControls() {
64      base.SetEnabledStateOfControls();
65      textBox.ReadOnly = Locked || ReadOnly || Content == null;
[9961]66      saveButton.Enabled = !Locked && !ReadOnly && Content != null && FileContentChanged;
[9671]67
[9697]68      if (Content != null && Content.Exists()) {
[9671]69        fileSystemWatcher.Filter = Path.GetFileName(Content.Value);
70        fileSystemWatcher.Path = Path.GetDirectoryName(Content.Value);
71      }
72      fileSystemWatcher.EnableRaisingEvents = Content != null && File.Exists(Content.Value) && Visible;
73    }
74
75    protected override void OnVisibleChanged(EventArgs e) {
76      //mkommend: necessary to update the textbox to detect intermediate file changes.
[9697]77      if (Visible && Content != null) UpdateTextBox();
[9671]78      base.OnVisibleChanged(e);
79    }
80
81    protected override void OnContentChanged() {
82      base.OnContentChanged();
[9961]83      FileContentChanged = false;
[9671]84      if (Content == null) {
85        textBox.Text = string.Empty;
[9705]86        //mkommend: other properties of the file system watcher cannot be cleared (e.g., path) as this leads to an ArgumentException
87        fileSystemWatcher.EnableRaisingEvents = false;
[9671]88        return;
89      }
90      saveFileDialog.Filter = Content.FileDialogFilter;
91      UpdateTextBox();
92    }
93
[9714]94    private void Content_FilePathChanged(object sender, EventArgs e) {
[9671]95      UpdateTextBox();
96      SetEnabledStateOfControls();
97    }
98
[9714]99    private void textBox_TextChanged(object sender, EventArgs e) {
[9961]100      FileContentChanged = fileText != textBox.Text;
[9671]101    }
102
[9961]103    private void OnFileContentChanged() {
[9671]104      SetEnabledStateOfControls();
[9961]105      textBox.ForeColor = FileContentChanged ? Color.Red : Color.Black;
[9671]106    }
107
[9714]108    private bool fileSystemWatcherChangedFired = false;
109    private void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e) {
[9671]110      //mkommend: cannot react on visible changed, because this event is not fired when the parent control gets visible set to false
111      if (!Visible) return;
112      //FileSystemWatcher may fire multiple events depending on how file changes are implemented in the modifying program
113      //see: http://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice
114      if (fileSystemWatcherChangedFired) return;
115      fileSystemWatcherChangedFired = true;
116
117      string newContent = ReadFile(Content.Value);
118      if (newContent == textBox.Text) {
119        fileSystemWatcherChangedFired = false;
120        return;
121      }
122
123      //File created
124      if (e.ChangeType == WatcherChangeTypes.Created) {
125        UpdateTextBox();
126      }
127
128      //File changed
129      else if (e.ChangeType == WatcherChangeTypes.Changed) {
130        string msg = string.Format("The content of the file \"{0}\" has changed.\nDo you want to reload the file?", Content.Value);
131        var result = MessageBox.Show(this, msg, "Reload the file?", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
132        if (result == DialogResult.Yes) {
133          UpdateTextBox();
134        } else {
135          fileText = newContent;
[9961]136          FileContentChanged = true;
[9671]137        }
138      }
139
140      //File deleted
141      else if (e.ChangeType == WatcherChangeTypes.Deleted) {
142        string msg = string.Format("The file \"{0}\" is not present anymore. Do you want to restore the file from the given content?", Content.Value);
143        var result = MessageBox.Show(this, msg, "Restore file?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
144        if (result == DialogResult.Yes) {
145          SaveFile();
146        }
147        UpdateTextBox();
148      }
149      fileSystemWatcherChangedFired = false;
150    }
151
[9714]152    private void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e) {
[9671]153      //mkommend: cannot react on visible changed, because this event is not fired when the parent control gets visible set to false
154      if (!Visible) return;
155      string msg = string.Format("The file \"{0}\" got renamed to \"{1}\". Do you want to update the file path?", e.OldName, e.Name);
156      var result = MessageBox.Show(this, msg, "Update file path?", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
157      if (result == DialogResult.Yes) {
158        Content.Value = e.FullPath;
159        fileSystemWatcher.Filter = e.Name;
160      }
161      UpdateTextBox();
162    }
163
[9714]164    private void SaveFile() {
[9671]165      //omit circular events by changing the file from HL
166      fileSystemWatcher.EnableRaisingEvents = false;
167      string path = Content.Value;
168      if (string.IsNullOrEmpty(path)) {
169        if (saveFileDialog.ShowDialog(this) != DialogResult.OK) return;
170        path = saveFileDialog.FileName;
171      }
172
173      WriteFile(path, textBox.Text);
174      Content.Value = path;
[9961]175      FileContentChanged = false;
[9671]176      fileSystemWatcher.EnableRaisingEvents = true;
177    }
178
[9714]179    private void saveButton_Click(object sender, EventArgs e) {
[9671]180      SaveFile();
181    }
182
[9714]183    private string fileText;
184    private void UpdateTextBox() {
[9671]185      if (string.IsNullOrEmpty(Content.Value)) {
186        textBox.Enabled = false;
187        textBox.Text = string.Format("No file path is specified.");
188        return;
189      }
190
[9714]191      fileText = ReadFile(Content.Value);
192      if (fileText == null) {
[9671]193        textBox.Enabled = false;
194        textBox.Text = string.Format("The specified file \"{0}\" cannot be found.", Content.Value);
195        return;
196      }
197
198      textBox.Enabled = true;
199      textBox.Text = fileText;
200    }
[9714]201    private void textBox_Validated(object sender, EventArgs e) {
[9961]202      if (!FileContentChanged) return;
[9671]203      string msg = string.Format("You have not saved the changes in the file \"{0}\" yet. Do you want to save the changes?", Content.Value);
204      var result = MessageBox.Show(this, msg, "Save changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
205      if (result == DialogResult.Yes) SaveFile();
206    }
207
208    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
209      if (keyData == (Keys.Control | Keys.S)) {
210        SaveFile();
211        return true;
212      }
213      return base.ProcessCmdKey(ref msg, keyData);
214    }
215
[9714]216    private static string ReadFile(string path) {
[9671]217      if (!File.Exists(path)) return null;
[9714]218      string fileContent = string.Empty;
[9961]219      try {
220        using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
221          using (StreamReader streamReader = new StreamReader(fileStream)) {
222            fileContent = streamReader.ReadToEnd();
223          }
[9671]224        }
225      }
[9961]226      catch (Exception e) {
227        ErrorHandling.ShowErrorDialog(e);
228      }
[9671]229      return fileContent;
230    }
231
[9714]232    private static void WriteFile(string path, string fileContent) {
[9961]233      try {
234        using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)) {
235          using (StreamWriter streamWriter = new StreamWriter(fileStream)) {
236            streamWriter.Write(fileContent);
237          }
[9671]238        }
239      }
[9961]240      catch (Exception e) {
241        ErrorHandling.ShowErrorDialog(e);
242      }
[9671]243    }
244  }
245}
Note: See TracBrowser for help on using the repository browser.