/* * Copyright (C) 2013 FooProject * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Linq; using System.Collections.Generic; namespace FooEditEngine { /// /// 既定のIDリスト /// public static class MarkerIDs { /// /// デフォルトIDを表す /// public static int Defalut = 0; /// /// URLを表す /// public static int URL = 1; /// /// IMEの変換候補を表す /// public static int IME = -1; } /// /// マーカーのタイプを表す列挙体 /// public enum HilightType { /// /// マーカーとして表示しないことを表す /// None, /// /// 選択状態を表す /// Select, /// /// URLを表す /// Url, /// /// 実線を表す /// Sold, /// /// 破線を表す /// Dash, /// /// 一点鎖線を表す /// DashDot, /// /// 二点鎖線を表す /// DashDotDot, /// /// 点線を表す /// Dot, /// /// 波線を表す /// Squiggle, } /// /// マーカー自身を表します /// public struct Marker : IRange, IEqualityComparer { #region IRange メンバー /// /// 開始位置 /// public int start { get; set; } /// /// 長さ /// public int length { get; set; } #endregion /// /// マーカーのタイプ /// public HilightType hilight; /// /// 色を指定する /// public Color color; /// /// 線を太くするかどうか /// public bool isBoldLine; /// /// マーカーを作成します /// /// 開始インデックス /// 長さ /// タイプ /// マーカー public static Marker Create(int start, int length, HilightType hilight) { return new Marker { start = start, length = length, hilight = hilight, color = new Color(), isBoldLine = false}; } /// /// マーカーを作成します /// /// 開始インデックス /// 長さ /// タイプ /// 色 /// 線を太くするかどうか /// マーカー public static Marker Create(int start, int length, HilightType hilight,Color color,bool isBoldLine = false) { return new Marker { start = start, length = length, hilight = hilight ,color = color , isBoldLine = isBoldLine }; } /// /// 等しいかどうかを調べます /// /// 比較されるマーカー /// 比較するマーカー /// 等しいなら真。そうでなければ偽 public bool Equals(Marker x, Marker y) { return x.hilight == y.hilight && x.length == y.length && x.start == y.start; } /// /// ハッシュを得ます /// /// マーカー /// ハッシュ public int GetHashCode(Marker obj) { return this.start ^ this.length ^ (int)this.hilight; } } /// /// マーカークラスのコレクションを表します /// public sealed class MarkerCollection { Dictionary> collection = new Dictionary>(); internal MarkerCollection() { this.Updated +=new EventHandler((s,e)=>{}); } /// /// 更新されたことを通知します /// public event EventHandler Updated; internal void Add(int id,Marker m) { this.AddImpl(id, m); this.Updated(this, null); } void AddImpl(int id, Marker m) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { markers.Remove(m.start, m.length); markers.Add(m); } else { markers = new RangeCollection(); markers.Add(m); this.collection.Add(id, markers); } } internal void AddRange(int id, IEnumerable collection) { foreach (Marker m in collection) this.AddImpl(id, m); this.Updated(this, null); } internal void RemoveAll(int id) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { markers.Clear(); } this.Updated(this, null); } internal void RemoveAll(int id,int start, int length) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { markers.Remove(start, length); } this.Updated(this, null); } internal void RemoveAll(int id, HilightType type) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { for (int i = 0; i < markers.Count; i++) { if (markers[i].hilight == type) markers.RemoveAt(i); } } this.Updated(this, null); } internal IEnumerable IDs { get { return this.collection.Keys; } } internal IEnumerable Get(int id) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { foreach (var m in markers) yield return m; } yield break; } internal IEnumerable Get(int id, int index) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { foreach (var m in markers.Get(index)) yield return m; } yield break; } internal IEnumerable Get(int id, int index, int length) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) { foreach (var m in markers.Get(index, length)) yield return m; } yield break; } /// /// マーカーをすべて削除します /// /// マーカーID public void Clear(int id) { RangeCollection markers; if (this.collection.TryGetValue(id, out markers)) markers.Clear(); this.Updated(this, null); } /// /// マーカーをすべて削除します /// public void Clear() { this.collection.Clear(); this.Updated(this, null); } internal void UpdateMarkers(int startIndex,int insertLength,int removeLength) { int deltaLength = insertLength - removeLength; foreach (RangeCollection markers in this.collection.Values) { for (int i = 0; i < markers.Count; i++) { Marker m = markers[i]; if (m.start + m.length - 1 < startIndex) { continue; } else { m.start += deltaLength; } markers[i] = m; } } } } }