リビジョン | b73c3927594e5b31724e0479bee10c9456abb9ea (tree) |
---|---|
日時 | 2011-02-16 01:14:21 |
作者 | azyobuzin <azyobuzin@user...> |
コミッター | azyobuzin |
・@#の補完(まだ途中)
・RecentStatusesCollectionを扱うところをlockした
・StatusesListViewをWPF風にした
・StatusesListViewでズレに対処
・メイン画面のサイズ・位置の保存を実装
@@ -25,11 +25,14 @@ namespace Azyobuzi.Twirunrun | ||
25 | 25 | this.DrawSubItem += this_DrawSubItem; |
26 | 26 | } |
27 | 27 | |
28 | + private int oldCount; | |
29 | + | |
28 | 30 | private IList<StatusInfo> statuses; |
29 | 31 | public IList<StatusInfo> Statuses |
30 | 32 | { |
31 | 33 | set |
32 | 34 | { |
35 | + if (statuses != null) oldCount = statuses.Count; | |
33 | 36 | statuses = value; |
34 | 37 | SetItemsCount(); |
35 | 38 | } |
@@ -39,18 +42,36 @@ namespace Azyobuzi.Twirunrun | ||
39 | 42 | } |
40 | 43 | } |
41 | 44 | |
42 | - public void SetItemsCount(int count) | |
45 | + public void SetItemsCount(int count, int addCount) | |
43 | 46 | { |
44 | 47 | this.Invoke((MethodInvoker)(() => |
45 | 48 | { |
46 | 49 | VirtualListSize = count; |
47 | 50 | this.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.ColumnContent); |
51 | + | |
52 | + if (addCount != 0) | |
53 | + { | |
54 | + var indexes = this.SelectedIndices.Cast<int>().ToArray(); | |
55 | + this.SelectedIndices.Clear(); | |
56 | + indexes.Select(oldIndex => oldIndex + | |
57 | + (int)Settings.Instance.OrderType.SelectCase() | |
58 | + .Case(OrderTypes.Ascending, () => -1) | |
59 | + .Case(OrderTypes.Descending, () => +1) | |
60 | + .Result | |
61 | + ) | |
62 | + .ForEach(newIndex => this.SelectedIndices.Add(newIndex)); | |
63 | + } | |
48 | 64 | })); |
49 | 65 | } |
50 | 66 | |
51 | 67 | public void SetItemsCount() |
52 | 68 | { |
53 | - SetItemsCount(Statuses.Count); | |
69 | + SetItemsCount(Statuses.Count, statuses.Count - oldCount); | |
70 | + } | |
71 | + | |
72 | + protected override void OnSelectedIndexChanged(EventArgs e) | |
73 | + { | |
74 | + base.OnSelectedIndexChanged(e); | |
54 | 75 | } |
55 | 76 | |
56 | 77 | private ListViewItem CreateListViewItem(StatusInfo item) |
@@ -87,22 +108,22 @@ namespace Azyobuzi.Twirunrun | ||
87 | 108 | e.Item = item; |
88 | 109 | } |
89 | 110 | |
90 | - //ラベルは保留 | |
91 | 111 | private void this_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) |
92 | 112 | { |
93 | 113 | if (e.ItemIndex < 0 || e.ColumnIndex < 0) return; |
94 | 114 | |
95 | 115 | e.Graphics.InterpolationMode = InterpolationMode.High; |
96 | 116 | |
97 | - using (var b = new SolidBrush( | |
98 | - (e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected ? | |
99 | - SystemColors.Highlight : e.SubItem.BackColor)) | |
117 | + using (var b = (e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected ? | |
118 | + (Brush)new LinearGradientBrush(e.Bounds, Color.FromArgb(240, 250, 255), Color.FromArgb(170, 240, 255), LinearGradientMode.Vertical) | |
119 | + : (Brush)new SolidBrush(e.SubItem.BackColor)) | |
100 | 120 | { |
101 | 121 | e.Graphics.FillRectangle(b, e.Bounds); |
102 | 122 | } |
103 | 123 | |
104 | - var foreColor = (e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected ? | |
105 | - SystemColors.HighlightText : e.Item.ForeColor; | |
124 | + //var foreColor = (e.ItemState & ListViewItemStates.Selected) == ListViewItemStates.Selected ? | |
125 | + // SystemColors.HighlightText : e.Item.ForeColor; | |
126 | + var foreColor = e.SubItem.ForeColor; | |
106 | 127 | |
107 | 128 | e.ColumnIndex.SelectCase() |
108 | 129 | .Case(0, () =>//名前部 |
@@ -10,11 +10,12 @@ namespace Azyobuzi.Twirunrun | ||
10 | 10 | { |
11 | 11 | RecentStatusesCollection.Instance.CollectionChanged += (sender, e) => |
12 | 12 | { |
13 | - Timeline.Statuses = | |
14 | - RecentStatusesCollection.Instance.AsParallel() | |
15 | - .Where(tweet => tweet.Type == StatusTypes.DirectMessage) | |
16 | - .OrderBy(Settings.Instance.OrderType) | |
17 | - .ToList(); | |
13 | + lock (RecentStatusesCollection.Instance) | |
14 | + Timeline.Statuses = | |
15 | + RecentStatusesCollection.Instance.AsParallel() | |
16 | + .Where(tweet => tweet.Type == StatusTypes.DirectMessage) | |
17 | + .OrderBy(Settings.Instance.OrderType) | |
18 | + .ToList(); | |
18 | 19 | }; |
19 | 20 | } |
20 | 21 |
@@ -30,9 +31,15 @@ namespace Azyobuzi.Twirunrun | ||
30 | 31 | dm.Count == count |
31 | 32 | ) |
32 | 33 | ).Select(dm => new StatusInfo(dm)) |
33 | - .Where(dm => !RecentStatusesCollection.Instance.AsParallel().Contains(dm)) | |
34 | + .AsEnumerable() | |
35 | + .Where(dm => | |
36 | + { | |
37 | + lock (RecentStatusesCollection.Instance) | |
38 | + return !RecentStatusesCollection.Instance.AsParallel().Contains(dm); | |
39 | + }) | |
34 | 40 | .ToArray(); |
35 | - RecentStatusesCollection.Instance.AddRange(newDMs); | |
41 | + lock (RecentStatusesCollection.Instance) | |
42 | + RecentStatusesCollection.Instance.AddRange(newDMs); | |
36 | 43 | if (!first && newDMs.Any()) |
37 | 44 | this.NotifyNewItems(newDMs.OrderByDescending(_ => _)); |
38 | 45 | } |
@@ -10,11 +10,12 @@ namespace Azyobuzi.Twirunrun | ||
10 | 10 | { |
11 | 11 | RecentStatusesCollection.Instance.CollectionChanged += (sender, e) => |
12 | 12 | { |
13 | - Timeline.Statuses = | |
14 | - RecentStatusesCollection.Instance.AsParallel() | |
15 | - .Where(tweet => tweet.Type != StatusTypes.DirectMessage) | |
16 | - .OrderBy(Settings.Instance.OrderType) | |
17 | - .ToList(); | |
13 | + lock (RecentStatusesCollection.Instance) | |
14 | + Timeline.Statuses = | |
15 | + RecentStatusesCollection.Instance.AsParallel() | |
16 | + .Where(tweet => tweet.Type != StatusTypes.DirectMessage) | |
17 | + .OrderBy(Settings.Instance.OrderType) | |
18 | + .ToList(); | |
18 | 19 | }; |
19 | 20 | } |
20 | 21 |
@@ -29,9 +30,15 @@ namespace Azyobuzi.Twirunrun | ||
29 | 30 | tweet.Count == count |
30 | 31 | ) |
31 | 32 | .Select(tweet => new StatusInfo(tweet)) |
32 | - .Where(tweet => !RecentStatusesCollection.Instance.AsParallel().Contains(tweet)) | |
33 | + .AsEnumerable() | |
34 | + .Where(tweet => | |
35 | + { | |
36 | + lock (RecentStatusesCollection.Instance) | |
37 | + return !RecentStatusesCollection.Instance.AsParallel().Contains(tweet); | |
38 | + }) | |
33 | 39 | .ToArray(); |
34 | - RecentStatusesCollection.Instance.AddRange(newTweets); | |
40 | + lock (RecentStatusesCollection.Instance) | |
41 | + RecentStatusesCollection.Instance.AddRange(newTweets); | |
35 | 42 | if (!first && newTweets.Any()) |
36 | 43 | this.NotifyNewItems(newTweets.OrderByDescending(_ => _)); |
37 | 44 | } |
@@ -16,13 +16,14 @@ namespace Azyobuzi.Twirunrun | ||
16 | 16 | RecentStatusesCollection.Instance.CollectionChanged += (sender, e) => |
17 | 17 | { |
18 | 18 | //リストに反映 |
19 | - Timeline.Statuses = | |
20 | - RecentStatusesCollection.Instance.AsParallel() | |
21 | - .Where(tweet => | |
22 | - tweet.Type != StatusTypes.DirectMessage && | |
23 | - mentionCheckRegex.IsMatch(tweet.Text)) | |
24 | - .OrderBy(Settings.Instance.OrderType) | |
25 | - .ToList(); | |
19 | + lock (RecentStatusesCollection.Instance) | |
20 | + Timeline.Statuses = | |
21 | + RecentStatusesCollection.Instance.AsParallel() | |
22 | + .Where(tweet => | |
23 | + tweet.Type != StatusTypes.DirectMessage && | |
24 | + mentionCheckRegex.IsMatch(tweet.Text)) | |
25 | + .OrderBy(Settings.Instance.OrderType) | |
26 | + .ToList(); | |
26 | 27 | //新着通知 |
27 | 28 | if (e.NewItems.Count != 0 && !first) |
28 | 29 | { |
@@ -46,10 +47,18 @@ namespace Azyobuzi.Twirunrun | ||
46 | 47 | tweet.Count == count |
47 | 48 | ) |
48 | 49 | .Select(tweet => new StatusInfo(tweet)) |
49 | - .Where(tweet => !RecentStatusesCollection.Instance.AsParallel().Contains(tweet)) | |
50 | + .AsEnumerable() | |
51 | + .Where(tweet => | |
52 | + { | |
53 | + lock (RecentStatusesCollection.Instance) | |
54 | + return !RecentStatusesCollection.Instance.AsParallel().Contains(tweet); | |
55 | + }) | |
50 | 56 | .ToArray(); |
51 | 57 | if (newTweets.Any()) |
52 | - RecentStatusesCollection.Instance.AddRange(newTweets); | |
58 | + { | |
59 | + lock (RecentStatusesCollection.Instance) | |
60 | + RecentStatusesCollection.Instance.AddRange(newTweets); | |
61 | + } | |
53 | 62 | first = false; |
54 | 63 | } |
55 | 64 | finally |
@@ -28,19 +28,17 @@ | ||
28 | 28 | /// </summary> |
29 | 29 | private void InitializeComponent() |
30 | 30 | { |
31 | - this.statusBox = new System.Windows.Forms.TextBox(); | |
31 | + this.statusBox = new UpdateStatusTextBox(); | |
32 | 32 | this.updateBtn = new System.Windows.Forms.Button(); |
33 | 33 | this.restLbl = new System.Windows.Forms.Label(); |
34 | 34 | this.SuspendLayout(); |
35 | 35 | // |
36 | 36 | // statusBox |
37 | 37 | // |
38 | - this.statusBox.AcceptsReturn = true; | |
39 | 38 | this.statusBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) |
40 | 39 | | System.Windows.Forms.AnchorStyles.Left) |
41 | 40 | | System.Windows.Forms.AnchorStyles.Right))); |
42 | 41 | this.statusBox.Location = new System.Drawing.Point(3, 3); |
43 | - this.statusBox.Multiline = true; | |
44 | 42 | this.statusBox.Name = "statusBox"; |
45 | 43 | this.statusBox.Size = new System.Drawing.Size(144, 115); |
46 | 44 | this.statusBox.TabIndex = 0; |
@@ -82,7 +80,7 @@ | ||
82 | 80 | |
83 | 81 | #endregion |
84 | 82 | |
85 | - private System.Windows.Forms.TextBox statusBox; | |
83 | + private UpdateStatusTextBox statusBox; | |
86 | 84 | private System.Windows.Forms.Button updateBtn; |
87 | 85 | private System.Windows.Forms.Label restLbl; |
88 | 86 | } |
@@ -0,0 +1,102 @@ | ||
1 | +namespace Azyobuzi.Twirunrun | |
2 | +{ | |
3 | + partial class UpdateStatusTextBox | |
4 | + { | |
5 | + /// <summary> | |
6 | + /// 必要なデザイナー変数です。 | |
7 | + /// </summary> | |
8 | + private System.ComponentModel.IContainer components = null; | |
9 | + | |
10 | + /// <summary> | |
11 | + /// 使用中のリソースをすべてクリーンアップします。 | |
12 | + /// </summary> | |
13 | + /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param> | |
14 | + protected override void Dispose(bool disposing) | |
15 | + { | |
16 | + if (disposing && (components != null)) | |
17 | + { | |
18 | + components.Dispose(); | |
19 | + } | |
20 | + base.Dispose(disposing); | |
21 | + } | |
22 | + | |
23 | + #region コンポーネント デザイナーで生成されたコード | |
24 | + | |
25 | + /// <summary> | |
26 | + /// デザイナー サポートに必要なメソッドです。このメソッドの内容を | |
27 | + /// コード エディターで変更しないでください。 | |
28 | + /// </summary> | |
29 | + private void InitializeComponent() | |
30 | + { | |
31 | + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); | |
32 | + this.textBox1 = new System.Windows.Forms.TextBox(); | |
33 | + this.listBox1 = new System.Windows.Forms.ListBox(); | |
34 | + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); | |
35 | + this.splitContainer1.Panel1.SuspendLayout(); | |
36 | + this.splitContainer1.Panel2.SuspendLayout(); | |
37 | + this.splitContainer1.SuspendLayout(); | |
38 | + this.SuspendLayout(); | |
39 | + // | |
40 | + // splitContainer1 | |
41 | + // | |
42 | + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; | |
43 | + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; | |
44 | + this.splitContainer1.Location = new System.Drawing.Point(0, 0); | |
45 | + this.splitContainer1.Name = "splitContainer1"; | |
46 | + // | |
47 | + // splitContainer1.Panel1 | |
48 | + // | |
49 | + this.splitContainer1.Panel1.Controls.Add(this.textBox1); | |
50 | + // | |
51 | + // splitContainer1.Panel2 | |
52 | + // | |
53 | + this.splitContainer1.Panel2.Controls.Add(this.listBox1); | |
54 | + this.splitContainer1.Panel2Collapsed = true; | |
55 | + this.splitContainer1.Size = new System.Drawing.Size(150, 150); | |
56 | + this.splitContainer1.SplitterDistance = 25; | |
57 | + this.splitContainer1.TabIndex = 0; | |
58 | + // | |
59 | + // textBox1 | |
60 | + // | |
61 | + this.textBox1.AcceptsReturn = true; | |
62 | + this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill; | |
63 | + this.textBox1.Location = new System.Drawing.Point(0, 0); | |
64 | + this.textBox1.Multiline = true; | |
65 | + this.textBox1.Name = "textBox1"; | |
66 | + this.textBox1.Size = new System.Drawing.Size(150, 150); | |
67 | + this.textBox1.TabIndex = 0; | |
68 | + this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown); | |
69 | + this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); | |
70 | + // | |
71 | + // listBox1 | |
72 | + // | |
73 | + this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill; | |
74 | + this.listBox1.FormattingEnabled = true; | |
75 | + this.listBox1.ItemHeight = 12; | |
76 | + this.listBox1.Location = new System.Drawing.Point(0, 0); | |
77 | + this.listBox1.Name = "listBox1"; | |
78 | + this.listBox1.Size = new System.Drawing.Size(96, 100); | |
79 | + this.listBox1.TabIndex = 0; | |
80 | + // | |
81 | + // UpdateStatusTextBox | |
82 | + // | |
83 | + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); | |
84 | + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
85 | + this.Controls.Add(this.splitContainer1); | |
86 | + this.Name = "UpdateStatusTextBox"; | |
87 | + this.splitContainer1.Panel1.ResumeLayout(false); | |
88 | + this.splitContainer1.Panel1.PerformLayout(); | |
89 | + this.splitContainer1.Panel2.ResumeLayout(false); | |
90 | + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); | |
91 | + this.splitContainer1.ResumeLayout(false); | |
92 | + this.ResumeLayout(false); | |
93 | + | |
94 | + } | |
95 | + | |
96 | + #endregion | |
97 | + | |
98 | + private System.Windows.Forms.SplitContainer splitContainer1; | |
99 | + private System.Windows.Forms.TextBox textBox1; | |
100 | + private System.Windows.Forms.ListBox listBox1; | |
101 | + } | |
102 | +} |
@@ -0,0 +1,86 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.ComponentModel; | |
4 | +using System.Drawing; | |
5 | +using System.Data; | |
6 | +using System.Linq; | |
7 | +using System.Text; | |
8 | +using System.Windows.Forms; | |
9 | + | |
10 | +namespace Azyobuzi.Twirunrun | |
11 | +{ | |
12 | + public partial class UpdateStatusTextBox : UserControl | |
13 | + { | |
14 | + public UpdateStatusTextBox() | |
15 | + { | |
16 | + InitializeComponent(); | |
17 | + listBox1.DataSource = Settings.Instance.AtHashtagList; | |
18 | + } | |
19 | + | |
20 | + public void Clear() | |
21 | + { | |
22 | + textBox1.Clear(); | |
23 | + splitContainer1.Panel2Collapsed = true; | |
24 | + } | |
25 | + | |
26 | + [Browsable(true)] | |
27 | + public override string Text | |
28 | + { | |
29 | + get | |
30 | + { | |
31 | + return textBox1.Text; | |
32 | + } | |
33 | + set | |
34 | + { | |
35 | + textBox1.Text = value; | |
36 | + } | |
37 | + } | |
38 | + | |
39 | + private void textBox1_KeyPress(object sender, KeyPressEventArgs e) | |
40 | + { | |
41 | + if (e.KeyChar == (char)Keys.Back) | |
42 | + { | |
43 | + if (textBox1.SelectionStart > 0 && "@@##".Contains(textBox1.Text[textBox1.SelectionStart - 1])) | |
44 | + splitContainer1.Panel2Collapsed = true; | |
45 | + else | |
46 | + return; | |
47 | + } | |
48 | + else if (e.KeyChar == (char)Keys.Delete) | |
49 | + { | |
50 | + if (textBox1.SelectionStart != textBox1.TextLength && "@@##".Contains(textBox1.Text[textBox1.SelectionStart])) | |
51 | + splitContainer1.Panel2Collapsed = true; | |
52 | + else | |
53 | + return; | |
54 | + } | |
55 | + | |
56 | + if ("@@##".Contains(e.KeyChar)) | |
57 | + splitContainer1.Panel2Collapsed = false; | |
58 | + else if (!"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ_-0123456789".Contains(e.KeyChar)) | |
59 | + splitContainer1.Panel2Collapsed = true; | |
60 | + } | |
61 | + | |
62 | + public int TextLength | |
63 | + { | |
64 | + get | |
65 | + { | |
66 | + return textBox1.TextLength; | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + public void Select(int start, int length) | |
71 | + { | |
72 | + textBox1.Select(start, length); | |
73 | + } | |
74 | + | |
75 | + private void textBox1_KeyDown(object sender, KeyEventArgs e) | |
76 | + { | |
77 | + if (!splitContainer1.Panel2Collapsed) | |
78 | + { | |
79 | + if (e.KeyCode == Keys.Down && listBox1.SelectedIndex != listBox1.Items.Count - 1) | |
80 | + listBox1.SelectedIndex++; | |
81 | + else if (e.KeyCode == Keys.Up && listBox1.SelectedIndex > -1) | |
82 | + listBox1.SelectedIndex--; | |
83 | + } | |
84 | + } | |
85 | + } | |
86 | +} |
@@ -0,0 +1,120 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<root> | |
3 | + <!-- | |
4 | + Microsoft ResX Schema | |
5 | + | |
6 | + Version 2.0 | |
7 | + | |
8 | + The primary goals of this format is to allow a simple XML format | |
9 | + that is mostly human readable. The generation and parsing of the | |
10 | + various data types are done through the TypeConverter classes | |
11 | + associated with the data types. | |
12 | + | |
13 | + Example: | |
14 | + | |
15 | + ... ado.net/XML headers & schema ... | |
16 | + <resheader name="resmimetype">text/microsoft-resx</resheader> | |
17 | + <resheader name="version">2.0</resheader> | |
18 | + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |
19 | + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |
20 | + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |
21 | + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |
22 | + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |
23 | + <value>[base64 mime encoded serialized .NET Framework object]</value> | |
24 | + </data> | |
25 | + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |
26 | + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |
27 | + <comment>This is a comment</comment> | |
28 | + </data> | |
29 | + | |
30 | + There are any number of "resheader" rows that contain simple | |
31 | + name/value pairs. | |
32 | + | |
33 | + Each data row contains a name, and value. The row also contains a | |
34 | + type or mimetype. Type corresponds to a .NET class that support | |
35 | + text/value conversion through the TypeConverter architecture. | |
36 | + Classes that don't support this are serialized and stored with the | |
37 | + mimetype set. | |
38 | + | |
39 | + The mimetype is used for serialized objects, and tells the | |
40 | + ResXResourceReader how to depersist the object. This is currently not | |
41 | + extensible. For a given mimetype the value must be set accordingly: | |
42 | + | |
43 | + Note - application/x-microsoft.net.object.binary.base64 is the format | |
44 | + that the ResXResourceWriter will generate, however the reader can | |
45 | + read any of the formats listed below. | |
46 | + | |
47 | + mimetype: application/x-microsoft.net.object.binary.base64 | |
48 | + value : The object must be serialized with | |
49 | + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |
50 | + : and then encoded with base64 encoding. | |
51 | + | |
52 | + mimetype: application/x-microsoft.net.object.soap.base64 | |
53 | + value : The object must be serialized with | |
54 | + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |
55 | + : and then encoded with base64 encoding. | |
56 | + | |
57 | + mimetype: application/x-microsoft.net.object.bytearray.base64 | |
58 | + value : The object must be serialized into a byte array | |
59 | + : using a System.ComponentModel.TypeConverter | |
60 | + : and then encoded with base64 encoding. | |
61 | + --> | |
62 | + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |
63 | + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |
64 | + <xsd:element name="root" msdata:IsDataSet="true"> | |
65 | + <xsd:complexType> | |
66 | + <xsd:choice maxOccurs="unbounded"> | |
67 | + <xsd:element name="metadata"> | |
68 | + <xsd:complexType> | |
69 | + <xsd:sequence> | |
70 | + <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |
71 | + </xsd:sequence> | |
72 | + <xsd:attribute name="name" use="required" type="xsd:string" /> | |
73 | + <xsd:attribute name="type" type="xsd:string" /> | |
74 | + <xsd:attribute name="mimetype" type="xsd:string" /> | |
75 | + <xsd:attribute ref="xml:space" /> | |
76 | + </xsd:complexType> | |
77 | + </xsd:element> | |
78 | + <xsd:element name="assembly"> | |
79 | + <xsd:complexType> | |
80 | + <xsd:attribute name="alias" type="xsd:string" /> | |
81 | + <xsd:attribute name="name" type="xsd:string" /> | |
82 | + </xsd:complexType> | |
83 | + </xsd:element> | |
84 | + <xsd:element name="data"> | |
85 | + <xsd:complexType> | |
86 | + <xsd:sequence> | |
87 | + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
88 | + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |
89 | + </xsd:sequence> | |
90 | + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |
91 | + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |
92 | + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |
93 | + <xsd:attribute ref="xml:space" /> | |
94 | + </xsd:complexType> | |
95 | + </xsd:element> | |
96 | + <xsd:element name="resheader"> | |
97 | + <xsd:complexType> | |
98 | + <xsd:sequence> | |
99 | + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
100 | + </xsd:sequence> | |
101 | + <xsd:attribute name="name" type="xsd:string" use="required" /> | |
102 | + </xsd:complexType> | |
103 | + </xsd:element> | |
104 | + </xsd:choice> | |
105 | + </xsd:complexType> | |
106 | + </xsd:element> | |
107 | + </xsd:schema> | |
108 | + <resheader name="resmimetype"> | |
109 | + <value>text/microsoft-resx</value> | |
110 | + </resheader> | |
111 | + <resheader name="version"> | |
112 | + <value>2.0</value> | |
113 | + </resheader> | |
114 | + <resheader name="reader"> | |
115 | + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
116 | + </resheader> | |
117 | + <resheader name="writer"> | |
118 | + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
119 | + </resheader> | |
120 | +</root> | |
\ No newline at end of file |
@@ -34,14 +34,14 @@ | ||
34 | 34 | this.ファイルFToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); |
35 | 35 | this.fileMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); |
36 | 36 | this.終了XToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); |
37 | + this.ストリーミングSToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
38 | + this.streamingStateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
39 | + this.startStopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
37 | 40 | this.postPanelSplitter = new System.Windows.Forms.Splitter(); |
38 | 41 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); |
39 | 42 | this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel(); |
40 | 43 | this.statusBrowserSplitter = new System.Windows.Forms.Splitter(); |
41 | 44 | this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); |
42 | - this.ストリーミングSToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
43 | - this.streamingStateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
44 | - this.startStopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); | |
45 | 45 | this.timelineTabs = new Azyobuzi.Twirunrun.TwirunrunTabControl(); |
46 | 46 | this.statusBrowser1 = new Azyobuzi.Twirunrun.StatusBrowser(); |
47 | 47 | this.updateStatusPanel1 = new Azyobuzi.Twirunrun.UpdateStatusPanel(); |
@@ -83,6 +83,29 @@ | ||
83 | 83 | this.終了XToolStripMenuItem.Text = "終了(&X)"; |
84 | 84 | this.終了XToolStripMenuItem.Click += new System.EventHandler(this.終了XToolStripMenuItem_Click); |
85 | 85 | // |
86 | + // ストリーミングSToolStripMenuItem | |
87 | + // | |
88 | + this.ストリーミングSToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { | |
89 | + this.streamingStateToolStripMenuItem, | |
90 | + this.startStopToolStripMenuItem}); | |
91 | + this.ストリーミングSToolStripMenuItem.Name = "ストリーミングSToolStripMenuItem"; | |
92 | + this.ストリーミングSToolStripMenuItem.Size = new System.Drawing.Size(122, 22); | |
93 | + this.ストリーミングSToolStripMenuItem.Text = "ストリーミング(&S)"; | |
94 | + // | |
95 | + // streamingStateToolStripMenuItem | |
96 | + // | |
97 | + this.streamingStateToolStripMenuItem.Enabled = false; | |
98 | + this.streamingStateToolStripMenuItem.Name = "streamingStateToolStripMenuItem"; | |
99 | + this.streamingStateToolStripMenuItem.Size = new System.Drawing.Size(124, 22); | |
100 | + this.streamingStateToolStripMenuItem.Text = "Stopped"; | |
101 | + // | |
102 | + // startStopToolStripMenuItem | |
103 | + // | |
104 | + this.startStopToolStripMenuItem.Name = "startStopToolStripMenuItem"; | |
105 | + this.startStopToolStripMenuItem.Size = new System.Drawing.Size(124, 22); | |
106 | + this.startStopToolStripMenuItem.Text = "&Start"; | |
107 | + this.startStopToolStripMenuItem.Click += new System.EventHandler(this.startStopToolStripMenuItem_Click); | |
108 | + // | |
86 | 109 | // postPanelSplitter |
87 | 110 | // |
88 | 111 | this.postPanelSplitter.Dock = System.Windows.Forms.DockStyle.Top; |
@@ -127,29 +150,6 @@ | ||
127 | 150 | this.notifyIcon1.Visible = true; |
128 | 151 | this.notifyIcon1.Click += new System.EventHandler(this.notifyIcon1_Click); |
129 | 152 | // |
130 | - // ストリーミングSToolStripMenuItem | |
131 | - // | |
132 | - this.ストリーミングSToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { | |
133 | - this.streamingStateToolStripMenuItem, | |
134 | - this.startStopToolStripMenuItem}); | |
135 | - this.ストリーミングSToolStripMenuItem.Name = "ストリーミングSToolStripMenuItem"; | |
136 | - this.ストリーミングSToolStripMenuItem.Size = new System.Drawing.Size(122, 22); | |
137 | - this.ストリーミングSToolStripMenuItem.Text = "ストリーミング(&S)"; | |
138 | - // | |
139 | - // streamingStateToolStripMenuItem | |
140 | - // | |
141 | - this.streamingStateToolStripMenuItem.Enabled = false; | |
142 | - this.streamingStateToolStripMenuItem.Name = "streamingStateToolStripMenuItem"; | |
143 | - this.streamingStateToolStripMenuItem.Size = new System.Drawing.Size(152, 22); | |
144 | - this.streamingStateToolStripMenuItem.Text = "Stopped"; | |
145 | - // | |
146 | - // startStopToolStripMenuItem | |
147 | - // | |
148 | - this.startStopToolStripMenuItem.Name = "startStopToolStripMenuItem"; | |
149 | - this.startStopToolStripMenuItem.Size = new System.Drawing.Size(152, 22); | |
150 | - this.startStopToolStripMenuItem.Text = "&Start"; | |
151 | - this.startStopToolStripMenuItem.Click += new System.EventHandler(this.startStopToolStripMenuItem_Click); | |
152 | - // | |
153 | 153 | // timelineTabs |
154 | 154 | // |
155 | 155 | this.timelineTabs.Dock = System.Windows.Forms.DockStyle.Fill; |
@@ -196,10 +196,13 @@ | ||
196 | 196 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); |
197 | 197 | this.MainMenuStrip = this.menuStrip1; |
198 | 198 | this.Name = "MainForm"; |
199 | + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; | |
199 | 200 | this.Text = "ついるんるん"; |
200 | 201 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); |
201 | - this.Load += new System.EventHandler(this.Form1_Load); | |
202 | + this.Load += new System.EventHandler(this.MainForm_Load); | |
202 | 203 | this.Shown += new System.EventHandler(this.MainForm_Shown); |
204 | + this.LocationChanged += new System.EventHandler(this.MainForm_BoundsChanged); | |
205 | + this.SizeChanged += new System.EventHandler(this.MainForm_BoundsChanged); | |
203 | 206 | this.menuStrip1.ResumeLayout(false); |
204 | 207 | this.menuStrip1.PerformLayout(); |
205 | 208 | this.fileMenuStrip.ResumeLayout(false); |
@@ -102,7 +102,7 @@ namespace Azyobuzi.Twirunrun | ||
102 | 102 | us.NewDirectMessage += us_NewDirectMessage; |
103 | 103 | } |
104 | 104 | |
105 | - private void Form1_Load(object sender, EventArgs e) | |
105 | + private void MainForm_Load(object sender, EventArgs e) | |
106 | 106 | { |
107 | 107 | Icons.AddCompleted = |
108 | 108 | () => ((TimelineTabPage)timelineTabs.SelectedTab).Timeline.Refresh(); |
@@ -193,7 +193,8 @@ namespace Azyobuzi.Twirunrun | ||
193 | 193 | us.Start(null, false); |
194 | 194 | else |
195 | 195 | us.Stop(); |
196 | - }); | |
196 | + }) | |
197 | + .Case("MainFormSetting", () => s.MainFormSetting.Restore(this)); | |
197 | 198 | } |
198 | 199 | |
199 | 200 | private void updateStatusPanel1_RunUpdateStatus(object sender, EventArgs e) |
@@ -311,7 +312,7 @@ namespace Azyobuzi.Twirunrun | ||
311 | 312 | { |
312 | 313 | string message; |
313 | 314 | Exception ex = |
314 | - exception.InnerException == null && exception.InnerException is TwitterQueryException | |
315 | + exception.InnerException == null && !(exception.InnerException is TwitterQueryException) | |
315 | 316 | ? exception : exception.InnerException; |
316 | 317 | var twitterex = ex as TwitterQueryException; |
317 | 318 | if (twitterex != null) |
@@ -390,8 +391,11 @@ namespace Azyobuzi.Twirunrun | ||
390 | 391 | private void us_NewTweet(object sender, NewTweetEventArgs e) |
391 | 392 | { |
392 | 393 | var newItem = new StatusInfo(e.Status); |
393 | - if (!RecentStatusesCollection.Instance.AsParallel().Contains(newItem)) | |
394 | - RecentStatusesCollection.Instance.Add(newItem); | |
394 | + lock (RecentStatusesCollection.Instance) | |
395 | + { | |
396 | + if (!RecentStatusesCollection.Instance.AsParallel().Contains(newItem)) | |
397 | + RecentStatusesCollection.Instance.Add(newItem); | |
398 | + } | |
395 | 399 | if (Settings.Instance.StreamingNotifyNewTweet) |
396 | 400 | NotifyNewItems(new[] { newItem }, "Streaming 新着"); |
397 | 401 | } |
@@ -399,8 +403,11 @@ namespace Azyobuzi.Twirunrun | ||
399 | 403 | private void us_NewDirectMessage(object sender, NewDirectMessageEventArgs e) |
400 | 404 | { |
401 | 405 | var newItem = new StatusInfo(e.DirectMessage); |
402 | - if (!RecentStatusesCollection.Instance.AsParallel().Contains(newItem)) | |
403 | - RecentStatusesCollection.Instance.Add(newItem); | |
406 | + lock (RecentStatusesCollection.Instance) | |
407 | + { | |
408 | + if (!RecentStatusesCollection.Instance.AsParallel().Contains(newItem)) | |
409 | + RecentStatusesCollection.Instance.Add(newItem); | |
410 | + } | |
404 | 411 | if (Settings.Instance.StreamingNotifyNewTweet) |
405 | 412 | NotifyNewItems(new[] { newItem }, "Streaming 新着DM"); |
406 | 413 | } |
@@ -414,5 +421,13 @@ namespace Azyobuzi.Twirunrun | ||
414 | 421 | { |
415 | 422 | this.Visible = true; |
416 | 423 | } |
424 | + | |
425 | + private void MainForm_BoundsChanged(object sender, EventArgs e) | |
426 | + { | |
427 | + if (this.WindowState == FormWindowState.Normal) | |
428 | + Settings.Instance.MainFormSetting = FormSettings.FromForm(this); | |
429 | + else | |
430 | + Settings.Instance.MainFormSetting.WindowState = this.WindowState; | |
431 | + } | |
417 | 432 | } |
418 | 433 | } |
@@ -743,6 +743,54 @@ namespace Azyobuzi.Twirunrun | ||
743 | 743 | return autoRestart; |
744 | 744 | } |
745 | 745 | } |
746 | + | |
747 | + | |
748 | + // | |
749 | + //MainFormの設定 | |
750 | + // | |
751 | + private FormSettings mainFormSetting = new FormSettings() | |
752 | + #region MainForm初期設定 | |
753 | + { | |
754 | + Bounds = new Rectangle(200, 200, 450, 500), | |
755 | + WindowState = FormWindowState.Normal | |
756 | + }; | |
757 | + #endregion | |
758 | + public FormSettings MainFormSetting | |
759 | + { | |
760 | + set | |
761 | + { | |
762 | + if (!mainFormSetting.Equals(value)) | |
763 | + { | |
764 | + mainFormSetting = value; | |
765 | + OnPropertyChanged("MainFormSetting"); | |
766 | + } | |
767 | + } | |
768 | + get | |
769 | + { | |
770 | + return mainFormSetting; | |
771 | + } | |
772 | + } | |
773 | + | |
774 | + | |
775 | + // | |
776 | + //@・#の履歴 | |
777 | + // | |
778 | + private List<string> atHashtagList = new List<string>(); | |
779 | + public List<string> AtHashtagList | |
780 | + { | |
781 | + set | |
782 | + { | |
783 | + if (!atHashtagList.SequenceEqual(value)) | |
784 | + { | |
785 | + atHashtagList = value; | |
786 | + OnPropertyChanged("AtHashtagList");//あんまり意味無い | |
787 | + } | |
788 | + } | |
789 | + get | |
790 | + { | |
791 | + return atHashtagList; | |
792 | + } | |
793 | + } | |
746 | 794 | } |
747 | 795 | |
748 | 796 | public class FormSettings : IEquatable<FormSettings> |
@@ -103,6 +103,12 @@ | ||
103 | 103 | <Compile Include="Controls\TwirunrunTabControl.cs"> |
104 | 104 | <SubType>Component</SubType> |
105 | 105 | </Compile> |
106 | + <Compile Include="Controls\UpdateStatusTextBox.cs"> | |
107 | + <SubType>UserControl</SubType> | |
108 | + </Compile> | |
109 | + <Compile Include="Controls\UpdateStatusTextBox.Designer.cs"> | |
110 | + <DependentUpon>UpdateStatusTextBox.cs</DependentUpon> | |
111 | + </Compile> | |
106 | 112 | <Compile Include="DynamicScriptObject.cs" /> |
107 | 113 | <Compile Include="Events.cs" /> |
108 | 114 | <Compile Include="Extensions.cs" /> |
@@ -231,6 +237,9 @@ | ||
231 | 237 | <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
232 | 238 | </Content> |
233 | 239 | <Content Include="lib\UserStreamEx.XML" /> |
240 | + <EmbeddedResource Include="Controls\UpdateStatusTextBox.resx"> | |
241 | + <DependentUpon>UpdateStatusTextBox.cs</DependentUpon> | |
242 | + </EmbeddedResource> | |
234 | 243 | <EmbeddedResource Include="Forms\MainForm.resx"> |
235 | 244 | <DependentUpon>MainForm.cs</DependentUpon> |
236 | 245 | </EmbeddedResource> |