PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/MarkDownSharpEditor/Form1.cs

https://github.com/asanoesw/MarkDownSharpEditor
C# | 3551 lines | 2262 code | 325 blank | 964 comment | 525 complexity | c88aa535553c02d781cd86a947e9b9dd MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;
  10. using System.Collections;
  11. using System.Security.Cryptography;
  12. using System.Text.RegularExpressions;
  13. using System.Diagnostics;
  14. using System.Runtime.InteropServices;
  15. using System.Windows.Documents;
  16. using MarkDownSharpEditor.Properties;
  17. using mshtml;
  18. namespace MarkDownSharpEditor
  19. {
  20. public partial class Form1 : Form
  21. {
  22. //-----------------------------------
  23. // WebBrowserコンポーネントプレビューの更新音(クリック音)をOFFにする
  24. // Click sound off when webBrowser component preview
  25. const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
  26. const int SET_FEATURE_ON_PROCESS = 0x00000002;
  27. [DllImport("urlmon.dll")]
  28. [PreserveSig]
  29. [return: MarshalAs(UnmanagedType.Error)]
  30. static extern int CoInternetSetFeatureEnabled(int FeatureEntry, [MarshalAs(UnmanagedType.U4)] int dwFlags, bool fEnable);
  31. //-----------------------------------
  32. int undoCounter = 0; // Undo buffer counter
  33. List<string> UndoBuffer = new List<string>();
  34. private bool _fSearchStart = false; //検索を開始したか ( Start search flag )
  35. private int _richEditBoxInternalHeight; //richTextBox1の内部的な高さ ( internal height of richTextBox1 component )
  36. private int _WebBrowserInternalHeight; //webBrowser1の内部的な高さ(body)( internal height of webBrowser1 component )
  37. private Point _preFormPos; //フォームサイズ変更前の位置を一時保存 ( Temporary form position before resizing form )
  38. private Size _preFormSize; //フォームサイズ変更前のサイズを一時保存 ( Temporay form size before resizing form )
  39. private bool _fNoTitle = true; //無題のまま編集中かどうか ( no name of file flag )
  40. private string _MarkDownTextFilePath = ""; //編集中のMDファイルパス ( Editing .MD file path )
  41. private string _TemporaryHtmlFilePath = ""; //プレビュー用のテンポラリHTMLファイルパス ( Temporary HTML file path for preview )
  42. private string _SelectedCssFilePath = ""; //選択中のCSSファイルパス ( Applying CSS file path )
  43. private Encoding _EditingFileEncoding = Encoding.UTF8; //編集中MDファイルの文字エンコーディング ( Character encoding of MD file editing )
  44. private bool _fConstraintChange = true; //更新状態の抑制 ( Constraint changing flag )
  45. private List<MarkdownSyntaxKeyword> _MarkdownSyntaxKeywordAarray = new List<MarkdownSyntaxKeyword>(); // Array of MarkdownSyntaxKeyword Class
  46. private ArrayList _SyntaxArrayList = new ArrayList();
  47. //-----------------------------------
  48. // コンストラクタ ( Constructor )
  49. //-----------------------------------
  50. public Form1()
  51. {
  52. InitializeComponent();
  53. //IME Handler On/Off
  54. if (MarkDownSharpEditor.AppSettings.Instance.Lang == "ja")
  55. {
  56. richTextBox1.IMEWorkaroundEnabled = true;
  57. }
  58. else
  59. {
  60. richTextBox1.IMEWorkaroundEnabled = false;
  61. }
  62. this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter);
  63. this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragDrop);
  64. richTextBox1.AllowDrop = true;
  65. //設定を読み込む ( Read options )
  66. //Program.csで読み込むようにした ( Load in "Program.cs" )
  67. //MarkDownSharpEditor.AppSettings.Instance.ReadFromXMLFile();
  68. //WebBrowserClickSoundOFF();
  69. CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS, SET_FEATURE_ON_PROCESS, true);
  70. }
  71. //----------------------------------------------------------------------
  72. // フォームをロード ( Load main form )
  73. //----------------------------------------------------------------------
  74. private void Form1_Load(object sender, EventArgs e)
  75. {
  76. var obj = MarkDownSharpEditor.AppSettings.Instance;
  77. //-----------------------------------
  78. //フォーム位置・サイズ ( Form position & size )
  79. //-----------------------------------
  80. this.Location = obj.FormPos;
  81. this.Size = obj.FormSize;
  82. this.richTextBox1.Width = obj.richEditWidth;
  83. //ウィンドウ位置の調整(へんなところに行かないように戻す)
  84. // Ajust window position ( Set position into Desktop range )
  85. if (this.Left < 0 || this.Left > Screen.PrimaryScreen.Bounds.Width)
  86. {
  87. this.Left = 0;
  88. }
  89. if (this.Top < 0 || this.Top > Screen.PrimaryScreen.Bounds.Height)
  90. {
  91. this.Top = 0;
  92. }
  93. if (obj.FormState == 1)
  94. { //最小化 ( Minimize )
  95. this.WindowState = FormWindowState.Minimized;
  96. }
  97. else if (obj.FormState == 2)
  98. { //最大化 ( Maximize )
  99. this.WindowState = FormWindowState.Maximized;
  100. }
  101. //メインメニュー表示
  102. //View main menu
  103. this.menuViewToolBar.Checked = obj.fViewToolBar;
  104. this.toolStrip1.Visible = obj.fViewToolBar;
  105. this.menuViewStatusBar.Checked = obj.fViewStatusBar;
  106. this.statusStrip1.Visible = obj.fViewStatusBar;
  107. this.menuViewWidthEvenly.Checked = obj.fSplitBarWidthEvenly;
  108. //言語 ( Language )
  109. if (obj.Lang == "ja")
  110. {
  111. menuViewJapanese.Checked = true;
  112. menuViewEnglish.Checked = false;
  113. }
  114. else
  115. {
  116. menuViewJapanese.Checked = false;
  117. menuViewEnglish.Checked = true;
  118. }
  119. //ブラウザープレビューまでの間隔
  120. //Interval time of browser preview
  121. if (obj.AutoBrowserPreviewInterval > 0)
  122. {
  123. timer1.Interval = obj.AutoBrowserPreviewInterval;
  124. }
  125. //-----------------------------------
  126. //RichEditBox font
  127. FontConverter fc = new FontConverter();
  128. try { richTextBox1.Font = (Font)fc.ConvertFromString(obj.FontFormat); }
  129. catch { }
  130. //RichEditBox font color
  131. richTextBox1.ForeColor = Color.FromArgb(obj.richEditForeColor);
  132. //ステータスバーに表示
  133. //View in statusbar
  134. toolStripStatusLabelFontInfo.Text =
  135. richTextBox1.Font.Name + "," + richTextBox1.Font.Size.ToString() + "pt";
  136. //エディターのシンタックスハイライター設定の反映
  137. //Syntax highlighter of editor window is enabled
  138. _MarkdownSyntaxKeywordAarray = MarkdownSyntaxKeyword.CreateKeywordList();
  139. //-----------------------------------
  140. //選択中のエンコーディングを表示
  141. //View selected character encoding name
  142. foreach (EncodingInfo ei in Encoding.GetEncodings())
  143. {
  144. if (ei.GetEncoding().IsBrowserDisplay == true)
  145. {
  146. if (ei.CodePage == obj.CodePageNumber)
  147. {
  148. toolStripStatusLabelHtmlEncoding.Text = ei.DisplayName;
  149. break;
  150. }
  151. }
  152. }
  153. //-----------------------------------
  154. //指定されたCSSファイル名を表示
  155. //View selected CSS file name
  156. toolStripStatusLabelCssFileName.Text = Resources.toolTipCssFileName; //"CSSファイル指定なし"; ( No CSS file )
  157. if (obj.ArrayCssFileList.Count > 0)
  158. {
  159. string FilePath = (string)obj.ArrayCssFileList[0];
  160. if (File.Exists(FilePath) == true)
  161. {
  162. toolStripStatusLabelCssFileName.Text = Path.GetFileName(FilePath);
  163. _SelectedCssFilePath = FilePath;
  164. }
  165. }
  166. //-----------------------------------
  167. //出力するHTMLエンコーディング表示
  168. //View HTML charcter encoding name for output
  169. if (obj.HtmlEncodingOption == 0)
  170. {
  171. // 編集中(RichEditBox側)のエンコーディング
  172. // 基本的にはテキストファイルが読み込まれたときに表示する
  173. // View encoding name of editor window
  174. toolStripStatusLabelHtmlEncoding.Text = _EditingFileEncoding.EncodingName;
  175. }
  176. else
  177. {
  178. //エンコーディングを指定する(&C)
  179. //Select encoding
  180. Encoding enc = Encoding.GetEncoding(obj.CodePageNumber);
  181. toolStripStatusLabelHtmlEncoding.Text = enc.EncodingName;
  182. }
  183. //-----------------------------------
  184. //検索フォーム・オプション
  185. //Search form options
  186. chkOptionCase.Checked = obj.fSearchOptionIgnoreCase ? false : true;
  187. }
  188. //----------------------------------------------------------------------
  189. // フォームを表示
  190. // View Main form
  191. //----------------------------------------------------------------------
  192. private void Form1_Shown(object sender, EventArgs e)
  193. {
  194. string DirPath = MarkDownSharpEditor.AppSettings.GetAppDataLocalPath();
  195. ArrayList FileArray = new ArrayList();
  196. //TODO: 「新しいウィンドウで開く」="/new"などの引数も含まれるので、
  197. // その辺りの処理も将来的に入れる。
  198. //コマンドラインでファイルが投げ込まれてきている
  199. //Launch with arguments
  200. string[] cmds = System.Environment.GetCommandLineArgs();
  201. for (int i = 1; i < cmds.Count(); i++)
  202. {
  203. if (File.Exists(cmds[i]) == true)
  204. {
  205. FileArray.Add(cmds[i]);
  206. }
  207. }
  208. try
  209. {
  210. if (FileArray.Count > 1)
  211. { //"問い合わせ"
  212. //"複数のファイルが読み込まれました。\n現在の設定内容でHTMLファイルへの一括変換を行いますか?
  213. //「いいえ」を選択するとそのまますべてのファイル開きます。"
  214. //"Question"
  215. //"More than one were read.\nDo you wish to convert all files to HTML files on this options?\n
  216. // if you select 'No', all files will be opend without converting."
  217. DialogResult ret = MessageBox.Show(Resources.MsgConvertAllFilesToHTML,
  218. Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
  219. if (ret == DialogResult.Yes)
  220. { //一括でHTMLファイル出力
  221. //Output HTML files in batch process
  222. BatchOutputToHtmlFiles((String[])FileArray.ToArray(typeof(string)));
  223. return;
  224. }
  225. else if (ret == DialogResult.Cancel)
  226. { //キャンセル
  227. //Cancel
  228. return;
  229. }
  230. else
  231. { //「いいえ」
  232. // "NO" button
  233. bool fOpen = false;
  234. foreach (string FilePath in FileArray)
  235. { //最初のファイルだけ、このウィンドウだけ開く
  236. //First file open in this window
  237. if (fOpen == false)
  238. {
  239. richTextBox1.Modified = false;
  240. OpenFile(FilePath);
  241. fOpen = true;
  242. }
  243. else
  244. { //他の複数ファイルは順次新しいウィンドウで開く
  245. //Other files open in new windows
  246. System.Diagnostics.Process.Start(
  247. Application.ExecutablePath, string.Format("{0}", FilePath));
  248. }
  249. }
  250. }
  251. }
  252. else if (FileArray.Count == 1)
  253. {
  254. richTextBox1.Modified = false;
  255. OpenFile((string)FileArray[0]);
  256. }
  257. else
  258. { //前に編集していたファイルがあればそれを開く
  259. //Open it if there is editing file before
  260. if (MarkDownSharpEditor.AppSettings.Instance.fOpenEditFileBefore == true)
  261. {
  262. if (MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Count > 0)
  263. {
  264. AppHistory EditedFilePath = new AppHistory();
  265. EditedFilePath = (AppHistory)MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles[0];
  266. if (File.Exists(EditedFilePath.md) == true)
  267. {
  268. _TemporaryHtmlFilePath = "";
  269. richTextBox1.Modified = false;
  270. OpenFile(EditedFilePath.md);
  271. return;
  272. }
  273. }
  274. }
  275. if (_MarkDownTextFilePath == "")
  276. { //無ければ「無題」ファイル
  277. // "No title" if no file exists
  278. richTextBox1.Modified = false;
  279. OpenFile("");
  280. }
  281. }
  282. }
  283. finally
  284. {
  285. _fConstraintChange = false;
  286. //SyntaxHighlighter
  287. if (backgroundWorker2.IsBusy == false)
  288. {
  289. //backgroundWorker2.WorkerReportsProgress = true;
  290. backgroundWorker2.RunWorkerAsync(richTextBox1.Text);
  291. }
  292. richTextBox1.Modified = false;
  293. //フォームタイトル更新 / Refresh form caption
  294. FormTextChange();
  295. }
  296. }
  297. //----------------------------------------------------------------------
  298. // フォームタイトルの表示(更新)
  299. // Refresh form caption
  300. //----------------------------------------------------------------------
  301. private void FormTextChange()
  302. {
  303. string FileName;
  304. if (_fNoTitle == true)
  305. {
  306. FileName = Resources.NoFileName; //"(無題)" "(No title)"
  307. }
  308. else
  309. {
  310. //FileName = System.IO.Path.GetFileName(_MarkDownTextFilePath);
  311. FileName = _MarkDownTextFilePath;
  312. }
  313. if (richTextBox1.Modified == true)
  314. {
  315. FileName = FileName + Resources.FlagChanged; //"(更新)"; "(Changed)"
  316. }
  317. this.Text = FileName + " - " + Application.ProductName;
  318. }
  319. //----------------------------------------------------------------------
  320. // 見出しリストメニューの表示
  321. //----------------------------------------------------------------------
  322. private void mnuShowHeaderListMenu_Click(object sender, EventArgs e)
  323. {
  324. ShowHeaderListContextMenu();
  325. }
  326. //----------------------------------------------------------------------
  327. // 見出しリストメニューの表示
  328. //----------------------------------------------------------------------
  329. void ShowHeaderListContextMenu()
  330. {
  331. int retCode;
  332. //Markdown
  333. object[][] mkObject = {
  334. new object[2] { 1, @"^#[^#]*?$" }, //見出し1 (headline1)
  335. new object[2] { 1, @"^.*\n=+$" }, //見出し1 (headline1)
  336. new object[2] { 2, @"^##[^#]*?$" }, //見出し2 (headline2)
  337. new object[2] { 2, @"^.+\n-+$" }, //見出し2 (headline2)
  338. new object[2] { 3, @"^###[^#]*?$" }, //見出し3 (headline3)
  339. new object[2] { 4, @"^####[^#]*?$" }, //見出し4 (headline4)
  340. new object[2] { 5, @"^#####[^#]*?$" }, //見出し5 (headline5)
  341. new object[2] { 6, @"^######[^#]*?$"} //見出し6 (headline6)
  342. };
  343. //コンテキストメニュー項目を初期化(クリア)
  344. //Clear context menus
  345. contextMenu2.Items.Clear();
  346. bool fModify = richTextBox1.Modified;
  347. _fConstraintChange = true;
  348. //現在のカーソル位置
  349. //Current cursor position
  350. int selectStart = this.richTextBox1.SelectionStart;
  351. int selectEnd = richTextBox1.SelectionLength;
  352. Point CurrentOffset = richTextBox1.AutoScrollOffset;
  353. //現在のスクロール位置
  354. //Current scroll position
  355. int CurrentScrollPos = richTextBox1.VerticalPosition;
  356. //描画停止
  357. //Stop to update
  358. richTextBox1.BeginUpdate();
  359. for (int i = 0; i < mkObject.Length; i++)
  360. {
  361. Regex r = new Regex((string)mkObject[i][1], RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
  362. MatchCollection col = r.Matches(richTextBox1.Text, 0);
  363. if (col.Count > 0)
  364. {
  365. foreach (Match m in col)
  366. {
  367. int IndexNum = m.Groups[0].Index;
  368. string title = new String(' ', (int)mkObject[i][0]) + richTextBox1.Text.Substring(m.Groups[0].Index, m.Groups[0].Length);
  369. if ((retCode = title.LastIndexOf("\n")) > -1)
  370. {
  371. title = title.Substring(0, title.LastIndexOf("\n"));
  372. }
  373. //コンテキストメニューに登録
  374. //Regist item to context menus
  375. bool fAdd = false;
  376. ToolStripMenuItem item = new ToolStripMenuItem();
  377. for (int c = 0; c < contextMenu2.Items.Count; c++)
  378. {
  379. //登録されている項目よりも前の項目のときは挿入する
  380. //Insert item to registed items
  381. if (IndexNum < (int)contextMenu2.Items[c].Tag)
  382. {
  383. item.Text = title;
  384. item.Tag = IndexNum;
  385. contextMenu2.Items.Insert(c, item);
  386. fAdd = true;
  387. break;
  388. }
  389. }
  390. if (fAdd == false)
  391. {
  392. item.Text = title;
  393. item.Tag = IndexNum;
  394. contextMenu2.Items.Add(item);
  395. }
  396. }
  397. }
  398. }
  399. //カーソル位置を戻す
  400. //Restore cursor position
  401. richTextBox1.Select(selectStart, selectEnd);
  402. richTextBox1.AutoScrollOffset = CurrentOffset;
  403. //描画再開
  404. //Resume to update
  405. richTextBox1.EndUpdate();
  406. richTextBox1.Modified = fModify;
  407. _fConstraintChange = false;
  408. //richTextBox1のキャレット位置
  409. //Curret position in richTextBox1
  410. Point pt = richTextBox1.GetPositionFromCharIndex(richTextBox1.SelectionStart);
  411. //スクリーン座標に変換
  412. //Convert the position to screen position
  413. pt = richTextBox1.PointToScreen(pt);
  414. //コンテキストメニューを表示
  415. //View context menus
  416. contextMenu2.Show(pt);
  417. }
  418. //----------------------------------------------------------------------
  419. // 見出しメニュークリックイベント
  420. // Click event in context menus
  421. //----------------------------------------------------------------------
  422. private void contextMenu2_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
  423. {
  424. if ((int)e.ClickedItem.Tag > 0)
  425. {
  426. richTextBox1.SelectionStart = (int)e.ClickedItem.Tag;
  427. richTextBox1.ScrollToCaret();
  428. }
  429. }
  430. //----------------------------------------------------------------------
  431. // HACK: RichTextBox内容変更 [ シンタックス・ハイライター表示)]
  432. // Apply richTextBox1 to syntax highlight with changing
  433. //----------------------------------------------------------------------
  434. private void richTextBox1_TextChanged(object sender, EventArgs e)
  435. {
  436. if (_fConstraintChange == true)
  437. {
  438. return;
  439. }
  440. if (backgroundWorker2.IsBusy == false)
  441. {
  442. //バックグラウンドワーカーへパースを投げる / SyntaxHightlighter on BackgroundWorker
  443. backgroundWorker2.RunWorkerAsync(richTextBox1.Text);
  444. }
  445. //-----------------------------------
  446. //Formキャプション変更 / Change form caption
  447. FormTextChange();
  448. //-----------------------------------
  449. //ブラウザプレビュー制御 / Preview webBrowser component
  450. if (MarkDownSharpEditor.AppSettings.Instance.fAutoBrowserPreview == true)
  451. {
  452. timer1.Enabled = true;
  453. }
  454. }
  455. //----------------------------------------------------------------------
  456. // RichTextBox Key Press
  457. //----------------------------------------------------------------------
  458. private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
  459. {
  460. //-----------------------------------
  461. // Add undo buffer
  462. //-----------------------------------
  463. //現在のUndoCounterから先を削除
  464. //Remove first item of undo counter
  465. if (undoCounter < UndoBuffer.Count)
  466. {
  467. UndoBuffer.RemoveRange(undoCounter, UndoBuffer.Count - undoCounter);
  468. }
  469. UndoBuffer.Add(richTextBox1.Rtf);
  470. undoCounter = UndoBuffer.Count;
  471. //EnterやEscapeキーでビープ音が鳴らないようにする
  472. //Stop to beep in Enter & Escape key
  473. if (e.KeyChar == (char)Keys.Enter || e.KeyChar == (char)Keys.Escape)
  474. {
  475. e.Handled = true;
  476. }
  477. timer2.Enabled = true;
  478. }
  479. //----------------------------------------------------------------------
  480. // RichTextBox VScroll event
  481. //----------------------------------------------------------------------
  482. private void richTextBox1_VScroll(object sender, EventArgs e)
  483. {
  484. if (_fConstraintChange == false)
  485. {
  486. WebBrowserMoveCursor();
  487. }
  488. }
  489. //----------------------------------------------------------------------
  490. // RichTextBox Enter event
  491. //----------------------------------------------------------------------
  492. private void richTextBox1_Enter(object sender, EventArgs e)
  493. {
  494. //ブラウザプレビュー制御 / Preview webBrowser component
  495. if (MarkDownSharpEditor.AppSettings.Instance.fAutoBrowserPreview == true)
  496. {
  497. timer1.Enabled = true;
  498. }
  499. }
  500. //----------------------------------------------------------------------
  501. // RichTextBox Mouse click
  502. //----------------------------------------------------------------------
  503. private void richTextBox1_MouseClick(object sender, MouseEventArgs e)
  504. {
  505. //timer1.Enabled = true;
  506. }
  507. //----------------------------------------------------------------------
  508. // Form Closing event
  509. //----------------------------------------------------------------------
  510. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  511. {
  512. if (richTextBox1.Modified == true)
  513. {
  514. //"問い合わせ"
  515. //"編集中のファイルがあります。保存してから終了しますか?"
  516. //"Question"
  517. //"This file being edited. Do you wish to save before exiting?"
  518. DialogResult ret = MessageBox.Show(Resources.MsgSaveFileToEnd,
  519. Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
  520. if (ret == DialogResult.Yes)
  521. {
  522. if (SaveToEditingFile() == true)
  523. {
  524. _fNoTitle = false;
  525. }
  526. else
  527. {
  528. //キャンセルで抜けてきた
  529. //user cancel
  530. e.Cancel = true;
  531. return;
  532. }
  533. }
  534. else if (ret == DialogResult.Cancel)
  535. {
  536. e.Cancel = true;
  537. return;
  538. }
  539. }
  540. _fConstraintChange = true;
  541. //無題ファイルのまま編集しているのなら削除
  542. //Delete file if the file is no title
  543. if (_fNoTitle == true)
  544. {
  545. if (File.Exists(_MarkDownTextFilePath) == true)
  546. {
  547. try
  548. {
  549. File.Delete(_MarkDownTextFilePath);
  550. }
  551. catch
  552. {
  553. }
  554. }
  555. }
  556. //データバージョン
  557. //Data version
  558. System.Reflection.Assembly asmbly = System.Reflection.Assembly.GetExecutingAssembly();
  559. System.Version ver = asmbly.GetName().Version;
  560. MarkDownSharpEditor.AppSettings.Instance.Version = ver.Major * 1000 + ver.Minor * 100 + ver.Build * 10 + ver.Revision;
  561. //フォーム位置・サイズ ( Form position & size )
  562. if (this.WindowState == FormWindowState.Minimized)
  563. { //最小化 ( Minimize )
  564. MarkDownSharpEditor.AppSettings.Instance.FormState = 1;
  565. //一時記憶していた位置・サイズを保存 ( Save temporary position & size value )
  566. MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(_preFormPos.X, _preFormPos.Y);
  567. MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(_preFormSize.Width, _preFormSize.Height);
  568. }
  569. else if (this.WindowState == FormWindowState.Maximized)
  570. { //最大化 ( Maximize )
  571. MarkDownSharpEditor.AppSettings.Instance.FormState = 2;
  572. //一時記憶していた位置・サイズを保存 ( Save temporary position & size value )
  573. MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(_preFormPos.X, _preFormPos.Y);
  574. MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(_preFormSize.Width, _preFormSize.Height);
  575. }
  576. else
  577. { //通常 ( Normal window )
  578. MarkDownSharpEditor.AppSettings.Instance.FormState = 0;
  579. MarkDownSharpEditor.AppSettings.Instance.FormPos = new Point(this.Left, this.Top);
  580. MarkDownSharpEditor.AppSettings.Instance.FormSize = new Size(this.Width, this.Height);
  581. }
  582. MarkDownSharpEditor.AppSettings.Instance.richEditWidth = this.richTextBox1.Width;
  583. FontConverter fc = new FontConverter();
  584. MarkDownSharpEditor.AppSettings.Instance.FontFormat = fc.ConvertToString(richTextBox1.Font);
  585. MarkDownSharpEditor.AppSettings.Instance.richEditForeColor = richTextBox1.ForeColor.ToArgb();
  586. //表示オプションなど
  587. //Save view options etc
  588. MarkDownSharpEditor.AppSettings.Instance.fViewToolBar = this.menuViewToolBar.Checked;
  589. MarkDownSharpEditor.AppSettings.Instance.fViewStatusBar = this.menuViewStatusBar.Checked;
  590. MarkDownSharpEditor.AppSettings.Instance.fSplitBarWidthEvenly = this.menuViewWidthEvenly.Checked;
  591. //検索オプション
  592. //Save search options
  593. MarkDownSharpEditor.AppSettings.Instance.fSearchOptionIgnoreCase = chkOptionCase.Checked ? false : true;
  594. if (File.Exists(_MarkDownTextFilePath) == true)
  595. {
  596. //編集中のファイルパス
  597. //Save editing file path
  598. foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
  599. {
  600. if (data.md == _MarkDownTextFilePath)
  601. { //いったん削除して ( delete once ... )
  602. MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Remove(data);
  603. break;
  604. }
  605. }
  606. AppHistory HistroyData = new AppHistory();
  607. HistroyData.md = _MarkDownTextFilePath;
  608. HistroyData.css = _SelectedCssFilePath;
  609. MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Insert(0, HistroyData); //先頭に挿入 ( Insert at the top )
  610. }
  611. //設定の保存
  612. //Save settings
  613. MarkDownSharpEditor.AppSettings.Instance.SaveToXMLFile();
  614. //MarkDownSharpEditor.AppSettings.Instance.SaveToJsonFile();
  615. timer1.Enabled = false;
  616. //webBrowser1.Navigate("about:blank");
  617. //クリック音対策
  618. //Constraint click sounds
  619. if (webBrowser1.Document != null)
  620. {
  621. webBrowser1.Document.OpenNew(true);
  622. webBrowser1.Document.Write("");
  623. }
  624. }
  625. //-----------------------------------
  626. // Form closed event
  627. //-----------------------------------
  628. private void Form1_FormClosed(object sender, FormClosedEventArgs e)
  629. {
  630. //テンポラリファイルの削除
  631. //Delete temporary files
  632. Delete_TemporaryHtmlFilePath();
  633. }
  634. //-----------------------------------
  635. // Form resize begin event
  636. //-----------------------------------
  637. private void Form1_ResizeBegin(object sender, EventArgs e)
  638. {
  639. //リサイズ前の位置・サイズを一時記憶
  640. _preFormPos.X = this.Left;
  641. _preFormPos.Y = this.Top;
  642. _preFormSize.Width = this.Width;
  643. _preFormSize.Height = this.Height;
  644. }
  645. //-----------------------------------
  646. // Form resize end event
  647. //-----------------------------------
  648. private void Form1_ResizeEnd(object sender, EventArgs e)
  649. {
  650. //ソースウィンドウとビューウィンドウを均等にするか
  651. //Equalize width of source window and view window
  652. if (menuViewWidthEvenly.Checked == true)
  653. {
  654. this.richTextBox1.Width =
  655. (splitContainer1.Width - splitContainer1.SplitterWidth) / 2;
  656. }
  657. }
  658. //-----------------------------------
  659. // richTextBox1 DragEnter event
  660. //-----------------------------------
  661. private void richTextBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
  662. {
  663. if (e.Data.GetDataPresent(DataFormats.FileDrop) == true)
  664. {
  665. e.Effect = DragDropEffects.Copy;
  666. }
  667. else
  668. {
  669. e.Effect = DragDropEffects.None;
  670. }
  671. }
  672. //-----------------------------------
  673. // richTextBox1 Drag and Drop event
  674. //-----------------------------------
  675. private void richTextBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
  676. {
  677. string[] FileArray = (string[])e.Data.GetData(DataFormats.FileDrop, false);
  678. if (FileArray.Length > 1)
  679. {
  680. if (FileArray.Length > 0)
  681. {
  682. //"問い合わせ"
  683. //"複数のファイルが読み込まれました。\n現在の設定内容でHTMLファイルへの一括変換を行いますか?
  684. //「いいえ」を選択するとそのまますべてのファイル開きます。"
  685. //"Question"
  686. //"More than one were read.\nDo you wish to convert all files to HTML files on this options?\n
  687. // if you select 'No', all files will be opend without converting."
  688. DialogResult ret = MessageBox.Show("MsgConvertAllFilesToHTML",
  689. Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
  690. if (ret == DialogResult.Yes)
  691. {
  692. //一括でHTMLファイル出力
  693. //Output HTML files in batch process
  694. BatchOutputToHtmlFiles(FileArray);
  695. return;
  696. }
  697. else if (ret == DialogResult.Cancel)
  698. {
  699. //キャンセル
  700. //Cancel
  701. return;
  702. }
  703. else
  704. { //「いいえ」
  705. // "No" button
  706. bool fOpen = false;
  707. foreach (string FilePath in FileArray)
  708. {
  709. //最初のファイルだけ、このウィンドウだけ開く
  710. //First file open in this window
  711. if (fOpen == false)
  712. {
  713. OpenFile(FilePath);
  714. fOpen = true;
  715. }
  716. else
  717. {
  718. //他の複数ファイルは順次新しいウィンドウで開く
  719. //Other files open in new windows
  720. System.Diagnostics.Process.Start(
  721. Application.ExecutablePath, string.Format("{0}", FilePath));
  722. }
  723. }
  724. }
  725. }
  726. else
  727. {
  728. //前に編集していたファイルがあればそれを開く
  729. //Open it if there is editing file before
  730. if (MarkDownSharpEditor.AppSettings.Instance.fOpenEditFileBefore == true)
  731. {
  732. if (MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Count > 0)
  733. {
  734. AppHistory EditedFilePath = new AppHistory();
  735. EditedFilePath = (AppHistory)MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles[0];
  736. if (File.Exists(EditedFilePath.md) == true)
  737. {
  738. OpenFile(EditedFilePath.md);
  739. }
  740. }
  741. }
  742. }
  743. _fConstraintChange = false;
  744. //フォームタイトル更新
  745. //Refresh form caption
  746. FormTextChange();
  747. ArrayList ArrayFileList = new ArrayList();
  748. foreach (string FilePath in FileArray)
  749. {
  750. ArrayFileList.Add(FilePath);
  751. }
  752. BatchOutputToHtmlFiles((String[])ArrayFileList.ToArray(typeof(string)));
  753. }
  754. else if (FileArray.Count() == 1)
  755. {
  756. //ファイルが一個の場合は編集中のウィンドウで開く
  757. //Open it in this window if file is one
  758. OpenFile(FileArray[0]);
  759. }
  760. }
  761. //----------------------------------------------------------------------
  762. // OpenFile [ .mdファイルを開く ]
  763. //----------------------------------------------------------------------
  764. private bool OpenFile(string FilePath, bool fOpenDialog = false)
  765. {
  766. //引数 FilePath = "" の場合は「無題」編集で開始する
  767. // Argument "FilePath" = "" => Start editing in 'no title'
  768. if (FilePath == "")
  769. {
  770. _fNoTitle = true; // No title flag
  771. }
  772. else
  773. {
  774. _fNoTitle = false;
  775. }
  776. //-----------------------------------
  777. //編集中のファイルがある
  778. if (richTextBox1.Modified == true)
  779. {
  780. //"問い合わせ"
  781. //"編集中のファイルがあります。保存してから終了しますか?"
  782. //"Question"
  783. //"This file being edited. Do you wish to save before exiting?"
  784. DialogResult ret = MessageBox.Show(Resources.MsgSaveFileToEnd,
  785. Resources.DialogTitleQuestion, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
  786. if (ret == DialogResult.Yes)
  787. {
  788. if (SaveToEditingFile() == false)
  789. {
  790. //キャンセルで抜けてきた
  791. //Cancel
  792. return (false);
  793. }
  794. }
  795. else if (ret == DialogResult.Cancel)
  796. {
  797. return (false);
  798. }
  799. //編集履歴に残す
  800. //Save file path to editing history
  801. foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
  802. {
  803. if (data.md == _MarkDownTextFilePath)
  804. { //いったん削除して ( delete once ... )
  805. MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Remove(data);
  806. break;
  807. }
  808. }
  809. AppHistory HistroyData = new AppHistory();
  810. HistroyData.md = _MarkDownTextFilePath;
  811. HistroyData.css = _SelectedCssFilePath;
  812. MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles.Insert(0, HistroyData); //先頭に挿入 ( Insert at the top )
  813. }
  814. //-----------------------------------
  815. //オープンダイアログ表示
  816. //View open file dialog
  817. if (fOpenDialog == true)
  818. {
  819. if (File.Exists(_MarkDownTextFilePath) == true)
  820. { //編集中のファイルがあればそのディレクトリを初期フォルダーに
  821. //Set parent directory of editing file to initial folder
  822. openFileDialog1.InitialDirectory = Path.GetDirectoryName(_MarkDownTextFilePath);
  823. //テンポラリファイルがあればここで削除
  824. //Delete it if temporary file exists
  825. Delete_TemporaryHtmlFilePath();
  826. }
  827. openFileDialog1.FileName = "";
  828. if (openFileDialog1.ShowDialog() == DialogResult.OK)
  829. {
  830. FilePath = openFileDialog1.FileName;
  831. _fNoTitle = false;
  832. }
  833. else
  834. {
  835. return (false);
  836. }
  837. }
  838. //編集中のファイルパスとする
  839. //Set this file to 'editing file' path
  840. _MarkDownTextFilePath = FilePath;
  841. //-----------------------------------
  842. //文字コードを調査するためにテキストファイルを開く
  843. //Detect encoding
  844. if (_fNoTitle == false)
  845. {
  846. byte[] bs;
  847. using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
  848. {
  849. bs = new byte[fs.Length];
  850. fs.Read(bs, 0, bs.Length);
  851. }
  852. //文字コードを取得する
  853. //Get charcter encoding
  854. _EditingFileEncoding = GetCode(bs);
  855. }
  856. else
  857. {
  858. //「無題」はデフォルトのエンコーディング
  859. // Set this file to default encoding in 'No title'
  860. _EditingFileEncoding = Encoding.UTF8;
  861. }
  862. //ステータスバーに表示
  863. //View in statusbar
  864. toolStripStatusLabelTextEncoding.Text = _EditingFileEncoding.EncodingName;
  865. //編集中のエンコーディングを使用する(&D)か
  866. //Use encoding of editing file
  867. if (MarkDownSharpEditor.AppSettings.Instance.HtmlEncodingOption == 0)
  868. {
  869. toolStripStatusLabelHtmlEncoding.Text = _EditingFileEncoding.EncodingName;
  870. }
  871. //-----------------------------------
  872. //ペアとなるCSSファイルがあるか探索してあれば適用する
  873. //Apply that the pair CSS file to this file exists
  874. foreach (AppHistory data in MarkDownSharpEditor.AppSettings.Instance.ArrayHistoryEditedFiles)
  875. {
  876. if (data.md == _MarkDownTextFilePath)
  877. {
  878. if (File.Exists(data.css) == true)
  879. {
  880. _SelectedCssFilePath = data.css;
  881. break;
  882. }
  883. }
  884. }
  885. //選択中のCSSファイル名をステータスバーに表示
  886. //View selected CSS file name to stausbar
  887. if (File.Exists(_SelectedCssFilePath) == true)
  888. {
  889. toolStripStatusLabelCssFileName.Text = Path.GetFileName(_SelectedCssFilePath);
  890. }
  891. else
  892. {
  893. toolStripStatusLabelCssFileName.Text = Resources.toolTipCssFileName; //"CSSファイル指定なし"; ( not selected CSS file)
  894. }
  895. _fConstraintChange = true;
  896. richTextBox1.Clear();
  897. //RichEditBoxの「フォント」設定
  898. // richTextBox1 font name setting
  899. var obj = MarkDownSharpEditor.AppSettings.Instance;
  900. FontConverter fc = new FontConverter();
  901. try { richTextBox1.Font = (Font)fc.ConvertFromString(obj.FontFormat); }
  902. catch { }
  903. //RichEditBoxの「フォントカラー」設定
  904. // richTextBox1 font color setting
  905. richTextBox1.ForeColor = Color.FromArgb(obj.richEditForeColor);
  906. //View them in statusbar
  907. toolStripStatusLabelFontInfo.Text = richTextBox1.Font.Name + "," + richTextBox1.Font.Size.ToString() + "pt";
  908. //-----------------------------------
  909. //テキストファイルの読み込み
  910. //Read text file
  911. if (File.Exists(FilePath) == true)
  912. {
  913. richTextBox1.Text = File.ReadAllText(FilePath, _EditingFileEncoding);
  914. }
  915. richTextBox1.BeginUpdate();
  916. richTextBox1.SelectionStart = richTextBox1.Text.Length;
  917. richTextBox1.ScrollToCaret();
  918. //richTextBox1の全高さを求める
  919. //Get height of richTextBox1 ( for webBrowser sync )
  920. _richEditBoxInternalHeight = richTextBox1.VerticalPosition;
  921. //カーソル位置を戻す
  922. //Restore cursor position
  923. richTextBox1.SelectionStart = 0;
  924. richTextBox1.EndUpdate();
  925. //変更フラグOFF
  926. richTextBox1.Modified = false;
  927. //Undoバッファに追加
  928. //Add all text to undo buffer
  929. UndoBuffer.Clear();
  930. UndoBuffer.Add(richTextBox1.Rtf);
  931. undoCounter = UndoBuffer.Count;
  932. //プレビュー更新
  933. PreviewToBrowser();
  934. _fConstraintChange = false;
  935. FormTextChange();
  936. return (true);
  937. }
  938. //----------------------------------------------------------------------
  939. // 表示するHTMLのテンポラリファイルパスを取得する
  940. // Get temporary HTML file path
  941. //----------------------------------------------------------------------
  942. private string Get_TemporaryHtmlFilePath(string FilePath)
  943. {
  944. string DirPath = Path.GetDirectoryName(FilePath);
  945. string FileName = Path.GetFileNameWithoutExtension(FilePath);
  946. MD5 md5Hash = MD5.Create();
  947. byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(FileName));
  948. StringBuilder sBuilder = new StringBuilder();
  949. for (int i = 0; i < data.Length; i++)
  950. {
  951. sBuilder.Append(data[i].ToString("x2"));
  952. }
  953. return (Path.Combine(DirPath, FileName + "_" + sBuilder.ToString() + ".html"));
  954. }
  955. //----------------------------------------------------------------------
  956. // 表示しているHTMLのテンポラリファイルを削除する
  957. // Delete temporary HTML file
  958. //----------------------------------------------------------------------
  959. private void Delete_TemporaryHtmlFilePath()
  960. {
  961. string TempHtmlFilePath;
  962. if (_MarkDownTextFilePath == "")
  963. {
  964. return;
  965. }
  966. TempHtmlFilePath = Get_TemporaryHtmlFilePath(_MarkDownTextFilePath);
  967. //見つかったときだけ削除
  968. //Delete it if the file exists
  969. if (File.Exists(TempHtmlFilePath) == true)
  970. {
  971. try
  972. {
  973. File.Delete(TempHtmlFilePath);
  974. }
  975. catch
  976. {
  977. //"エラー"
  978. //"テンポラリファイルの削除に失敗しました。編集中の場所に残った可能性があります。
  979. //"このファイルは手動で削除していただいても問題ありません。
  980. //"Error"
  981. //"Error during deleting temporary file!\na temporary file may be left in the folder the file is edited.\n"
  982. // This file is not a problem even if you delete it manually.
  983. MessageBox.Show(Resources.MsgErrorDeleteTemporaryFile + TempHtmlFilePath,
  984. Resources.DialogTitleError, MessageBoxButtons.OK, MessageBoxIcon.Error);
  985. }
  986. }
  987. }
  988. //----------------------------------------------------------------------
  989. // ブラウザープレビューの間隔を調整
  990. // Ajust browser preview interval
  991. //----------------------------------------------------------------------
  992. private void timer1_Tick(object sender, EventArgs e)
  993. {
  994. PreviewToBrowser();
  995. timer1.Enabled = false;
  996. }
  997. private void timer2_Tick(object sender, EventArgs e)
  998. {
  999. timer2.Enabled = false;
  1000. }
  1001. //----------------------------------------------------------------------
  1002. // HACK: PreviewToBrowser [ ブラウザプレビュー ]
  1003. //----------------------------------------------------------------------
  1004. private void PreviewToBrowser()
  1005. {
  1006. //更新抑制中のときはプレビューしない
  1007. //Do not preview in constraint to change
  1008. if (_fConstraintChange == true)
  1009. {
  1010. return;
  1011. }
  1012. if (backgroundWorker1.IsBusy == true)
  1013. {
  1014. return;
  1015. }
  1016. string ResultText = "";
  1017. backgroundWorker1.WorkerReportsProgress = true;
  1018. //編集箇所にマーカーを挿入する
  1019. //Insert marker in editing
  1020. if (richTextBox1.SelectionStart > 0)
  1021. {
  1022. //int NextLineNum = richTextBox1.GetLineFromCharIndex(richTextBox1.SelectionStart) + 1;
  1023. int ParagraphStart = richTextBox1.GetFirstCharIndexOfCurrentLine();
  1024. //if (ParagraphStart == 0)
  1025. //{
  1026. // ParagraphStart = 1;
  1027. //}
  1028. ResultText =
  1029. richTextBox1.Text.Substring(0, ParagraphStart) + "<!-- edit -->" +
  1030. richTextBox1.Text.Substring(ParagraphStart);
  1031. }
  1032. else
  1033. {
  1034. ResultText = richTextBox1.Text;
  1035. }
  1036. backgroundWorker1.RunWorkerAsync(ResultText);
  1037. }
  1038. //----------------------------------------------------------------------
  1039. // BackgroundWorker ProgressChanged
  1040. //----------------------------------------------------------------------
  1041. private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  1042. {
  1043. //ProgressBar1.Value = e.ProgressPercentage;
  1044. //Label1.Text = e.ProgressPercentage.ToString();
  1045. }
  1046. //----------------------------------------------------------------------
  1047. // BackgroundWorker browser preview
  1048. //----------------------------------------------------------------------
  1049. private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  1050. {
  1051. string ResultText = (string)e.Argument;
  1052. string MkResultText = "";
  1053. string BackgroundColorString;
  1054. string EncodingName;
  1055. //編集中のファイル名
  1056. //Editing file name
  1057. string FileName = (_MarkDownTextFilePath == "" ? "" : Path.GetFileName(_MarkDownTextFilePath));
  1058. //DOCTYPE
  1059. HtmlHeader htmlHeader = new HtmlHeader();
  1060. string DocType = htmlHeader.GetHtmlHeader(MarkDownSharpEditor.AppSettings.Instance.HtmlDocType);
  1061. //マーキングの色づけ
  1062. //Marker's color
  1063. if (MarkDownSharpEditor.AppSettings.Instance.fHtmlHighLightColor == true)
  1064. {
  1065. Color ColorBackground = Color.FromArgb(MarkDownSharpEditor.AppSettings.Instance.HtmlHighLightColor);
  1066. BackgroundColorString = ColorTranslator.ToHtml(ColorBackground);
  1067. }
  1068. else
  1069. {
  1070. BackgroundColorString = "none";
  1071. }
  1072. //指定のエンコーディング
  1073. //Codepage
  1074. int CodePageNum = MarkDownSharpEditor.AppSettings.Instance.CodePageNumber;
  1075. try
  1076. {
  1077. Encoding enc = Encoding.GetEncoding(CodePageNum);
  1078. //ブラウザ表示に対応したエンコーディングか
  1079. //Is the encoding supported browser?
  1080. if (enc.IsBrowserDisplay == true)
  1081. {
  1082. EncodingName = enc.WebName;
  1083. }
  1084. else
  1085. {
  1086. EncodingName = "utf-8";
  1087. }
  1088. }
  1089. catch
  1090. {
  1091. //エンコーディングの取得に失敗した場合
  1092. //Default encoding if failing to get encoding
  1093. EncodingName = "utf-8";
  1094. }
  1095. //Header
  1096. string header = string.Format(
  1097. @"{0}
  1098. <html>
  1099. <head>
  1100. <meta http-equiv='Content-Type' content='text/html; charset={1}' />
  1101. <link rel='stylesheet' href='{2}' type='text/css' />
  1102. <style type='text/css'>
  1103. ._mk {{background-color:{3}}}
  1104. </style>
  1105. <title>{4}</title>
  1106. </head>
  1107. <body>
  1108. ",
  1109. DocType, //DOCTYPE
  1110. EncodingName, //エンコーディング ( encoding )
  1111. _SelectedCssFilePath, //適用中のCSSファイル ( Selected CSS file )
  1112. BackgroundColorString, //編集箇所の背景色 ( background color in Editing )
  1113. FileName); //タイトル(=ファイル名) ( title = file name )
  1114. //Footer
  1115. string footer = "</body>\n</html>";
  1116. //-----------------------------------
  1117. //Markdown parse ( default )
  1118. //Markdown mkdwn = new Markdown();
  1119. //-----------------------------------
  1120. //-----------------------------------
  1121. // MarkdownDeep
  1122. // Create an instance of Markdown
  1123. //-----------------------------------
  1124. var mkdwn = new MarkdownDeep.Markdown();
  1125. // Set options
  1126. mkdwn.ExtraMode = MarkDownSharpEditor.AppSettings.Instance.fMarkdownExtraMode;
  1127. mkdwn.SafeMode = false;
  1128. //-----------------------------------
  1129. ResultText = mkdwn.Transform(ResultText);
  1130. //表示するHTMLデータを作成
  1131. //Creat HTML data
  1132. ResultText = header + ResultText + footer;
  1133. //パースされた内容から編集行を探す
  1134. //Search editing line in parsed data
  1135. string OneLine;
  1136. StringReader sr = new StringReader(ResultText);
  1137. StringWriter sw = new StringWriter();
  1138. while ((OneLine = sr.ReadLine()) != null)
  1139. {
  1140. if (OneLine.IndexOf("<!-- edit -->") >= 0)
  1141. {
  1142. MkResultText += ("<div class='_mk'>" + OneLine + "</div>\n");
  1143. }
  1144. else
  1145. {
  1146. MkResultText += (OneLine + "\n");
  1147. }
  1148. }
  1149. //エンコーディングしつつbyte値に変換する(richEditBoxは基本的にutf-8 = 65001)
  1150. //Encode and convert it to 'byte' value ( richEditBox default encoding is utf-8 = 65001 )
  1151. byte[] bytesData = Encoding.GetEncoding(CodePageNum).GetBytes(MkResultText);
  1152. //-----------------------------------
  1153. // Write to temporay file
  1154. if (_fNoTitle == false)
  1155. {
  1156. //テンポラリファイルパスを取得する
  1157. //Get temporary file path
  1158. if (_TemporaryHtmlFilePath == "")
  1159. {
  1160. _TemporaryHtmlFilePath = Get_TemporaryHtmlFilePath(_MarkDownTextFilePath);
  1161. }
  1162. //他のプロセスからのテンポラリファイルの参照と削除を許可して開く(でないと飛ぶ)
  1163. //Open temporary file to allow references from other processes
  1164. using (FileStream fs = new FileStream(
  1165. _TemporaryHtmlFilePath,
  1166. FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete))
  1167. {
  1168. fs.Write(bytesData, 0, bytesData.Length);
  1169. e.Result = _TemporaryHtmlFilePath;
  1170. }
  1171. }
  1172. //-----------------------------------
  1173. // Navigate and view in browser
  1174. else
  1175. {
  1176. //Write data as it is, if the editing data is no title
  1177. ResultText = Encoding.GetEncoding(CodePageNum).GetString(bytesData);
  1178. e.Result = ResultText;
  1179. }
  1180. }
  1181. private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  1182. {
  1183. if (e.Error != null)
  1184. {
  1185. //Error!
  1186. }
  1187. else
  1188. {
  1189. if ((string)e.Result != "")
  1190. {
  1191. //-----------------------------------
  1192. //スクロールバーの位置を退避しておく
  1193. //Memorize scroll positions
  1194. HtmlDocument doc = webBrowser1.Document;
  1195. Point scrollpos = new Point(0, 0);
  1196. if (doc == null)
  1197. {
  1198. webBrowser1.Navigate("about:blank");
  1199. }
  1200. else
  1201. {
  1202. IHTMLDocument3 doc3 = (IHTMLDocument3)webBrowser1.Document.DomDocument;
  1203. IHTMLElement2 elm = (IHTMLElement2)doc3.documentElement;
  1204. scrollpos = new Point(elm.scrollLeft, elm.scrollTop);
  1205. }
  1206. //-----------------------------------
  1207. System.Threading.Tasks.Task waitTask;
  1208. if (_fNoTitle == false)
  1209. {
  1210. //ナビゲート
  1211. //Browser navigate
  1212. //webBrowser1.Navigate(@"file://" + (string)e.Result);
  1213. waitTask = WebBrowserNavigate(@"file://" + (string)e.Result);
  1214. richTextBox1.Focus();
  1215. toolStripButtonBrowserPreview.Enabled = true;
  1216. }
  1217. else
  1218. {
  1219. webBrowser1.Document.OpenNew(true);
  1220. //webBrowser1.Document.Write((string)e.Result);
  1221. waitTask = WebBrowserDocumentWrite((string)e.Result);
  1222. //ツールバーの「関連付けられたブラウザーを起動」を無効に
  1223. //"Associated web browser" in toolbar is invalid
  1224. toolStripButtonBrowserPreview.Enabled = false;
  1225. }
  1226. //-----------------------------------
  1227. //スクロールバーの位置を復帰する
  1228. //Restore scroll bar position
  1229. if (doc != null)
  1230. {
  1231. waitTask.ContinueWith((arg1) =>
  1232. {
  1233. this.BeginInvoke(new Action(() =>
  1234. {
  1235. doc.Window.ScrollTo(scrollpos);
  1236. this.webBrowser1.Document.Body.AttachEventHandler("onscroll", OnScrollEventHandler);
  1237. }));
  1238. });
  1239. }
  1240. }
  1241. }
  1242. }
  1243. /// <summary>
  1244. /// webBrowser コンポーネントにHTMLを出力して
  1245. /// DocumentComplate になるのを非同期で待ち合わせる
  1246. /// </summary>
  1247. /// <param name="html"></param>
  1248. /// <returns></returns>
  1249. System.Threading.Tasks.Task WebBrowserDocumentWrite(string html)
  1250. {
  1251. if (browserWaitTimer == null)
  1252. {
  1253. browserWaitTimer = new Timer();
  1254. browserWaitTimer.Tick += browserWaitTimer_Tick;
  1255. browserWaitTimer.Enabled = true;
  1256. }
  1257. var obj = waitObject;
  1258. if (obj != null)
  1259. {
  1260. obj.SetCanceled();
  1261. }
  1262. waitObject = new System.Threading.Tasks.TaskCompletionSource<string>();
  1263. timerCount = 0;
  1264. this.webBrowser1.DocumentText = html;
  1265. browserWaitTimer.Enabled = true;
  1266. return waitObject.Task;
  1267. }
  1268. /// <summary>
  1269. /// webBrowser コンポーネントにHTMLを出力して
  1270. /// DocumentComplate になるのを非同期で待ち合わせる
  1271. /// </summary>
  1272. /// <param name="html"></param>
  1273. /// <returns></returns>
  1274. System.Threading.Tasks.Task WebBrowserNavigate(string url)
  1275. {
  1276. if (browserWaitTimer == null)
  1277. {
  1278. browserWaitTimer = new Timer();
  1279. browserWaitTimer.Tick += browserWaitTimer_Tick;
  1280. browserWaitTimer.Enabled = true;
  1281. }
  1282. var obj = waitObject;
  1283. if (obj != null)
  1284. {
  1285. obj.SetCanceled();
  1286. }
  1287. waitObject = new System.Threading.Tasks.TaskCompletionSource<string>();
  1288. timerCount = 0;
  1289. this.webBrowser1.Navigate(url);
  1290. browserWaitTimer.Enabled = true;
  1291. return waitObject.Task;
  1292. }
  1293. void browserWaitTimer_Tick(object sender, EventArgs e)
  1294. {
  1295. if (waitObject == null)
  1296. {
  1297. browserWaitTimer.Enabled = false;
  1298. return;
  1299. }
  1300. timerCount++;
  1301. if (this.webBrowser1.ReadyState == WebBrowserReadyState.Complete)
  1302. {
  1303. waitObject.SetResult("OK");
  1304. waitObject = null;
  1305. browserWaitTimer.Enabled = false;
  1306. }
  1307. else if (timerCount > 20)
  1308. {
  1309. // 反応ないので終わりにする
  1310. waitObject.SetResult("OK");
  1311. waitObject = null;
  1312. browserWaitTimer.Enabled = false;
  1313. }
  1314. }
  1315. System.Threading.Tasks.TaskCompletionSource<string> waitObject = null;
  1316. int timerCount = 0;
  1317. Timer browserWaitTimer;
  1318. //----------------------------------------------------------------------
  1319. // BackgroundWorker Syntax hightlighter work
  1320. //----------------------------------------------------------------------
  1321. private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
  1322. {
  1323. var text = e.Argument as string;
  1324. if (string.IsNullOrEmpty(text))
  1325. {
  1326. e.Result = null;
  1327. return;
  1328. }
  1329. if (timer2.Enabled == true)
  1330. {
  1331. e.Result = null;
  1332. return;
  1333. }
  1334. var result = new List<SyntaxColorScheme>();
  1335. foreach (MarkdownSyntaxKeyword mk in _MarkdownSyntaxKeywordAarray)
  1336. {
  1337. MatchCollection col = mk.Regex.Matches(text, 0);
  1338. if (col.Count > 0)
  1339. {
  1340. foreach (Match m in col)
  1341. {
  1342. SyntaxColorScheme sytx = new SyntaxColorScheme();
  1343. sytx.SelectionStartIndex = m.Groups[0].Index;
  1344. sytx.SelectionLength = m.Groups[0].Length;
  1345. sytx.ForeColor = mk.ForeColor;
  1346. sytx.BackColor = mk.BackColor;
  1347. result.Add(sytx);
  1348. }
  1349. }
  1350. }
  1351. e.Result = result;
  1352. }
  1353. //----------------------------------------------------------------------
  1354. // BackgroundWorker Editor Syntax hightlighter progress changed
  1355. //----------------------------------------------------------------------
  1356. private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
  1357. {
  1358. }
  1359. //-------------------------------------------------------…

Large files files are truncated, but you can click here to view the full file