• R/O
  • SSH
  • HTTPS

kuon: 提交


Commit MetaInfo

修訂303 (tree)
時間2010-01-16 11:53:09
作者catwalk

Log Message

2010

Change Summary

差異

--- kuon/trunk/Kuon.cs (revision 302)
+++ kuon/trunk/Kuon.cs (revision 303)
@@ -246,6 +246,7 @@
246246
247247 commandLine = null;
248248 CoreConfigs.General.FirstBoot = false;
249+
249250 System.Windows.Forms.Application.Run();
250251
251252 return 0;
--- kuon/trunk/Forms/StatusBar.cs (revision 302)
+++ kuon/trunk/Forms/StatusBar.cs (revision 303)
@@ -86,8 +86,9 @@
8686 this.Control.BeginInvoke(new Action<object>(this.Start), id);
8787 }else{
8888 this.Reports.Add(id, 0);
89- this.Visible = true;
90- this.Text = "0 %";
89+ if(!(this.Visible)){
90+ this.Visible = true;
91+ }
9192 }
9293 }
9394
--- kuon/trunk/Core/OutputPanel.cs (revision 302)
+++ kuon/trunk/Core/OutputPanel.cs (revision 303)
@@ -78,6 +78,7 @@
7878 if(this.InvokeRequired){
7979 this.BeginInvoke(new Action<string>(this.WriteLine), str);
8080 }else if(!(this.IsDisposed) && (this.IsHandleCreated)){
81+ this.BeginUpdate();
8182 foreach(string line in str.Split('\n')){
8283 if(this.trimWriteLine && String.IsNullOrEmpty(line.Trim())){
8384 continue;
@@ -86,6 +87,7 @@
8687 this.CutLines();
8788 this.ScrollToBottom();
8889 }
90+ this.EndUpdate();
8991 }
9092 }
9193
@@ -97,6 +99,7 @@
9799 if(this.InvokeRequired){
98100 this.BeginInvoke(new Action<string, Color>(this.WriteLine), str, color);
99101 }else if(!(this.IsDisposed) && (this.IsHandleCreated)){
102+ this.BeginUpdate();
100103 foreach(string line in str.Split('\n')){
101104 if(this.trimWriteLine && String.IsNullOrEmpty(line.Trim())){
102105 continue;
@@ -105,6 +108,7 @@
105108 this.CutLines();
106109 this.ScrollToBottom();
107110 }
111+ this.EndUpdate();
108112 }
109113 }
110114
@@ -112,7 +116,8 @@
112116 if(this.InvokeRequired){
113117 this.BeginInvoke(new Action<string>(this.Write), str);
114118 }else if(!(this.IsDisposed) && (this.IsHandleCreated)){
115- int i = 0;
119+ this.BeginUpdate();
120+ int i = 0;
116121 foreach(string line in str.Split('\n')){
117122 if(this.trimWriteLine && String.IsNullOrEmpty(line.Trim())){
118123 continue;
@@ -130,6 +135,7 @@
130135 }
131136 i++;
132137 }
138+ this.EndUpdate();
133139 }
134140 }
135141
@@ -137,6 +143,7 @@
137143 if(this.InvokeRequired){
138144 this.BeginInvoke(new Action<string, Color>(this.Write), str, color);
139145 }else if(!(this.IsDisposed) && (this.IsHandleCreated)){
146+ this.BeginUpdate();
140147 int i = 0;
141148 foreach(string line in str.Split('\n')){
142149 if(this.trimWriteLine && String.IsNullOrEmpty(line.Trim())){
@@ -155,6 +162,7 @@
155162 }
156163 i++;
157164 }
165+ this.EndUpdate();
158166 }
159167 }
160168
--- kuon/trunk/Core/ReplacementMacro.cs (revision 302)
+++ kuon/trunk/Core/ReplacementMacro.cs (revision 303)
@@ -192,6 +192,8 @@
192192 return Resource.Path.ScriptDirectory;
193193 case "configdir":
194194 return Resource.Path.ConfigDirectory;
195+ case "resourcedir":
196+ return Resource.Path.ResourceDirectory;
195197 case "defaultconfigdir":
196198 return Resource.Path.DefaultConfigDirectory;
197199 case "specialfolder":
--- kuon/trunk/Core/MenuCreator.cs (revision 302)
+++ kuon/trunk/Core/MenuCreator.cs (revision 303)
@@ -6,6 +6,7 @@
66 using System.Collections.Generic;
77 using System.Collections.ObjectModel;
88 using System.Drawing;
9+using System.IO;
910 using System.Windows.Forms;
1011 using System.Xml;
1112 using System.Xml.Schema;
@@ -38,11 +39,22 @@
3839 Image image = null;
3940 ToolStripMenuItem menuItem;
4041 if(!(String.IsNullOrEmpty(item.ImagePath))){
42+ string path = ReplacementMacro.Expand(item.ImagePath);
4143 try{
42- image = Image.FromFile(item.ImagePath);
44+ using(FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)){
45+ image = Image.FromStream(stream);
46+ stream.Close();
47+ }
4348 }catch(Exception ex){
44- MessageBox.Show(ex.Message + "\n" + item.ImagePath, ApplicationInfo.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
49+ MessageBox.Show(ex.Message + "\n" + path, ApplicationInfo.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
4550 }
51+ }else if(!(String.IsNullOrEmpty(item.IconPath))){
52+ string path = ReplacementMacro.Expand(item.IconPath);
53+ try{
54+ image = (new Icon(path, new Size(16, 16))).ToBitmap();
55+ }catch(Exception ex){
56+ MessageBox.Show(ex.Message + "\n" + path, ApplicationInfo.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
57+ }
4658 }
4759 if(String.IsNullOrEmpty(item.Action)){
4860 menuItem = new ToolStripMenuItem(item.Text, image);
@@ -140,6 +152,17 @@
140152 }
141153 }
142154
155+ private string iconPath = null;
156+ [XmlAttribute("icon")]
157+ public string IconPath{
158+ get{
159+ return this.iconPath;
160+ }
161+ set{
162+ this.iconPath = value;
163+ }
164+ }
165+
143166 private ContentAlignment textAlign = ContentAlignment.MiddleCenter;
144167 [XmlAttribute("align")]
145168 public ContentAlignment TextAlign{
--- kuon/trunk/Modules/Filer/Filer.cs (revision 302)
+++ kuon/trunk/Modules/Filer/Filer.cs (revision 303)
@@ -25,8 +25,8 @@
2525
2626 private const string unknownString = "unknown";
2727 private FolderView folderView;
28- private AddressBarControl addressBar = new AddressBarControl();
29- private StatusBarControl statusBar = new StatusBarControl();
28+ private AddressBarControl addressBar;
29+ private StatusBarControl statusBar;
3030 private string volumeLabel = unknownString;
3131 private string usingSpaceString = unknownString;
3232 private decimal freeSpace = 0;
@@ -54,8 +54,6 @@
5454 }
5555
5656 this.SuspendLayout();
57- this.Dock = DockStyle.Fill;
58- this.BorderStyle = BorderStyle.FixedSingle;
5957 if(FilerModule.FilerOption.FilerFont != null){
6058 this.Font = FilerModule.FilerOption.FilerFont.GetFont();
6159 }else{
@@ -62,10 +60,11 @@
6260 this.Font = SystemFonts.MessageBoxFont;
6361 }
6462
65- this.statusBar.ShowDiskUsageGraph = FilerModule.FilerOption.ShowDiskUsageGraph;
66-
6763 this.folderView = new FolderView(path);
6864 this.folderView.BorderStyle = BorderStyle.None;
65+ this.statusBar = new StatusBarControl(this.folderView);
66+ this.statusBar.ShowDiskUsageGraph = FilerModule.FilerOption.ShowDiskUsageGraph;
67+ this.addressBar = new AddressBarControl(this.folderView);
6968 this.RefreshAddressBar();
7069 this.RefreshDriveInfo();
7170 this.RefreshStatusBar();
@@ -193,7 +192,12 @@
193192
194193 private void AutoRefreshMessageProcessQueueEventListener(object sender, EventArgs e){
195194 while(this.autoRefreshMessageQueueServer.Queue.Count > 0){
196- MainForm.Instance.Output.WriteLine(this.autoRefreshMessageQueueServer.Queue.Dequeue());
195+ List<string> items = new List<string>();
196+ foreach(string item in this.autoRefreshMessageQueueServer.Queue){
197+ items.AddRange(item.Split('\n'));
198+ }
199+ MainForm.Instance.Output.Items.AddRange(items.ToArray());
200+ MainForm.Instance.Output.LimitLines = MainForm.Instance.Output.LimitLines;
197201 }
198202 }
199203
@@ -498,6 +502,15 @@
498502 this.folderView.CalculateDirectoryFileSize(mode);
499503 }
500504
505+ public History<string> History{
506+ get{
507+ return this.folderView.History;
508+ }
509+ set{
510+ this.folderView.History = value;
511+ }
512+ }
513+
501514 protected override void Dispose(bool disposing){
502515 if(!(this.disposed)){
503516 this.container.Dispose();
@@ -704,6 +717,9 @@
704717 get{
705718 return this.folderView.BackHistory;
706719 }
720+ set{
721+ this.folderView.BackHistory = value;
722+ }
707723 }
708724
709725 public string[] ForwardHistory{
@@ -710,6 +726,9 @@
710726 get{
711727 return this.folderView.ForwardHistory;
712728 }
729+ set{
730+ this.folderView.ForwardHistory = value;
731+ }
713732 }
714733
715734 public bool Activated{
@@ -883,7 +902,11 @@
883902 #region 内部クラス
884903
885904 private class AddressBarControl : TextBox{
886- public AddressBarControl(){
905+ private FolderView folderView;
906+
907+ public AddressBarControl(FolderView folderView){
908+ this.folderView = folderView;
909+
887910 this.BackColor = Color.FromKnownColor(KnownColor.Control);
888911 this.BorderStyle = BorderStyle.None;
889912 this.ReadOnly = true;
@@ -890,6 +913,11 @@
890913 this.Dock = DockStyle.Top;
891914 this.Multiline = false;
892915 this.TabStop = false;
916+ this.Font = SystemFonts.CaptionFont;
917+
918+ this.Click += delegate{
919+ this.folderView.Focus();
920+ };
893921 }
894922
895923 public void Highlight(){
@@ -905,15 +933,21 @@
905933
906934 private class StatusBarControl : StatusStrip{
907935 private ToolStripStatusLabel label = new ToolStripStatusLabel();
908- private ToolStripStatusLabel filterIcon = new ToolStripStatusLabel();
909- private ToolStripStatusLabel navLockIcon = new ToolStripStatusLabel();
936+ private ToolStripButton filterIcon = new ToolStripButton();
937+ private ToolStripButton navLockIcon = new ToolStripButton();
910938 private ToolStripButton driveNameControl = new ToolStripButton();
911939 private ToolStripStatusLabel driveUsingSpaceLabel = new ToolStripStatusLabel();
912940 private ToolStripStatusLabel driveFreeSpaceLabel = new ToolStripStatusLabel();
913941 //private ToolStripStatusLabel driveTotalSpaceLabel = new ToolStripStatusLabel();
914942 private ToolStripProgressBar driveUsageBar = new ToolStripProgressBar();
943+ private FolderView folderView;
915944
916- public StatusBarControl(){
945+ public StatusBarControl(FolderView folderView){
946+ this.folderView = folderView;
947+ this.Click += delegate{
948+ this.folderView.Focus();
949+ };
950+
917951 this.GripStyle = ToolStripGripStyle.Hidden;
918952 this.SizingGrip = false;
919953
@@ -922,13 +956,17 @@
922956 this.Items.Add(this.label);
923957
924958 this.filterIcon.Text = "";
925- this.filterIcon.Visible = false;
926- this.filterIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, Resource.Path.FilterIcon), IconSize.Small);
959+ this.filterIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Unfilter.ico"), IconSize.Small);
960+ this.filterIcon.Click += delegate{
961+ Kuon.Filer.FilerModule.SetFileFilter();
962+ };
927963 this.Items.Add(this.filterIcon);
928964
929965 this.navLockIcon.Text = "";
930- this.navLockIcon.Visible = false;
931- this.navLockIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, Resource.Path.LockIcon), IconSize.Small);
966+ this.navLockIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Unlock.ico"), IconSize.Small);
967+ this.navLockIcon.Click += delegate{
968+ Kuon.Filer.FilerModule.ToggleNavigation();
969+ };
932970 this.Items.Add(this.navLockIcon);
933971
934972 this.driveNameControl.Click += delegate{
@@ -945,6 +983,7 @@
945983 //this.driveTotalSpaceLabel.TextAlign = ContentAlignment.MiddleLeft;
946984 //this.Items.Add(this.driveTotalSpaceLabel);
947985
986+ this.driveUsageBar.Width = 100;
948987 this.driveUsageBar.Alignment = ToolStripItemAlignment.Right;
949988 this.driveUsageBar.Maximum = 100;
950989 this.driveUsageBar.Minimum = 0;
@@ -968,7 +1007,11 @@
9681007 return this.filterIcon.Visible;
9691008 }
9701009 set{
971- this.filterIcon.Visible = value;
1010+ if(value){
1011+ this.filterIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Filter.ico"), IconSize.Small);
1012+ }else{
1013+ this.filterIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Unfilter.ico"), IconSize.Small);
1014+ }
9721015 }
9731016 }
9741017
@@ -978,7 +1021,11 @@
9781021 return this.navLockIcon.Visible;
9791022 }
9801023 set{
981- this.navLockIcon.Visible = value;
1024+ if(value){
1025+ this.navLockIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Lock.ico"), IconSize.Small);
1026+ }else{
1027+ this.navLockIcon.Image = Shell.GetIconImage(StringEx.JoinPath(Resource.Path.ResourceDirectory, "Unlock.ico"), IconSize.Small);
1028+ }
9821029 }
9831030 }
9841031
@@ -1050,15 +1097,25 @@
10501097 }
10511098 }
10521099
1053- public class ToolStripGraphBar : ToolStripProgressBar{
1100+ public class ToolStripGraphBar : ToolStripLabel{
1101+ private int value;
1102+
10541103 public ToolStripGraphBar(){
1055-
10561104 }
10571105
1106+ public int Value{
1107+ get{
1108+ return this.value;
1109+ }
1110+ set{
1111+ this.value = value;
1112+ }
1113+ }
1114+
10581115 protected override void OnPaint(PaintEventArgs e){
1059- using(Pen rectPen = new Pen(SystemColors.WindowFrame))
1060- using(Pen graphPen = new Pen(SystemColors.MenuHighlight))
1061- using(Pen backgroundPen = new Pen(SystemColors.Menu)){
1116+ using(Pen rectPen = new Pen(SystemColors.Highlight))
1117+ using(Pen graphPen = new Pen(SystemColors.Highlight))
1118+ using(Pen backgroundPen = new Pen(SystemColors.Control)){
10621119 e.Graphics.DrawRectangle(backgroundPen, e.ClipRectangle);
10631120 e.Graphics.DrawLines(rectPen, new Point[]{
10641121 new Point(e.ClipRectangle.Left, e.ClipRectangle.Top),
@@ -1066,6 +1123,12 @@
10661123 new Point(e.ClipRectangle.Right, e.ClipRectangle.Bottom),
10671124 new Point(e.ClipRectangle.Right, e.ClipRectangle.Top),
10681125 new Point(e.ClipRectangle.Left, e.ClipRectangle.Top)});
1126+ e.Graphics.DrawRectangle(graphPen, new Rectangle(
1127+ e.ClipRectangle.Left,
1128+ e.ClipRectangle.Top,
1129+ e.ClipRectangle.Left + (e.ClipRectangle.Width * 100 / this.value),
1130+ e.ClipRectangle.Bottom
1131+ ));
10691132 }
10701133 }
10711134 }
--- kuon/trunk/Modules/Filer/DoubleWindowFiler.cs (revision 302)
+++ kuon/trunk/Modules/Filer/DoubleWindowFiler.cs (revision 303)
@@ -8,6 +8,7 @@
88 using System.Windows.Forms;
99 using Kuon;
1010 using Kuon.Forms;
11+using Kuon.Utilities;
1112
1213 namespace Kuon.Filer{
1314 public class DoubleWindowFiler : SplitContainer{
@@ -26,7 +27,7 @@
2627 #region コンストラクタ
2728
2829 public DoubleWindowFiler(ConfigFilerForm data){
29- this.Initialize(data.LeftFilerPath, data.RightFilerPath, data.LeftNavigationLockPath, data.RightNavigationLockPath);
30+ this.Initialize(data);
3031 }
3132
3233 #endregion
@@ -33,23 +34,42 @@
3334
3435 #region 関数
3536
36- private void Initialize(string leftFilerPath, string rightFilerPath, string leftNavigationLockPath, string rightNavigationLockPath){
37- if((leftFilerPath == null) || (rightFilerPath == null)){
38- throw new ArgumentNullException();
37+ private void Initialize(ConfigFilerForm data){
38+ if(data.LeftFilerPath == null){
39+ data.LeftFilerPath = Environment.CurrentDirectory;
3940 }
41+ if(data.RightFilerPath == null){
42+ data.RightFilerPath = Environment.CurrentDirectory;
43+ }
4044
4145 this.SuspendLayout();
4246
4347 // Filer
44- this.leftFiler = new FilerControl(leftFilerPath);
45- this.rightFiler = new FilerControl(rightFilerPath);
48+ this.leftFiler = new FilerControl(data.LeftFilerPath);
49+ this.rightFiler = new FilerControl(data.RightFilerPath);
50+ this.leftFiler.BorderStyle = BorderStyle.FixedSingle;
51+ this.rightFiler.BorderStyle = BorderStyle.FixedSingle;
52+ this.leftFiler.Dock = DockStyle.Fill;
53+ this.rightFiler.Dock = DockStyle.Fill;
54+ if(data.LeftBackHistory != null){
55+ this.leftFiler.BackHistory = data.LeftBackHistory;
56+ }
57+ if(data.RightBackHistory != null){
58+ this.rightFiler.BackHistory = data.RightBackHistory;
59+ }
60+ if(data.LeftForwardHistory != null){
61+ this.leftFiler.ForwardHistory = data.LeftForwardHistory;
62+ }
63+ if(data.RightForwardHistory != null){
64+ this.rightFiler.ForwardHistory = data.RightForwardHistory;
65+ }
4666 this.container.Add(this.leftFiler);
4767 this.container.Add(this.rightFiler);
48- if(!(String.IsNullOrEmpty(leftNavigationLockPath))){
49- this.leftFiler.NavigationLockPath = leftNavigationLockPath;
68+ if(!(String.IsNullOrEmpty(data.LeftNavigationLockPath))){
69+ this.leftFiler.NavigationLockPath = data.LeftNavigationLockPath;
5070 }
51- if(!(String.IsNullOrEmpty(rightNavigationLockPath))){
52- this.rightFiler.NavigationLockPath = rightNavigationLockPath;
71+ if(!(String.IsNullOrEmpty(data.RightNavigationLockPath))){
72+ this.rightFiler.NavigationLockPath = data.RightNavigationLockPath;
5373 }
5474
5575 this.Orientation = FilerModule.FilerOption.Orientation;
--- kuon/trunk/Modules/Filer/FilerForm.cs (revision 302)
+++ kuon/trunk/Modules/Filer/FilerForm.cs (revision 303)
@@ -278,6 +278,10 @@
278278 this.RightFilerPath = filerForm.DoubleWindowFiler.RightFiler.Path + IO.Path.DirectorySeparatorChar;
279279 this.LeftNavigationLockPath = filerForm.DoubleWindowFiler.LeftFiler.NavigationLockPath;
280280 this.RightNavigationLockPath = filerForm.DoubleWindowFiler.RightFiler.NavigationLockPath;
281+ this.LeftBackHistory = filerForm.DoubleWindowFiler.LeftFiler.History.BackHistory;
282+ this.RightBackHistory = filerForm.DoubleWindowFiler.RightFiler.History.BackHistory;
283+ this.LeftForwardHistory = filerForm.DoubleWindowFiler.LeftFiler.History.ForwardHistory;
284+ this.RightForwardHistory = filerForm.DoubleWindowFiler.RightFiler.History.ForwardHistory;
281285 }
282286
283287 public override Form Restore(Form parent, bool isAddWindowBar){
@@ -323,5 +327,46 @@
323327 this.rightNavigationLockPath = value;
324328 }
325329 }
330+
331+ private string[] leftBackHistory = null;
332+ public string[] LeftBackHistory{
333+ get{
334+ return this.leftBackHistory;
335+ }
336+ set{
337+ this.leftBackHistory = value;
338+ }
339+ }
340+
341+ private string[] rightBackHistory = null;
342+ public string[] RightBackHistory{
343+ get{
344+ return this.rightBackHistory;
345+ }
346+ set{
347+ this.rightBackHistory = value;
348+ }
349+ }
350+
351+
352+ private string[] leftForwardHistory = null;
353+ public string[] LeftForwardHistory{
354+ get{
355+ return this.leftForwardHistory;
356+ }
357+ set{
358+ this.leftForwardHistory = value;
359+ }
360+ }
361+
362+ private string[] rightForwardHistory = null;
363+ public string[] RightForwardHistory{
364+ get{
365+ return this.rightForwardHistory;
366+ }
367+ set{
368+ this.rightForwardHistory = value;
369+ }
370+ }
326371 }
327372 }
\ No newline at end of file
--- kuon/trunk/Modules/Filer/FolderView.cs (revision 302)
+++ kuon/trunk/Modules/Filer/FolderView.cs (revision 303)
@@ -43,7 +43,7 @@
4343 private LogicalOperation fileFilterMode = LogicalOperation.Or;
4444 private readonly FileFilterCollection fileFilters = new FileFilterCollection();
4545 private readonly FileInfoProvider directory = new Directory(4096 * FilerModule.FilerOption.WatcherBufferSize);
46- private readonly History<string> history = new History<string>(FilerModule.FilerOption.HistoryCount);
46+ private History<string> history = new History<string>(FilerModule.FilerOption.HistoryCount);
4747 private readonly IContainer container = new Container();
4848 private readonly static object StaticSyncObject = new object();
4949 private string fileMask = "*.*";
@@ -53,6 +53,8 @@
5353 private BackgroundWorker autoRefreshWorker = new BackgroundWorker();
5454 private Queue<IO.FileSystemEventArgs> autoRefreshQueue = new Queue<IO.FileSystemEventArgs>();
5555 private Queue<IO.FileSystemEventArgs> autoRefreshEvents = new Queue<IO.FileSystemEventArgs>();
56+ private Queue<GetInfoItem> getInfoQueue = new Queue<GetInfoItem>();
57+ private BackgroundWorker infoWorker = new BackgroundWorker();
5658
5759 /*
5860 ImageList.ImageCollectionのキーについて。
@@ -86,8 +88,6 @@
8688 //private const int DownImageIndex = 1;
8789 private static readonly DelayProcess incrementWatcherBufferSizeDelayProcess = new DelayProcess();
8890 private static readonly ContextMenuStrip contextMenuStrip;
89- private static Queue<GetInfoItem> getInfoQueue = new Queue<GetInfoItem>();
90- private static BackgroundWorker infoWorker = new BackgroundWorker();
9191
9292 #endregion
9393
@@ -138,12 +138,6 @@
138138 MessageBox.Show(ex.Message);
139139 }
140140
141- infoWorker.WorkerReportsProgress = true;
142- infoWorker.WorkerSupportsCancellation = true;
143- infoWorker.DoWork += new DoWorkEventHandler(GetInfo_DoWork);
144- infoWorker.ProgressChanged += new ProgressChangedEventHandler(GetInfo_ProgressChanged);
145- infoWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(GetInfo_RunWorkerCompleted);
146-
147141 AppDomain.CurrentDomain.ProcessExit += ProcessExitEventListener;
148142 }
149143
@@ -166,9 +160,10 @@
166160 if(!(String.IsNullOrEmpty(FilerModule.FilerOption.BackgroundImage))){
167161 try{
168162 this.BackColor = Color.Empty;
169- IO.FileStream stream = new IO.FileStream(FilerModule.FilerOption.BackgroundImage, IO.FileMode.Open, IO.FileAccess.Read);
170- this.BackgroundImage = Image.FromStream(stream);
171- stream.Close();
163+ using(IO.FileStream stream = new IO.FileStream(FilerModule.FilerOption.BackgroundImage, IO.FileMode.Open, IO.FileAccess.Read)){
164+ this.BackgroundImage = Image.FromStream(stream);
165+ stream.Close();
166+ }
172167 this.BackgroundImageTiled = FilerModule.FilerOption.BackgroundImageTiled;
173168 }catch(Exception ex){
174169 this.BackgroundImage = null;
@@ -191,7 +186,8 @@
191186 this.LabelEdit = false;
192187 this.LabelWrap = true;
193188 this.MultiSelect = true;
194- this.ShowItemToolTips = FilerModule.FilerOption.ShowItemToolTips;
189+ base.ShowItemToolTips = true;
190+ this.showItemToolTips = FilerModule.FilerOption.ShowItemToolTips;
195191 //this.OwnerDraw = true;
196192 //this.SetStyle(ControlStyles.UserPaint, true);
197193 this.View = FilerModule.FilerOption.ViewStyle;
@@ -230,6 +226,12 @@
230226 this.autoRefreshWorker.WorkerSupportsCancellation = true;
231227 this.autoRefreshWorker.WorkerReportsProgress = true;
232228
229+ this.infoWorker.WorkerReportsProgress = true;
230+ this.infoWorker.WorkerSupportsCancellation = true;
231+ this.infoWorker.DoWork += new DoWorkEventHandler(GetInfo_DoWork);
232+ this.infoWorker.ProgressChanged += new ProgressChangedEventHandler(GetInfo_ProgressChanged);
233+ this.infoWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(GetInfo_RunWorkerCompleted);
234+
233235 // 自動更新
234236 this.container.Add(this.directory);
235237 this.directory.Changed += this.DirectoryChangedEventListener;
@@ -273,6 +275,7 @@
273275 lock(this.autoRefreshQueue){
274276 if(!(this.autoRefreshWorker.IsBusy) && (this.autoRefreshQueue.Count > 0) && (this.directory.EnableRaisingEvents)){
275277 MainForm.Instance.StatusBar.Progress.Start(this.autoRefreshWorker);
278+ this.Cursor = Cursors.AppStarting;
276279 this.autoRefreshWorker.RunWorkerAsync();
277280 }
278281 }
@@ -434,7 +437,7 @@
434437 List<ListViewItem> items = new List<ListViewItem>(state.FilesToAdd.Count);
435438 lock(this.itemDictionary){
436439 foreach(var elm in state.FilesToAdd){
437- lock(getInfoQueue){
440+ lock(this.getInfoQueue){
438441 if(this.fileFilters.Count > 0){
439442 if(!(this.fileFilters.IsMatch(elm.Value.Info, this.fileFilterMode))){
440443 continue;
@@ -453,7 +456,7 @@
453456 var infoItem = new GetInfoItem(item, InfoType.Icon, null);
454457 infoItem.UseSimpleIcon = this.useSimpleIcon;
455458 infoItem.UseSmallIcon = this.UseSmallIcon;
456- getInfoQueue.Enqueue(infoItem);
459+ this.getInfoQueue.Enqueue(infoItem);
457460 }
458461 }
459462 if(elm.Value.State != null){
@@ -513,6 +516,9 @@
513516
514517 private void AutoRefreshWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
515518 MainForm.Instance.StatusBar.Progress.Complete(this.autoRefreshWorker);
519+ if(!(this.infoWorker.IsBusy || this.listWorker.IsBusy)){
520+ this.Cursor = Cursors.Default;
521+ }
516522 this.StartAutoRefreshWorker();
517523 }
518524
@@ -707,11 +713,7 @@
707713 this.List(0, focusedItemText);
708714 }
709715
710- private Stopwatch sw = new Stopwatch();
711-
712716 private void List(int focusedItemIndex, string focusedItemText){
713- this.sw.Reset();
714- this.sw.Start();
715717 lock(this.autoRefreshQueue){
716718 this.autoRefreshQueue.Clear();
717719 this.autoRefreshWorker.CancelAsync();
@@ -724,6 +726,7 @@
724726 }
725727
726728 MainForm.Instance.StatusBar.Progress.Start(this.listWorker);
729+ this.Cursor = Cursors.AppStarting;
727730
728731 this.BeginUpdate();
729732
@@ -742,9 +745,6 @@
742745
743746 this.EndUpdate();
744747
745- this.sw.Stop();
746- MainForm.AddOutput(this.path + " : Initializing : " + this.sw.ElapsedMilliseconds);
747-
748748 if(!(focusedItemText.IsNullOrEmpty())){
749749 focusedItemIndex = -1;
750750 }
@@ -753,18 +753,12 @@
753753
754754 private void ListWorker_DoWork(object sender, DoWorkEventArgs e){
755755 try{
756- this.sw.Reset();
757- this.sw.Start();
758756 ListWorkerArgument arg = (ListWorkerArgument)e.Argument;
759757 e.Result = arg;
760758 this.directory.Refresh();
761- this.sw.Stop();
762- MainForm.AddOutput(this.path + " : Listing : " + this.sw.ElapsedMilliseconds);
763759
764760
765761 if(!(this.listWorker.CancellationPending)){
766- this.sw.Reset();
767- this.sw.Start();
768762 List<FileInfo> infos = new List<FileInfo>();
769763 foreach(FileInfo info in this.directory){
770764 if(
@@ -773,29 +767,19 @@
773767 infos.Add(info);
774768 }
775769 }
776- this.sw.Stop();
777- MainForm.AddOutput(this.path + " : Filtering : " + this.sw.ElapsedMilliseconds);
778770
779771 infos.Sort(((ListViewItemComparer)this.ListViewItemSorter).Comparer);
780772
781- this.sw.Reset();
782- this.sw.Start();
783773 arg.Items = new ListViewItem[infos.Count];
784774 arg.ItemList = new List<ListViewItem>();
785- Stopwatch sw2 = new Stopwatch();
786- sw2.Reset();
787- sw2.Start();
788775 for(int i = 0; i < infos.Count; i++){
789776 ListViewItem item = this.BuildItem(infos[i]);
790777 arg.Items[i] = item;
791778 arg.ItemList.Add(item);
792779 }
793- sw2.Stop();
794780 if(arg.ItemList.Count > 0){
795781 this.listWorker.ReportProgress(100, new ListWorkerProgress(arg.FocusedItemIndex, arg.FocusedItemText, arg.ItemList, arg.Items));
796782 }
797- this.sw.Stop();
798- MainForm.AddOutput(this.path + " : Building : " + this.sw.ElapsedMilliseconds);
799783 }else{
800784 e.Cancel = true;
801785 }
@@ -805,8 +789,6 @@
805789 }
806790
807791 private void ListWorker_ProgressChanged(object sender, ProgressChangedEventArgs e){
808- this.sw.Reset();
809- this.sw.Start();
810792 ListWorkerProgress arg = (ListWorkerProgress)e.UserState;
811793
812794 MainForm.Instance.StatusBar.Progress.Report(this.listWorker, e.ProgressPercentage);
@@ -814,7 +796,7 @@
814796 this.BeginUpdate();
815797 ListViewItem focusedItem = null;
816798 lock(this.itemDictionary){
817- lock(getInfoQueue){
799+ lock(this.getInfoQueue){
818800 foreach(ListViewItem item in arg.ItemList){
819801 if(!(String.IsNullOrEmpty(arg.FocusedItemText)) && (StringComparer.OrdinalIgnoreCase.Equals(item.Text, arg.FocusedItemText))){
820802 focusedItem = item;
@@ -827,7 +809,7 @@
827809 var infoItem = new GetInfoItem(item, InfoType.Icon, null);
828810 infoItem.UseSimpleIcon = this.useSimpleIcon;
829811 infoItem.UseSmallIcon = this.UseSmallIcon;
830- getInfoQueue.Enqueue(infoItem);
812+ this.getInfoQueue.Enqueue(infoItem);
831813 }
832814 }
833815 this.itemDictionary.Add(item.Name, item);
@@ -844,8 +826,6 @@
844826 }
845827
846828 this.EndUpdate();
847- this.sw.Stop();
848- MainForm.AddOutput(this.path + " : Adding : " + this.sw.ElapsedMilliseconds);
849829
850830 StartGetInfoServer();
851831 }
@@ -852,6 +832,9 @@
852832
853833 private void ListWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
854834 MainForm.Instance.StatusBar.Progress.Complete(this.listWorker);
835+ if(!(this.infoWorker.IsBusy || this.autoRefreshWorker.IsBusy)){
836+ this.Cursor = Cursors.Default;
837+ }
855838 this.directory.EnableRaisingEvents = true;
856839 }
857840
@@ -946,13 +929,13 @@
946929 subItem.Tag = column.Tag;
947930 switch((FolderViewColumn)column.Tag){
948931 case FolderViewColumn.OwnerName:
949- lock(getInfoQueue){
950- getInfoQueue.Enqueue(new GetInfoItem(item, InfoType.OwnerName, subItem));
932+ lock(this.getInfoQueue){
933+ this.getInfoQueue.Enqueue(new GetInfoItem(item, InfoType.OwnerName, subItem));
951934 }
952935 break;
953936 case FolderViewColumn.FileRights:{
954- lock(getInfoQueue){
955- getInfoQueue.Enqueue(new GetInfoItem(item, InfoType.FileRights, subItem));
937+ lock(this.getInfoQueue){
938+ this.getInfoQueue.Enqueue(new GetInfoItem(item, InfoType.FileRights, subItem));
956939 }
957940 break;
958941 }
@@ -963,8 +946,10 @@
963946 item.Name = info.Name;
964947 item.Tag = info;
965948
966- if(this.ShowItemToolTips){
949+ if(this.showItemToolTips){
967950 item.ToolTipText = GetToolTipText(info);
951+ }else{
952+ item.ToolTipText = item.Text;
968953 }
969954
970955 // アイコン
@@ -1189,16 +1174,17 @@
11891174 return sb.ToString();
11901175 }
11911176
1192- private static void StartGetInfoServer(){
1193- lock(getInfoQueue){
1194- if((getInfoQueue.Count > 0) && !(infoWorker.IsBusy)){
1195- MainForm.Instance.StatusBar.Progress.Start(infoWorker);
1177+ private void StartGetInfoServer(){
1178+ lock(this.getInfoQueue){
1179+ if((this.getInfoQueue.Count > 0) && !(infoWorker.IsBusy)){
1180+ MainForm.Instance.StatusBar.Progress.Start(this.infoWorker);
1181+ this.Cursor = Cursors.AppStarting;
11961182 infoWorker.RunWorkerAsync();
11971183 }
11981184 }
11991185 }
12001186
1201- private static void GetInfo_DoWork(object sender, DoWorkEventArgs e){
1187+ private void GetInfo_DoWork(object sender, DoWorkEventArgs e){
12021188 try{
12031189 Stopwatch sw = new Stopwatch();
12041190 sw.Reset();
@@ -1206,9 +1192,9 @@
12061192 List<GetInfoItem> list = new List<GetInfoItem>();
12071193 do{
12081194 GetInfoItem item;
1209- lock(getInfoQueue){
1210- if(getInfoQueue.Count > 0){
1211- item = getInfoQueue.Dequeue();
1195+ lock(this.getInfoQueue){
1196+ if(this.getInfoQueue.Count > 0){
1197+ item = this.getInfoQueue.Dequeue();
12121198 }else{
12131199 break;
12141200 }
@@ -1258,7 +1244,7 @@
12581244 }
12591245 }
12601246
1261- private static void GetInfo_ProgressChanged(object sender, ProgressChangedEventArgs e){
1247+ private void GetInfo_ProgressChanged(object sender, ProgressChangedEventArgs e){
12621248 GetInfoItem[] items = (GetInfoItem[])e.UserState;
12631249
12641250 foreach(GetInfoItem item in items){
@@ -1289,8 +1275,11 @@
12891275 MainForm.Instance.StatusBar.Progress.Report(infoWorker, e.ProgressPercentage);
12901276 }
12911277
1292- private static void GetInfo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
1278+ private void GetInfo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
12931279 MainForm.Instance.StatusBar.Progress.Complete(infoWorker);
1280+ if(!(this.autoRefreshWorker.IsBusy || this.listWorker.IsBusy)){
1281+ this.Cursor = Cursors.Default;
1282+ }
12941283 StartGetInfoServer();
12951284 }
12961285
@@ -1908,7 +1897,7 @@
19081897
19091898 private bool ReuseHistory(string dir, int reuseHistoryCount, ref string name){
19101899 int i = 0;
1911- foreach(string history in this.history.BackStack){
1900+ foreach(string history in this.history.BackHistory){
19121901 if(reuseHistoryCount < ++i){
19131902 break;
19141903 }
@@ -1917,12 +1906,14 @@
19171906 name = IO.Path.GetFileName(history);
19181907 }
19191908 this.history.Current = this.FocusedFile ?? this.path;
1920- this.history.Back(i);
1909+ for(int j = 0; j < i; j++){
1910+ this.history.Back();
1911+ }
19211912 return true;
19221913 }
19231914 }
19241915 i = 0;
1925- foreach(string history in this.history.ForwardStack){
1916+ foreach(string history in this.history.ForwardHistory){
19261917 if(reuseHistoryCount < ++i){
19271918 break;
19281919 }
@@ -1931,7 +1922,9 @@
19311922 name = IO.Path.GetFileName(history);
19321923 }
19331924 this.history.Current = this.FocusedFile ?? this.path;
1934- this.history.Forward(i);
1925+ for(int j = 0; j < i; j++){
1926+ this.history.Forward();
1927+ }
19351928 return true;
19361929 }
19371930 }
@@ -1948,7 +1941,7 @@
19481941 }
19491942
19501943 public void GoForwardHistory(){
1951- if(this.history.Forward()){
1944+ if(this.history.Forward() != null){
19521945 if(this.IsAllowToGo(this.history.Current)){
19531946 this.ChangeDirectory(this.history.Current, false);
19541947 }else{
@@ -1959,12 +1952,16 @@
19591952 }
19601953
19611954 public void GoForwardHistory(int count){
1962- this.history.Forward(count);
1955+ for(int i = 0; i < count; i++){
1956+ this.history.Forward();
1957+ }
19631958 if(this.IsAllowToGo(this.history.Current)){
19641959 this.ChangeDirectory(this.history.Current, false);
19651960 }else{
19661961 MainForm.Instance.MessageBeep(MessageBeep.Okey);
1967- this.history.Back(count);
1962+ for(int i = 0; i < count; i++){
1963+ this.history.Back();
1964+ }
19681965 }
19691966 }
19701967
@@ -1977,7 +1974,7 @@
19771974 this.history.Current = focusedFile;
19781975 }
19791976 }
1980- if(this.history.Back()){
1977+ if(this.history.Back() != null){
19811978 if(this.IsAllowToGo(this.history.Current)){
19821979 this.ChangeDirectory(this.history.Current, false);
19831980 }else{
@@ -1996,12 +1993,16 @@
19961993 this.history.Current = focusedFile;
19971994 }
19981995 }
1999- this.history.Back(count);
1996+ for(int i = 0; i < count; i++){
1997+ this.history.Back();
1998+ }
20001999 if(this.IsAllowToGo(this.history.Current)){
20012000 this.ChangeDirectory(this.history.Current, false);
20022001 }else{
20032002 MainForm.Instance.MessageBeep(MessageBeep.Okey);
2004- this.history.Forward(count);
2003+ for(int i = 0; i < count; i++){
2004+ this.history.Forward();
2005+ }
20052006 }
20062007 }
20072008
@@ -2164,13 +2165,12 @@
21642165 public void CheckAndDown(){
21652166 this.Check();
21662167 int idx = this.FocusedItemIndex + 1;
2167- this.ClearSelection(false);
21682168 if(idx < this.Items.Count){
21692169 this.FocusedItemIndex = idx;
21702170 }
2171- try{
2171+ this.ClearSelection(false);
2172+ if(this.FocusedItem != null){
21722173 this.FocusedItem.Selected = true;
2173- }catch(NullReferenceException){
21742174 }
21752175 }
21762176
@@ -2315,10 +2315,21 @@
23152315 }
23162316 }
23172317
2318+
23182319 #endregion
23192320
23202321 #region プロパティ
23212322
2323+ public History<string> History{
2324+ get{
2325+ return this.history;
2326+ }
2327+ set{
2328+ this.history = value;
2329+ this.history.LimitCount = FilerModule.FilerOption.HistoryCount;
2330+ }
2331+ }
2332+
23222333 public string Path{
23232334 get{
23242335 return this.path;
@@ -2536,14 +2547,20 @@
25362547
25372548 public string[] ForwardHistory{
25382549 get{
2539- return this.history.ForwardStack.ToArray();
2550+ return this.history.ForwardHistory;
25402551 }
2552+ set{
2553+ this.history.ForwardHistory = value;
2554+ }
25412555 }
25422556
25432557 public string[] BackHistory{
25442558 get{
2545- return this.history.BackStack.ToArray();
2559+ return this.history.BackHistory;
25462560 }
2561+ set{
2562+ this.history.BackHistory = value;
2563+ }
25472564 }
25482565
25492566 public int LimitHistoryCount{
@@ -2666,6 +2683,16 @@
26662683 }
26672684 }
26682685
2686+ private bool showItemToolTips = true;
2687+ public new bool ShowItemToolTips{
2688+ get{
2689+ return this.showItemToolTips;
2690+ }
2691+ set{
2692+ this.showItemToolTips = value;
2693+ }
2694+ }
2695+
26692696 #endregion
26702697
26712698 #region イベント
--- kuon/trunk/Modules/Filer/FilerModule.cs (revision 302)
+++ kuon/trunk/Modules/Filer/FilerModule.cs (revision 303)
@@ -1490,6 +1490,10 @@
14901490 }
14911491 }
14921492
1493+ public static void ToggleNavigation(){
1494+ ToggleNavigation(null, null);
1495+ }
1496+
14931497 private static void ToggleNavigation(object sender, ActionEventArgs e){
14941498 FilerControl actFiler = FilerForm.ActiveFiler;
14951499 if(actFiler != null){
@@ -1650,6 +1654,10 @@
16501654 }
16511655 }
16521656
1657+ public static void SetFileFilter(){
1658+ SetFileFilter(null, ActionEventArgs.Empty);
1659+ }
1660+
16531661 private static void SetFileFilter(object sender, ActionEventArgs e){
16541662 FilerControl actFiler = FilerForm.ActiveFiler;
16551663 if(actFiler != null){
@@ -2103,6 +2111,21 @@
21032111 }
21042112
21052113 public override void Apply(){
2114+ {
2115+ int lenWidths = this.ColumnWidths.Length;
2116+ int lenOrder = this.ColumnOrder.Length;
2117+ if(lenOrder > lenWidths){
2118+ int[] widths = new int[lenOrder];
2119+ this.ColumnWidths.CopyTo(widths, 0);
2120+ for(int i = lenWidths; i < lenOrder; i++){
2121+ widths[i] = 100;
2122+ }
2123+ this.ColumnWidths = widths;
2124+ }else if(lenOrder < lenWidths){
2125+ Array.Resize(ref this.columnWidths, lenOrder);
2126+ }
2127+ }
2128+
21062129 if(MainForm.Instance != null){
21072130 foreach(FilerForm form in FilerForm.FilerForms){
21082131 form.DoubleWindowFiler.LeftFiler.AutoFitColumn = form.DoubleWindowFiler.RightFiler.AutoFitColumn = this.AutoFitColumn;
@@ -2130,9 +2153,11 @@
21302153 try{
21312154 form.DoubleWindowFiler.LeftFiler.BackColor = Color.Empty;
21322155 form.DoubleWindowFiler.RightFiler.BackColor = Color.Empty;
2133- IO.FileStream stream = new IO.FileStream(this.BackgroundImage, IO.FileMode.Open, IO.FileAccess.Read);
2134- Image image = Image.FromStream(stream);
2135- stream.Close();
2156+ Image image = null;
2157+ using(IO.FileStream stream = new IO.FileStream(this.BackgroundImage, IO.FileMode.Open, IO.FileAccess.Read)){
2158+ image = Image.FromStream(stream);
2159+ stream.Close();
2160+ }
21362161 form.DoubleWindowFiler.LeftFiler.BackgroundImage = image;
21372162 form.DoubleWindowFiler.RightFiler.BackgroundImage = image;
21382163 }catch(Exception ex){
@@ -2156,18 +2181,6 @@
21562181
21572182 form.DoubleWindowFiler.LeftFiler.Columns.Clear();
21582183 form.DoubleWindowFiler.RightFiler.Columns.Clear();
2159- int lenWidths = this.ColumnWidths.Length;
2160- int lenOrder = this.ColumnOrder.Length;
2161- if(lenOrder > lenWidths){
2162- int[] widths = new int[lenOrder];
2163- this.ColumnWidths.CopyTo(widths, 0);
2164- for(int i = lenOrder - 1; i < lenWidths; i++){
2165- widths[i] = 100;
2166- }
2167- this.ColumnWidths = widths;
2168- }else if(lenOrder < lenWidths){
2169- Array.Resize(ref this.columnWidths, lenOrder);
2170- }
21712184 for(int i = 0; i < this.ColumnOrder.Length; i++){
21722185 form.DoubleWindowFiler.LeftFiler.AddColumn(this.ColumnOrder[i], this.ColumnWidths[i]);
21732186 form.DoubleWindowFiler.RightFiler.AddColumn(this.ColumnOrder[i], this.ColumnWidths[i]);
@@ -2625,7 +2638,7 @@
26252638 }
26262639 }
26272640
2628- private string[] ignoreCachingIconFileTypes = new string[]{".exe", ".ico", ".lnk", ".icl", ".msc", ".cpl"};
2641+ private string[] ignoreCachingIconFileTypes = new string[]{".exe", ".ico", ".lnk", ".icl", ".msc", ".cpl", ".cur", ".ani"};
26292642 [Category("ViewCategory")]
26302643 [Description("IgnoreCachingIconFileTypesDescription")]
26312644 [DefaultValue(true)]
--- kuon/trunk/Modules/Viewer/ViewerControl.cs (revision 302)
+++ kuon/trunk/Modules/Viewer/ViewerControl.cs (revision 303)
@@ -4,8 +4,11 @@
44
55 using System;
66 using System.ComponentModel;
7+using System.Collections.Generic;
8+using System.Collections.ObjectModel;
79 using System.Drawing;
810 using System.Drawing.Drawing2D;
11+using System.Drawing.Imaging;
912 using System.Threading;
1013 using System.Windows.Forms;
1114 using Kuon.Utilities;
@@ -12,18 +15,39 @@
1215
1316 namespace Kuon.Viewer{
1417 public class ViewerControl : UserControl{
18+ #region field
19+
1520 private BackgroundWorker loadingWorker = new BackgroundWorker();
1621 private BackgroundWorker refreshWorker = new BackgroundWorker();
1722 private PictureBox pictureBox = new PictureBox();
18- private Bitmap originalImage = null;
23+ private GflBitmap originalImage = null;
1924 private double scale = 1.0;
20- private ImageFittingMode fittingMode = ImageFittingMode.Window;
25+ private ImageFittingMode fittingMode = ImageFittingMode.WindowLargeOnly;
26+ private FileList fileList = new FileList();
2127
28+ #endregion
29+
30+ #region constructor
31+
2232 public ViewerControl(){
33+ this.SuspendLayout();
34+
2335 this.AutoScroll = true;
24- this.BackColor = Color.Black;
36+ this.BackColor = SystemColors.AppWorkspace;
2537
26- this.Controls.Add(pictureBox);
38+ Bitmap backgroundTexture = new Bitmap(32, 32);
39+ using(Graphics g = Graphics.FromImage(backgroundTexture))
40+ using(SolidBrush brush1 = new SolidBrush(SystemColors.Window))
41+ using(SolidBrush brush2 = new SolidBrush(SystemColors.AppWorkspace))
42+ {
43+ g.FillRectangle(brush1, 0, 0, 16, 16);
44+ g.FillRectangle(brush1, 16, 16, 16, 16);
45+ g.FillRectangle(brush2, 16, 0, 16, 16);
46+ g.FillRectangle(brush2, 0, 16, 16, 16);
47+ }
48+ this.pictureBox.BackgroundImage = backgroundTexture;
49+ this.pictureBox.BackgroundImageLayout = ImageLayout.Tile;
50+ this.Controls.Add(this.pictureBox);
2751
2852 this.loadingWorker.DoWork += this.LoadImage_DoWork;
2953 this.loadingWorker.RunWorkerCompleted += this.LoadImage_RunWorkerCompleted;
@@ -34,9 +58,21 @@
3458 this.refreshWorker.RunWorkerCompleted += this.RefreshImage_RunWorkerCompleted;
3559 //this.refreshWorker.WorkerReportsProgress = true;
3660 this.refreshWorker.WorkerSupportsCancellation = true;
61+
62+ this.ResumeLayout();
3763 }
3864
39- public void LoadImage(string path){
65+ #endregion
66+
67+ #region Load
68+
69+ public void OpenImage(string path){
70+ this.fileList.Clear();
71+ this.fileList.Add(path);
72+ this.LoadImage(this.fileList.Current);
73+ }
74+
75+ private void LoadImage(string path){
4076 if(path == null){
4177 throw new ArgumentNullException();
4278 }
@@ -52,6 +88,7 @@
5288 LoadImageArgument arg = new LoadImageArgument(path);
5389
5490 MainForm.Instance.StatusBar.Progress.Start(arg);
91+ this.Cursor = Cursors.AppStarting;
5592 this.loadingWorker.RunWorkerAsync(arg);
5693 }
5794
@@ -64,23 +101,28 @@
64101 return;
65102 }
66103
67- using(GflBitmap bmp = GflBitmap.FromFile(arg.Path, new GflProgressCallback(delegate(object sender2, GflProgressEventArgs e2){
104+ arg.Bitmap = GflBitmap.FromFile(arg.Path, new GflProgressCallback(delegate(object sender2, GflProgressEventArgs e2){
68105 this.Invoke(new MethodInvoker(delegate{
69106 MainForm.Instance.StatusBar.Progress.Report(arg, e2.ProgressPercentage);
70107 }));
71- }))){
72- arg.Bitmap = bmp.ToBitmap();
73- }
108+ }));
74109
75110 if(this.loadingWorker.CancellationPending){
76111 arg.Cancelled = true;
77112 return;
78113 }
114+
115+ this.Invoke(new MethodInvoker(delegate{
116+ this.OnImageLoaded(new ImageLoadedEventArgs(arg.Bitmap));
117+ }));
79118 }
80119
81120 private void LoadImage_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
82121 LoadImageArgument arg = (LoadImageArgument)e.Result;
83122 MainForm.Instance.StatusBar.Progress.Complete(arg);
123+ if(!(this.refreshWorker.IsBusy)){
124+ this.Cursor = Cursors.Default;
125+ }
84126
85127 if(arg.Cancelled){
86128 this.originalImage = null;
@@ -92,7 +134,7 @@
92134
93135 public class LoadImageArgument{
94136 public string Path{get; private set;}
95- public Bitmap Bitmap{get; set;}
137+ public GflBitmap Bitmap{get; set;}
96138 public bool Cancelled{get; set;}
97139
98140 public LoadImageArgument(string path){
@@ -101,6 +143,10 @@
101143 }
102144 }
103145
146+ #endregion
147+
148+ #region refresh
149+
104150 public void RefreshImage(){
105151 if(this.originalImage == null){
106152 this.ClearImage();
@@ -118,6 +164,7 @@
118164 RefreshImageArgument arg = new RefreshImageArgument(this.originalImage, this.ClientSize, this.fittingMode, 1.0);
119165
120166 MainForm.Instance.StatusBar.Progress.Start(arg);
167+ this.Cursor = Cursors.AppStarting;
121168 MainForm.Instance.StatusBar.Progress.Report(arg, 50);
122169 this.refreshWorker.RunWorkerAsync(arg);
123170 }
@@ -131,7 +178,7 @@
131178 return;
132179 }
133180
134- Bitmap bitmap = arg.Bitmap;
181+ Bitmap bitmap = arg.Bitmap.ToBitmap();
135182
136183 double originalWidth = bitmap.Width;
137184 double originalHeight = bitmap.Height;
@@ -173,13 +220,17 @@
173220 if((destWidth == 0) || (destHeight == 0)){
174221 arg.Bitmap = null;
175222 }else{
176- Bitmap destImage = new Bitmap(destWidth, destHeight);
223+ Bitmap destImage = new Bitmap(destWidth, destHeight, PixelFormat.Format32bppArgb);
177224 using(Graphics g = Graphics.FromImage(destImage)){
225+ g.CompositingMode = CompositingMode.SourceOver;
178226 g.CompositingQuality = CompositingQuality.HighQuality;
179227 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
228+ g.PixelOffsetMode = PixelOffsetMode.HighQuality;
229+ g.SmoothingMode = SmoothingMode.HighQuality;
230+
180231 g.DrawImage(bitmap, 0, 0, destWidth, destHeight);
181232 }
182- arg.Bitmap = destImage;
233+ arg.DestBitmap = destImage;
183234 }
184235
185236 if(this.refreshWorker.CancellationPending){
@@ -192,11 +243,19 @@
192243 RefreshImageArgument arg = (RefreshImageArgument)e.Result;
193244
194245 MainForm.Instance.StatusBar.Progress.Complete(arg);
246+ if(!(this.loadingWorker.IsBusy)){
247+ this.Cursor = Cursors.Default;
248+ }
195249
196250 if(!(arg.Cancelled)){
197- int destWidth = (arg.Bitmap != null) ? arg.Bitmap.Width : 0;
198- int destHeight = (arg.Bitmap != null) ? arg.Bitmap.Height : 0;
199- this.pictureBox.Image = arg.Bitmap;
251+ this.SuspendLayout();
252+
253+ this.scale = arg.Scale;
254+ this.AutoScrollPosition = new Point(0, 0);
255+
256+ int destWidth = (arg.Bitmap != null) ? arg.DestBitmap.Width : 0;
257+ int destHeight = (arg.Bitmap != null) ? arg.DestBitmap.Height : 0;
258+ this.pictureBox.Image = arg.DestBitmap;
200259 this.pictureBox.ClientSize = new Size(destWidth, destHeight);
201260
202261 if(destWidth < this.ClientSize.Width){
@@ -209,17 +268,20 @@
209268 }else{
210269 this.pictureBox.Top = 0;
211270 }
271+
272+ this.ResumeLayout();
212273 }
213274 }
214275
215276 private class RefreshImageArgument{
216- public Bitmap Bitmap{get; set;}
277+ public GflBitmap Bitmap{get; set;}
278+ public Bitmap DestBitmap{get; set;}
217279 public double Scale{get; set;}
218280 public bool Cancelled{get; set;}
219281 public Size ClientSize{get; private set;}
220282 public ImageFittingMode FittingMode{get; private set;}
221283
222- public RefreshImageArgument(Bitmap bitmap, Size clientSize, ImageFittingMode fittingMode, double scale){
284+ public RefreshImageArgument(GflBitmap bitmap, Size clientSize, ImageFittingMode fittingMode, double scale){
223285 this.Bitmap = bitmap;
224286 this.ClientSize = clientSize;
225287 this.FittingMode = fittingMode;
@@ -228,6 +290,10 @@
228290 }
229291 }
230292
293+ #endregion
294+
295+ #region 関数
296+
231297 private void ClearImage(){
232298 this.pictureBox.ClientSize = new Size(0, 0);
233299 }
@@ -239,6 +305,10 @@
239305 base.OnSizeChanged(e);
240306 }
241307
308+ #endregion
309+
310+ #region プロパティ
311+
242312 public double Scale{
243313 get{
244314 return this.scale;
@@ -247,8 +317,123 @@
247317 this.scale = value;
248318 }
249319 }
320+
321+ public ImageFittingMode AutoFittingMode{
322+ get{
323+ return this.fittingMode;
324+ }
325+ set{
326+ this.fittingMode = value;
327+ }
328+ }
329+
330+ #endregion
331+
332+ #region クラス
333+
334+ public class FileList : Collection<string>{
335+ private int currentIndex = -1;
336+
337+ protected override void ClearItems(){
338+ base.ClearItems();
339+ this.currentIndex = -1;
340+ }
341+
342+ protected override void InsertItem(int index, string item){
343+ if(index < this.currentIndex){
344+ this.currentIndex++;
345+ }else if(index == this.currentIndex){
346+ this.currentIndex = -1;
347+ }else if(this.Count == 0){
348+ this.currentIndex = 0;
349+ }
350+ base.InsertItem(index, item);
351+ }
352+
353+ protected override void RemoveItem(int index){
354+ base.RemoveItem(index);
355+ if(index < this.currentIndex){
356+ this.currentIndex--;
357+ }else if(index == this.currentIndex){
358+ this.currentIndex = -1;
359+ }else if(this.Count == 0){
360+ this.currentIndex = -1;
361+ }
362+ }
363+
364+ public int CurrentIndex{
365+ get{
366+ return this.currentIndex;
367+ }
368+ set{
369+ if(value > this.Count){
370+ throw new ArgumentOutOfRangeException();
371+ }
372+ this.currentIndex = value;
373+ }
374+ }
375+
376+ public string Current{
377+ get{
378+ if(this.currentIndex >= 0){
379+ return this[this.currentIndex];
380+ }else{
381+ return null;
382+ }
383+ }
384+ }
385+ }
386+
387+ #endregion
388+
389+ #region イベント
390+
391+ private static readonly object EventImageLoaded = new object();
392+ public event ImageLoadedEventHandler ImageLoaded{
393+ add{
394+ this.Events.AddHandler(EventImageLoaded, value);
395+ }
396+ remove{
397+ this.Events.RemoveHandler(EventImageLoaded, value);
398+ }
399+ }
400+
401+ protected virtual void OnImageLoaded(ImageLoadedEventArgs e){
402+ ImageLoadedEventHandler handler = this.Events[EventImageLoaded] as ImageLoadedEventHandler;
403+ if(handler != null){
404+ handler(this, e);
405+ }
406+ }
407+
408+ #endregion
250409 }
251410
411+ public delegate void ImageLoadedEventHandler(object sender, ImageLoadedEventArgs e);
412+
413+ public class ImageLoadedEventArgs : EventArgs{
414+ public GflBitmap bitmap;
415+
416+ public ImageLoadedEventArgs(GflBitmap bitmap){
417+ this.bitmap = bitmap;
418+ }
419+
420+ public Bitmap SmallIcon{
421+ get{
422+ Bitmap icon = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
423+ using(Graphics g = Graphics.FromImage(icon)){
424+ g.CompositingMode = CompositingMode.SourceOver;
425+ g.CompositingQuality = CompositingQuality.HighQuality;
426+ g.InterpolationMode = InterpolationMode.HighQualityBicubic;
427+ g.PixelOffsetMode = PixelOffsetMode.HighQuality;
428+ g.SmoothingMode = SmoothingMode.HighQuality;
429+
430+ g.DrawImage(this.bitmap.ToBitmap(), 0, 0, 16, 16);
431+ }
432+ return icon;
433+ }
434+ }
435+ }
436+
252437 public enum ImageFittingMode{
253438 None = 0,
254439 Window = 1,
--- kuon/trunk/Modules/Viewer/ViewerForm.cs (revision 302)
+++ kuon/trunk/Modules/Viewer/ViewerForm.cs (revision 303)
@@ -3,11 +3,18 @@
33 */
44
55 using System;
6+using System.Drawing;
67 using System.Windows.Forms;
8+using Kuon;
9+using Kuon.Forms;
10+using Kuon.Utilities;
711
812 namespace Kuon.Viewer{
13+ using IO = System.IO;
14+
915 public class ViewerForm : ChildForm{
1016 private ViewerControl viewer = new ViewerControl();
17+ private MenuStrip menuStrip = new ClickThroughMenuStrip();
1118
1219 public ViewerForm(Form parent) : base(parent, true){
1320 this.SuspendLayout();
@@ -18,6 +25,31 @@
1825 //this.Location = data.Location;
1926 this.WindowState = FormWindowState.Normal;
2027
28+ {
29+ string path = StringEx.JoinPath(Resource.Path.ResourceDirectory, "Viewer.ico");
30+ if(System.IO.File.Exists(path)){
31+ Icon icon = Shell.GetIcon(path, IconSize.Small);
32+ if(icon != null){
33+ this.Icon = icon;
34+ }
35+ }
36+ }
37+
38+ try{
39+ if(IO.File.Exists(Resource.Path.ConfigDirectory + IO.Path.DirectorySeparatorChar + "ViewerMenu.xml")){
40+ this.menuStrip.Items.AddRange(MenuCreator.Create(Resource.Path.ConfigDirectory + IO.Path.DirectorySeparatorChar + "ViewerMenu.xml", "viewer"));
41+ }else{
42+ this.menuStrip.Items.AddRange(MenuCreator.Create(Resource.Path.LanguageDirectory + IO.Path.DirectorySeparatorChar + ApplicationConfig.GetConfig<ConfigGeneral>("General").Language + IO.Path.DirectorySeparatorChar + "ViewerMenu.xml", "viewer"));
43+ }
44+ }catch(InvalidOperationException ex){
45+ MessageBox.Show(ex.Message, ApplicationInfo.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
46+ }
47+ if(this.menuStrip.Items.Count > 0){
48+ this.menuStrip.Visible = false;
49+ this.MainMenuStrip = this.menuStrip;
50+ this.Controls.Add(this.menuStrip);
51+ }
52+
2153 this.viewer.Dock = DockStyle.Fill;
2254 this.Controls.Add(this.viewer);
2355
@@ -30,8 +62,27 @@
3062 this.WindowState = windowState;
3163 }
3264
33- public void LoadImage(string path){
34- this.viewer.LoadImage(path);
65+ public void OpenImage(string path){
66+ this.viewer.OpenImage(path);
3567 }
68+
69+ public void RefreshImage(){
70+ this.viewer.RefreshImage();
71+ }
72+
73+ public ImageFittingMode AutoFittingMode{
74+ get{
75+ return this.viewer.AutoFittingMode;
76+ }
77+ set{
78+ this.viewer.AutoFittingMode = value;
79+ }
80+ }
81+
82+ public static ViewerForm ActiveViewerForm{
83+ get{
84+ return MainForm.Instance.ActiveMdiChild as ViewerForm;
85+ }
86+ }
3687 }
3788 }
\ No newline at end of file
--- kuon/trunk/Modules/Viewer/ViewerModule.cs (revision 302)
+++ kuon/trunk/Modules/Viewer/ViewerModule.cs (revision 303)
@@ -7,6 +7,18 @@
77 using System.Windows.Forms;
88 using Kuon;
99
10+[assembly: AssemblyTitle("Kuon.Viewer")]
11+[assembly: AssemblyProduct("Kuon.Viewer")]
12+[assembly: AssemblyVersion("1.0.*")]
13+[assembly: AssemblyInformationalVersion("0.5.0.0")]
14+[assembly: AssemblyCopyright("Copyright 2009 Kuon Developer Team. (cat-walk)")]
15+[assembly: AssemblyDescription("Viewer module.")]
16+[assembly: AssemblyConfiguration("")]
17+[assembly: AssemblyCompany("")]
18+[assembly: AssemblyTrademark("")]
19+[assembly: AssemblyCulture("")]
20+[assembly: ModuleEntryPoint("Kuon.Viewer.ViewerModule")]
21+
1022 namespace Kuon.Viewer{
1123 public class ViewerModule : Module{
1224 public ViewerModule(){
@@ -26,10 +38,25 @@
2638
2739 public override void LoadActions(){
2840 const string @namespace = "viewer";
41+ if(!(ActionManager.Namespace.ContainsKey(@namespace))){
42+ ActionManager.Namespace.Add(@namespace, new ActionItemDictionary());
43+ }
2944 ActionManager.Global.Add("open-viewer-window", new ActionItem(OpenViewerWindow));
45+ ActionManager.Namespace[@namespace].Add("open-file", new ActionItem(OpenFile));
46+ ActionManager.Namespace[@namespace].Add("auto-fit-none", new ActionItem(AutoFitNone, AutoFitNone));
47+ ActionManager.Namespace[@namespace].Add("auto-fit-window", new ActionItem(AutoFitWindow, AutoFitWindow));
48+ ActionManager.Namespace[@namespace].Add("auto-fit-window-largeonly", new ActionItem(AutoFitWindowLargeOnly, AutoFitWindowLargeOnly));
49+ ActionManager.Namespace[@namespace].Add("auto-fit-window-width", new ActionItem(AutoFitWindowWidth, AutoFitWindowWidth));
50+ ActionManager.Namespace[@namespace].Add("auto-fit-window-width-largeonly", new ActionItem(AutoFitWindowWidthLargeOnly, AutoFitWindowWidthLargeOnly));
51+ ActionManager.Namespace[@namespace].Add("auto-fit-window-height", new ActionItem(AutoFitWindowHeight, AutoFitWindowHeight));
52+ ActionManager.Namespace[@namespace].Add("auto-fit-window-height-largeonly", new ActionItem(AutoFitWindowHeightLargeOnly, AutoFitWindowHeightLargeOnly));
3053 }
3154
3255 private static void OpenViewerWindow(object sender, ActionEventArgs e){
56+ new ViewerForm(MainForm.Instance);
57+ }
58+
59+ private static void OpenFile(object sender, ActionEventArgs e){
3360 OpenFileDialog dialog = new OpenFileDialog();
3461 dialog.CheckFileExists = true;
3562 dialog.CheckPathExists = true;
@@ -36,9 +63,159 @@
3663 dialog.Multiselect = false;
3764 DialogResult result = dialog.ShowDialog(MainForm.Instance);
3865 if(result == DialogResult.OK){
39- ViewerForm form = new ViewerForm(MainForm.Instance);
40- form.LoadImage(dialog.FileName);
66+ ViewerForm form = ViewerForm.ActiveViewerForm;
67+ if(form == null){
68+ form = new ViewerForm(MainForm.Instance);
69+ }
70+ form.OpenImage(dialog.FileName);
4171 }
4272 }
73+
74+ private static void AutoFitNone(object sender, ActionEventArgs e){
75+ ViewerForm form = ViewerForm.ActiveViewerForm;
76+ if(form != null){
77+ form.AutoFittingMode = ImageFittingMode.None;
78+ form.RefreshImage();
79+ }
80+ }
81+
82+ private static ToolStripMenuItem AutoFitNone(object sender, CreateMenuItemArgs e){
83+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
84+ menuItem.Paint += delegate{
85+ ViewerForm form = ViewerForm.ActiveViewerForm;
86+ if(form != null){
87+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.None);
88+ }else{
89+ menuItem.Checked = false;
90+ }
91+ };
92+ return menuItem;
93+ }
94+
95+ private static void AutoFitWindow(object sender, ActionEventArgs e){
96+ ViewerForm form = ViewerForm.ActiveViewerForm;
97+ if(form != null){
98+ form.AutoFittingMode = ImageFittingMode.Window;
99+ form.RefreshImage();
100+ }
101+ }
102+
103+ private static ToolStripMenuItem AutoFitWindow(object sender, CreateMenuItemArgs e){
104+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
105+ menuItem.Paint += delegate{
106+ ViewerForm form = ViewerForm.ActiveViewerForm;
107+ if(form != null){
108+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.Window);
109+ }else{
110+ menuItem.Checked = false;
111+ }
112+ };
113+ return menuItem;
114+ }
115+
116+ private static void AutoFitWindowLargeOnly(object sender, ActionEventArgs e){
117+ ViewerForm form = ViewerForm.ActiveViewerForm;
118+ if(form != null){
119+ form.AutoFittingMode = ImageFittingMode.WindowLargeOnly;
120+ form.RefreshImage();
121+ }
122+ }
123+
124+ private static ToolStripMenuItem AutoFitWindowLargeOnly(object sender, CreateMenuItemArgs e){
125+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
126+ menuItem.Paint += delegate{
127+ ViewerForm form = ViewerForm.ActiveViewerForm;
128+ if(form != null){
129+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.WindowLargeOnly);
130+ }else{
131+ menuItem.Checked = false;
132+ }
133+ };
134+ return menuItem;
135+ }
136+
137+ private static void AutoFitWindowWidth(object sender, ActionEventArgs e){
138+ ViewerForm form = ViewerForm.ActiveViewerForm;
139+ if(form != null){
140+ form.AutoFittingMode = ImageFittingMode.WindowWidth;
141+ form.RefreshImage();
142+ }
143+ }
144+
145+ private static ToolStripMenuItem AutoFitWindowWidth(object sender, CreateMenuItemArgs e){
146+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
147+ menuItem.Paint += delegate{
148+ ViewerForm form = ViewerForm.ActiveViewerForm;
149+ if(form != null){
150+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.WindowWidth);
151+ }else{
152+ menuItem.Checked = false;
153+ }
154+ };
155+ return menuItem;
156+ }
157+
158+ private static void AutoFitWindowWidthLargeOnly(object sender, ActionEventArgs e){
159+ ViewerForm form = ViewerForm.ActiveViewerForm;
160+ if(form != null){
161+ form.AutoFittingMode = ImageFittingMode.WindowWidthLargeOnly;
162+ form.RefreshImage();
163+ }
164+ }
165+
166+ private static ToolStripMenuItem AutoFitWindowWidthLargeOnly(object sender, CreateMenuItemArgs e){
167+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
168+ menuItem.Paint += delegate{
169+ ViewerForm form = ViewerForm.ActiveViewerForm;
170+ if(form != null){
171+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.WindowWidthLargeOnly);
172+ }else{
173+ menuItem.Checked = false;
174+ }
175+ };
176+ return menuItem;
177+ }
178+
179+ private static void AutoFitWindowHeight(object sender, ActionEventArgs e){
180+ ViewerForm form = ViewerForm.ActiveViewerForm;
181+ if(form != null){
182+ form.AutoFittingMode = ImageFittingMode.WindowHeight;
183+ form.RefreshImage();
184+ }
185+ }
186+
187+ private static ToolStripMenuItem AutoFitWindowHeight(object sender, CreateMenuItemArgs e){
188+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
189+ menuItem.Paint += delegate{
190+ ViewerForm form = ViewerForm.ActiveViewerForm;
191+ if(form != null){
192+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.WindowHeight);
193+ }else{
194+ menuItem.Checked = false;
195+ }
196+ };
197+ return menuItem;
198+ }
199+
200+ private static void AutoFitWindowHeightLargeOnly(object sender, ActionEventArgs e){
201+ ViewerForm form = ViewerForm.ActiveViewerForm;
202+ if(form != null){
203+ form.AutoFittingMode = ImageFittingMode.WindowHeightLargeOnly;
204+ form.RefreshImage();
205+ }
206+ }
207+
208+ private static ToolStripMenuItem AutoFitWindowHeightLargeOnly(object sender, CreateMenuItemArgs e){
209+ ToolStripMenuItem menuItem = new ToolStripMenuItem(e.Text, e.Image, e.ClickedEventHandler);
210+ menuItem.Paint += delegate{
211+ ViewerForm form = ViewerForm.ActiveViewerForm;
212+ if(form != null){
213+ menuItem.Checked = (form.AutoFittingMode == ImageFittingMode.WindowHeightLargeOnly);
214+ }else{
215+ menuItem.Checked = false;
216+ }
217+ };
218+ return menuItem;
219+ }
43220 }
44221 }
\ No newline at end of file
--- kuon/trunk/Modules/Renamer/RenameForm.cs (revision 302)
+++ kuon/trunk/Modules/Renamer/RenameForm.cs (revision 303)
@@ -4,11 +4,13 @@
44
55 using System;
66 using System.Collections.Generic;
7+using System.ComponentModel;
78 using System.Drawing;
89 using System.Linq;
910 using System.Reflection;
1011 using System.Text;
1112 using System.Text.RegularExpressions;
13+using System.Threading;
1214 using System.Windows.Forms;
1315 using Kuon;
1416 using Kuon.IO;
@@ -66,6 +68,7 @@
6668 private Button editButton = new Button();
6769 private ListViewEx fileListView = new ListViewEx();
6870 private MenuStrip menuStrip = new ClickThroughMenuStrip();
71+ private BackgroundWorker macroWorker = new BackgroundWorker();
6972
7073 private static readonly Image UnknownIcon;
7174 private static StringTable MacroHelp;
@@ -125,6 +128,8 @@
125128 this.Controls.Add(this.macroBox);
126129
127130 this.macroBox.MacroTextBox.TextChanged += delegate{
131+ this.ApplyMacro();
132+ /*
128133 RenameInfo[] infos = new RenameInfo[this.fileListView.Items.Count];
129134 {
130135 int i = 0;
@@ -134,6 +139,7 @@
134139 }
135140 RenameMacro.Expand(this.macroBox.MacroTextBox.Text, infos);
136141 this.RefreshList();
142+ */
137143 };
138144 this.macroBox.MacroTextBox.Text = @"<bn><ext>";
139145 /*
@@ -217,6 +223,12 @@
217223
218224 this.MinimumSize = new Size(buttonWidth * 6, this.fileListView.Top + this.Margin.Top * 5 + this.upButton.Height * 5);
219225
226+ this.macroWorker.WorkerReportsProgress = true;
227+ this.macroWorker.WorkerSupportsCancellation = true;
228+ this.macroWorker.DoWork += this.ApplyMacro_DoWork;
229+ this.macroWorker.ProgressChanged += this.ApplyMacro_Progress;
230+ this.macroWorker.RunWorkerCompleted += this.ApplyMacro_Completed;
231+
220232 this.Show();
221233 this.ResumeLayout();
222234
@@ -300,7 +312,7 @@
300312
301313 #endregion
302314
303- #region 関数
315+ #region List
304316
305317 private void RefreshList(){
306318 this.RefreshList(this.GetRenameInfos());
@@ -329,6 +341,71 @@
329341 this.fileListView.EndUpdate();
330342 }
331343
344+ private void ApplyMacro(){
345+ if(this.macroWorker.IsBusy){
346+ this.macroWorker.CancelAsync();
347+ while(this.macroWorker.IsBusy){
348+ Thread.Sleep(64);
349+ Application.DoEvents();
350+ }
351+ }
352+
353+ ListViewItem[] items = new ListViewItem[this.fileListView.Items.Count];
354+ {
355+ int i = 0;
356+ foreach(ListViewItem item in this.fileListView.Items){
357+ items[i++] = item;
358+ }
359+ }
360+ MainForm.Instance.StatusBar.Progress.Start(this.macroWorker);
361+ this.macroWorker.RunWorkerAsync(new ApplyMacroArgument(items, this.macroBox.MacroTextBox.Text));
362+ }
363+
364+ private void ApplyMacro_DoWork(object sender, DoWorkEventArgs e){
365+ ApplyMacroArgument arg = (ApplyMacroArgument)e.Argument;
366+ RenameInfo[] infos = new RenameInfo[arg.Items.Length];
367+ {
368+ int i = 0;
369+ foreach(ListViewItem item in arg.Items){
370+ infos[i++] = (RenameInfo)item.Tag;
371+ }
372+ }
373+ RenameMacro.Expand(arg.Text, infos, new ExpandEventHandler(delegate(object sender2, ExpandEventArgs e2){
374+ if(this.macroWorker.CancellationPending){
375+ e.Cancel = true;
376+ e2.Cancel = true;
377+ }else{
378+ this.macroWorker.ReportProgress(e2.ProgressPercentage);
379+ }
380+ }));
381+ }
382+
383+ private void ApplyMacro_Progress(object sender, ProgressChangedEventArgs e){
384+ MainForm.Instance.StatusBar.Progress.Report(this.macroWorker, e.ProgressPercentage);
385+ }
386+
387+ private void ApplyMacro_Completed(object sender, RunWorkerCompletedEventArgs e){
388+ MainForm.Instance.StatusBar.Progress.Complete(this.macroWorker);
389+ if(!e.Cancelled){
390+ this.RefreshList();
391+ this.CheckErrors();
392+ }
393+ }
394+
395+ private class ApplyMacroArgument{
396+ public ListViewItem[] Items{get; private set;}
397+ public string Text{get; private set;}
398+
399+ public ApplyMacroArgument(ListViewItem[] items, string text){
400+ this.Items = items;
401+ this.Text = text;
402+ }
403+ }
404+
405+ #endregion
406+
407+ #region 関数
408+
332409 private void AddFiles(string[] files){
333410 RenameInfo[] infos = this.GetRenameInfos();
334411 RenameInfo[] newInfos = new RenameInfo[infos.Length + files.Length];
--- kuon/trunk/Modules/Renamer/RenameMacro.cs (revision 302)
+++ kuon/trunk/Modules/Renamer/RenameMacro.cs (revision 303)
@@ -5,6 +5,7 @@
55 using System;
66 using System.Collections.Generic;
77 using System.Collections.ObjectModel;
8+using System.ComponentModel;
89 using System.Linq;
910 using System.Security.Cryptography;
1011 using System.Text;
@@ -86,6 +87,10 @@
8687 }
8788
8889 public static void Expand(string source, RenameInfo[] infos){
90+ Expand(source, infos, null);
91+ }
92+
93+ public static void Expand(string source, RenameInfo[] infos, ExpandEventHandler cancel){
8994 if(source == null){
9095 throw new ArgumentNullException();
9196 }
@@ -103,6 +108,13 @@
103108 root.Items.AddRange(Parse(source));
104109
105110 for(int i = 0; i < files.Length; i++){
111+ if(cancel != null){
112+ ExpandEventArgs e = new ExpandEventArgs((int)i / files.Length * 100);
113+ cancel(null, e);
114+ if(e.Cancel){
115+ return;
116+ }
117+ }
106118 infos[i].NewName = root.GetString(files[i], i);
107119 }
108120 }
@@ -731,4 +743,14 @@
731743 FileNameError = 0x0020,
732744 UndoError = 0x0040,
733745 }
746+
747+ public delegate void ExpandEventHandler(object sender, ExpandEventArgs e);
748+
749+ public class ExpandEventArgs : CancelEventArgs{
750+ public int ProgressPercentage{get; private set;}
751+
752+ public ExpandEventArgs(int percentage){
753+ this.ProgressPercentage = percentage;
754+ }
755+ }
734756 }
\ No newline at end of file
--- kuon/trunk/Utilities/History.cs (revision 302)
+++ kuon/trunk/Utilities/History.cs (revision 303)
@@ -6,139 +6,165 @@
66 using System.Collections.Generic;
77
88 namespace Kuon.Utilities{
9- public class History<T>{
10- private Stack<T> forwardStack = new Stack<T>();
11- private Stack<T> backStack = new Stack<T>();
12- private T current = default(T);
9+ public interface IHistory<T>{
10+ void Add(T item);
11+ void Clear();
12+ T Forward();
13+ T Back();
14+ bool CanGoForward{get;}
15+ bool CanGoBack{get;}
16+ T Current{get;}
17+ }
18+
19+ public class History<T> : IHistory<T>{
20+ private LinkedList<T> list = new LinkedList<T>();
21+ private LinkedListNode<T> current = null;
1322 private int limitCount = 0;
1423
1524 public History(){
1625 }
1726
18- public History(int limit){
19- this.limitCount = limit;
27+ public History(int limitCount){
28+ this.limitCount = limitCount;
2029 }
2130
22- /// <summary>
23- /// 履歴を追加する。
24- /// </summary>
25- /// <param name="item">アイテム</param>
2631 public void Add(T item){
27- if(item == null){
28- throw new ArgumentNullException();
29- }
30- this.backStack.Push(item);
31- if((this.limitCount > 0) && (this.backStack.Count > this.limitCount)){
32- Stack<T> stack = new Stack<T>();
33- for(int i = 0; i < this.limitCount; i++){
34- stack.Push(this.backStack.Pop());
32+ if(this.list.Count == 0){
33+ this.list.AddFirst(item);
34+ this.current = this.list.First;
35+ }else{
36+ if(this.current != null){
37+ while(this.current.Next != null){
38+ this.list.Remove(this.current.Next);
39+ }
3540 }
36- this.backStack = stack;
41+ this.list.AddAfter(this.current, item);
42+ this.current = this.current.Next;
3743 }
38- this.forwardStack.Clear();
39- this.current = default(T);
44+ if((this.limitCount > 0) && (this.list.Count > this.limitCount)){
45+ this.list.Remove(this.list.First);
46+ }
4047 }
4148
42- /// <summary>
43- /// 履歴をクリアする。
44- /// </summary>
45- public void Clear(){
46- this.backStack.Clear();
47- this.forwardStack.Clear();
48- }
49-
50- /// <summary>
51- /// 次の履歴へ移動する。
52- /// </summary>
53- /// <returns>移動出来たかどうか</returns>
54- public bool Forward(){
55- if(this.forwardStack.Count > 0){
56- this.backStack.Push(this.current);
57- this.current = this.forwardStack.Pop();
58- return true;
49+ public void Insert(T item){
50+ if(this.list.Count == 0){
51+ this.list.AddFirst(item);
52+ this.current = this.list.First;
5953 }else{
60- return false;
54+ this.list.AddAfter(this.current, item);
55+ this.current = this.current.Next;
6156 }
57+ if((this.limitCount > 0) && (this.list.Count > this.limitCount)){
58+ this.list.Remove(this.list.First);
59+ }
6260 }
6361
64- public bool Forward(int count){
65- if(count < 0){
66- throw new ArgumentOutOfRangeException();
67- }
68- while(count-- > 0){
69- if(!this.Forward()){
70- return false;
71- }
72- }
73- return true;
62+ public void Clear(){
63+ this.list.Clear();
64+ this.current = null;
7465 }
7566
76- public bool CanGoForward{
77- get{
78- return (this.forwardStack.Count > 0);
67+ public T Forward(){
68+ if(this.CanGoForward){
69+ this.current = this.current.Next;
70+ return this.current.Value;
71+ }else{
72+ return default(T);
7973 }
8074 }
8175
82- /// <summary>
83- /// 前の履歴へ移動する。
84- /// </summary>
85- /// <returns>移動できたかどうか</returns>
86- public bool Back(){
87- if(this.backStack.Count > 0){
88- this.forwardStack.Push(this.current);
89- this.current = this.backStack.Pop();
90- return true;
76+ public T Back(){
77+ if(this.CanGoBack){
78+ this.current = this.current.Previous;
79+ return this.current.Value;
9180 }else{
92- return false;
81+ return default(T);
9382 }
9483 }
9584
96- public bool Back(int count){
97- while(count-- > 0){
98- if(!this.Back()){
99- return false;
85+ public T Current{
86+ get{
87+ return this.current.Value;
88+ }
89+ set{
90+ if(this.current == null){
91+ this.list.AddFirst(value);
92+ this.current = this.list.First;
93+ }else{
94+ this.current.Value = value;
10095 }
10196 }
102- return true;
10397 }
10498
105- public bool CanGoBack{
99+ public T[] ForwardHistory{
106100 get{
107- return (this.backStack.Count > 0);
101+ if(this.current != null){
102+ List<T> list = new List<T>();
103+ LinkedListNode<T> node = this.current.Next;
104+ while(node != null){
105+ list.Add(node.Value);
106+ node = node.Next;
107+ }
108+ return list.ToArray();
109+ }else{
110+ return new T[0];
111+ }
108112 }
113+ set{
114+ if(this.current == null){
115+ this.list.AddFirst(default(T));
116+ this.current = this.list.First;
117+ }
118+ LinkedListNode<T> node = this.current;
119+ foreach(T item in value){
120+ this.list.AddAfter(node, item);
121+ node = node.Next;
122+ if((this.limitCount > 0) && (this.list.Count == this.limitCount)){
123+ break;
124+ }
125+ }
126+ }
109127 }
110-
111128
112- /// <summary>
113- /// 現在の状態。
114- /// </summary>
115- public T Current{
129+ public T[] BackHistory{
116130 get{
117- return this.current;
131+ if(this.current != null){
132+ List<T> list = new List<T>();
133+ LinkedListNode<T> node = this.current.Previous;
134+ while(node != null){
135+ list.Add(node.Value);
136+ node = node.Previous;
137+ }
138+ return list.ToArray();
139+ }else{
140+ return new T[0];
141+ }
118142 }
119143 set{
120- if(value == null){
121- throw new ArgumentNullException();
144+ if(this.current == null){
145+ this.list.AddFirst(default(T));
146+ this.current = this.list.First;
122147 }
123- this.current = value;
148+ LinkedListNode<T> node = this.current;
149+ foreach(T item in value){
150+ this.list.AddBefore(node, item);
151+ node = node.Previous;
152+ if((this.limitCount > 0) && (this.list.Count == this.limitCount)){
153+ break;
154+ }
155+ }
124156 }
125157 }
126158
127- /// <summary>
128- /// 現在より後ろの履歴のスタック。
129- /// </summary>
130- public Stack<T> BackStack{
159+ public bool CanGoForward{
131160 get{
132- return this.backStack;
161+ return ((this.current != null) || (this.current.Next != null));
133162 }
134163 }
135164
136- /// <summary>
137- /// 現在より前の履歴のスタック。
138- /// </summary>
139- public Stack<T> ForwardStack{
165+ public bool CanGoBack{
140166 get{
141- return this.forwardStack;
167+ return ((this.current != null) || (this.current.Previous != null));
142168 }
143169 }
144170
@@ -147,41 +173,52 @@
147173 return this.limitCount;
148174 }
149175 set{
150- if(limitCount < 1){
151- throw new ArgumentOutOfRangeException();
152- }
153176 this.limitCount = value;
154177 }
155178 }
156179 }
157-
158180 /*
159- public class SizeLimitedStack<T> : Stack<T>{
160- private int limit = -1;
161- public int Limit{
162- get{
163- return this.limit;
164- }
165- set{
166- this.limit = value;
167- }
181+ [Serializable]
182+ public class BranchHistory<T> : IHistory<T>{
183+ private Node current;
184+ private Node root;
185+
186+ public BranchHistory(){
187+ this.root = new RootNode();
188+ this.current = this.root;
168189 }
169190
170- public SizeLimitedStack() : base(){
191+ public void Add(T item){
192+ Node node = new Node(this.current, item);
193+ this.current.Children.Add(node);
194+ this.current = node;
171195 }
172196
173- public SizeLimitedStack(IEnumerable<T> collection) : base(collection){
197+ public void Clear(){
198+ this.root.Children.Clear();
199+ this.current = this.root;
174200 }
175201
176- public SizeLimitedStack(int capacity) : base(capacity){
202+ public T Forward(){
203+
177204 }
178205
179- public SizeLimitedStack(int capacity, int limit) : base(capacity){
180- this.limit = limit;
206+ private class Node{
207+ public Node Parent{get; set;}
208+ public IList<Node> Children{get; set;}
209+ public T Value{get; set;}
210+
211+ public Node(Node parent, T value){
212+ this.Parent = parent;
213+ this.Children = new SkipListNode<Node>();
214+ this.Value = value;
215+ }
181216 }
182217
183- //public override void Push(T item){
184- //}
218+ private class RootNode : Node{
219+ public RootNode() : base(null, default(T)){
220+ }
221+ }
185222 }
186223 */
187224 }
\ No newline at end of file
--- kuon/trunk/Utilities/Win32.cs (revision 302)
+++ kuon/trunk/Utilities/Win32.cs (revision 303)
@@ -19,9 +19,15 @@
1919 [DllImport("KERNEL32.DLL", EntryPoint = "RtlMoveMemory", CharSet = CharSet.Auto)]
2020 public static extern void CopyMemory(IntPtr dst, IntPtr src, int length);
2121
22+ [DllImport("USER32.DLL", EntryPoint = "GetActiveWindow", CharSet = CharSet.Auto)]
23+ public static extern IntPtr GetActiveWindow();
24+
2225 [DllImport("USER32.DLL", EntryPoint = "SetActiveWindow", CharSet = CharSet.Auto)]
2326 public static extern IntPtr SetActiveWindow(IntPtr hwnd);
2427
28+ [DllImport("USER32.DLL", EntryPoint = "GetClassLong", CharSet = CharSet.Auto)]
29+ public static extern IntPtr GetClassLong(IntPtr hwnd, GetClassLongOption nIndex);
30+
2531 /// <summary>
2632 /// ウインドウを表示する。
2733 /// </summary>
@@ -42,15 +48,10 @@
4248 [DllImport("USER32.DLL", EntryPoint = "GetForegroundWindow", CharSet = CharSet.Auto)]
4349 public static extern IntPtr GetForegroundWindow();
4450
45- /// <summary>
46- /// メッセージを発行する。
47- /// </summary>
48- /// <param name="hwnd">メッセージの発行先のウインドウのハンドル</param>
49- /// <param name="msg">メッセージ番号</param>
50- /// <param name="wParam">wParam</param>
51- /// <param name="lParam">lParam</param>
52- /// <returns>返り値</returns>
5351 [DllImport("USER32.DLL", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
52+ public static extern IntPtr SendMessage(IntPtr hwnd, WindowMessage msg, int wParam, int lParam);
53+
54+ [DllImport("USER32.DLL", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
5455 public static extern IntPtr SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);
5556
5657 [DllImport("USER32.DLL", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
@@ -79,22 +80,46 @@
7980 public static extern int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam);
8081
8182 [DllImport("user32", EntryPoint = "GetWindowThreadProcessId", CharSet = CharSet.Auto)]
82- public static extern int GetWindowThreadProcessId(IntPtr hWnd, ref int ProcessId);
83+ public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
8384
85+ [DllImport("user32", EntryPoint = "GetWindow", CharSet = CharSet.Auto)]
86+ public static extern IntPtr GetWindow(IntPtr hWnd, GetWindowOption option);
87+
8488 [DllImport("user32", EntryPoint = "GetWindowText", CharSet = CharSet.Auto)]
8589 public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
8690
91+ [DllImport("user32", EntryPoint = "SetWindowText", CharSet = CharSet.Auto)]
92+ public static extern bool SetWindowText(IntPtr hWnd, [MarshalAs(UnmanagedType.LPTStr)] string text);
93+
94+ [DllImport("user32", EntryPoint = "SetWindowPos", CharSet = CharSet.Auto)]
95+ public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, SetWindowPosOptions options);
96+
97+ [DllImport("user32", EntryPoint = "GetWindowRect", CharSet = CharSet.Auto)]
98+ public static extern int GetWindowRect(IntPtr hWnd, ref Win32.Rectangle rect);
99+
100+ [DllImport("user32", EntryPoint = "IsWindow", CharSet = CharSet.Auto)]
101+ public static extern bool IsWindow(IntPtr hWnd);
102+
87103 [DllImport("user32", EntryPoint = "GetWindowPlacement", CharSet = CharSet.Auto)]
88104 public static extern bool GetWindowPlacement(IntPtr Handle, ref WindowPlacement placement);
89105
90- [DllImport("user32", EntryPoint = "GetWindowRect", CharSet = CharSet.Auto)]
91- public static extern bool GetWindowPlacement(IntPtr Handle, ref Rectangle rect);
106+ [DllImport("user32", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
107+ public static extern uint GetWindowLong(IntPtr Handle, GetWindowLongOption option);
92108
109+ [DllImport("user32", EntryPoint = "IsWindowVisible", CharSet = CharSet.Auto)]
110+ public static extern bool IsWindowVisible(IntPtr Handle);
111+
112+ [DllImport("user32", EntryPoint = "IsWindowEnabled", CharSet = CharSet.Auto)]
113+ public static extern bool IsWindowEnabled(IntPtr Handle);
114+
115+ [DllImport("user32", EntryPoint = "EnableWindow", CharSet = CharSet.Auto)]
116+ public static extern bool IsWindowEnabled(IntPtr Handle, bool enable);
117+
93118 [StructLayout(LayoutKind.Sequential)]
94119 public struct WindowPlacement{
95120 public long Length;
96121 public long Flags;
97- public ShowWindowCommand cmd;
122+ public ShowWindowCommand Command;
98123 public Point MinPosition;
99124 public Point MaxPosition;
100125 public Rectangle NormalPosition;
@@ -114,10 +139,10 @@
114139 /// </summary>
115140 [StructLayout(LayoutKind.Sequential)]
116141 public struct Rectangle{
117- public long Left;
118- public long Top;
119- public long Right;
120- public long Bottom;
142+ public int Left;
143+ public int Top;
144+ public int Right;
145+ public int Bottom;
121146 }
122147
123148 [DllImport("user32.dll", EntryPoint = "ToUnicode", CharSet = CharSet.Auto)]
@@ -352,6 +377,92 @@
352377 }
353378 }
354379
380+ public enum GetWindowOption : uint{
381+ First = 0,
382+ Last = 1,
383+ Next = 2,
384+ Prev = 3,
385+ Owner = 4,
386+ Child = 5,
387+ EnabledPopup = 6,
388+ }
389+
390+ public enum GetWindowLongOption : int{
391+ WndProc = (-4),
392+ HInstance = (-6),
393+ HwndParent = (-8),
394+ Style = (-16),
395+ ExStyle = (-20),
396+ UserData = (-21),
397+ Id = (-12),
398+ }
399+
400+ public enum GetClassLongOption : int{
401+ MenuName = (-8),
402+ HbrBackground = (-10),
403+ HCursor = (-12),
404+ HIcon = (-14),
405+ HModule = (-16),
406+ WndProc = (-24),
407+ HIconSmall = (-34),
408+ }
409+
410+ [Flags]
411+ public enum WindowStyle : uint{
412+ Overlapped = 0x00000000,
413+ Popup = 0x80000000,
414+ Child = 0x40000000,
415+ Minimize = 0x20000000,
416+ Visible = 0x10000000,
417+ Disabled = 0x08000000,
418+ ClipSiblings = 0x04000000,
419+ ClipChildren = 0x02000000,
420+ Maximize = 0x01000000,
421+ Caption = 0x00C00000, /* WS_BORDER | WS_DLGFRAME */
422+ Border = 0x00800000,
423+ DialogFrame = 0x00400000,
424+ VScroll = 0x00200000,
425+ HScroll = 0x00100000,
426+ SystemMenu = 0x00080000,
427+ ThickFrame = 0x00040000,
428+ Group = 0x00020000,
429+ TabStop = 0x00010000,
430+
431+ MinimizeBox = 0x00020000,
432+ MaximizeBox = 0x00010000,
433+
434+ Tiled = Overlapped,
435+ Iconic = Minimize,
436+ SizeBox = ThickFrame,
437+ TiledWindows = OverlappedWindow,
438+
439+ /*
440+ * Common Window Styles
441+ */
442+ OverlappedWindow = (Overlapped | Caption | SystemMenu | ThickFrame | MinimizeBox | MaximizeBox),
443+ PopupWindow = (Popup | Border | SystemMenu),
444+ ChildWindow = (Child),
445+ }
446+
447+ [Flags]
448+ public enum SetWindowPosOptions : uint{
449+ NoSize = 0x0001,
450+ NoMove = 0x0002,
451+ NoZOrder = 0x0004,
452+ NoRedraw = 0x0008,
453+ NoActivate = 0x0010,
454+ FrameChanged = 0x0020, /* The frame changed: send WM_NCCALCSIZE */
455+ ShowWindow = 0x0040,
456+ HideWindow = 0x0080,
457+ NoCopyBits = 0x0100,
458+ NoOwnerZOrder = 0x0200, /* Don't do owner Z ordering */
459+ NoSendChanging = 0x0400, /* Don't send WM_WINDOWPOSCHANGING */
460+ DrawFrane = FrameChanged,
461+ NoReposition = NoOwnerZOrder,
462+ Defererase = 0x2000,
463+ AsyncWindowPosition = 0x4000,
464+ }
465+
355466 public enum WindowMessage : uint{
356467 Null = 0x0000,
357468 Create = 0x0001,
--- kuon/trunk/Utilities/GFL.cs (revision 302)
+++ kuon/trunk/Utilities/GFL.cs (revision 303)
@@ -186,6 +186,60 @@
186186
187187 #endregion
188188
189+ #region Extended
190+
191+ const string GfleDllName = "libgfle311.dll";
192+
193+ [DllImport(GfleDllName, EntryPoint = "gflNegative", CharSet = CharSet.Auto)]
194+ public static extern Error Negative(ref Bitmap src, ref IntPtr dst);
195+
196+ [DllImport(GfleDllName, EntryPoint = "gflReduceNoise", CharSet = CharSet.Auto)]
197+ public static extern Error ReduceNoise(ref Bitmap src, ref IntPtr dst);
198+
199+ [DllImport(GfleDllName, EntryPoint = "gflLogCorrection", CharSet = CharSet.Auto)]
200+ public static extern Error LogCorrection(ref Bitmap src, ref IntPtr dst);
201+
202+ [DllImport(GfleDllName, EntryPoint = "gflNormalize", CharSet = CharSet.Auto)]
203+ public static extern Error Normalize(ref Bitmap src, ref IntPtr dst);
204+
205+ [DllImport(GfleDllName, EntryPoint = "gflEqualize", CharSet = CharSet.Auto)]
206+ public static extern Error Equalize(ref Bitmap src, ref IntPtr dst);
207+
208+ [DllImport(GfleDllName, EntryPoint = "gflEqualizeOnLuminance", CharSet = CharSet.Auto)]
209+ public static extern Error EqualizeOnLuminance(ref Bitmap src, ref IntPtr dst);
210+
211+ [DllImport(GfleDllName, EntryPoint = "gflAutomaticContrast", CharSet = CharSet.Auto)]
212+ public static extern Error AutomaticContrast(ref Bitmap src, ref IntPtr dst);
213+
214+ [DllImport(GfleDllName, EntryPoint = "gflAutomaticLevels", CharSet = CharSet.Auto)]
215+ public static extern Error AutomaticLevels(ref Bitmap src, ref IntPtr dst);
216+
217+ [DllImport(GfleDllName, EntryPoint = "gflEnhanceDetail", CharSet = CharSet.Auto)]
218+ public static extern Error EnhanceDetail(ref Bitmap src, ref IntPtr dst);
219+
220+ [DllImport(GfleDllName, EntryPoint = "gflEnhanceFocus", CharSet = CharSet.Auto)]
221+ public static extern Error EnhanceFocus(ref Bitmap src, ref IntPtr dst);
222+
223+ [DllImport(GfleDllName, EntryPoint = "gflFocusRestoration", CharSet = CharSet.Auto)]
224+ public static extern Error FocusRestoration(ref Bitmap src, ref IntPtr dst);
225+
226+ [DllImport(GfleDllName, EntryPoint = "gflEdgeDetectLight", CharSet = CharSet.Auto)]
227+ public static extern Error EdgeDetectLight(ref Bitmap src, ref IntPtr dst);
228+
229+ [DllImport(GfleDllName, EntryPoint = "gflEdgeDetectMedium", CharSet = CharSet.Auto)]
230+ public static extern Error EdgeDetectMedium(ref Bitmap src, ref IntPtr dst);
231+
232+ [DllImport(GfleDllName, EntryPoint = "gflEdgeDetectHeavy", CharSet = CharSet.Auto)]
233+ public static extern Error EdgeDetectHeavy(ref Bitmap src, ref IntPtr dst);
234+
235+ [DllImport(GfleDllName, EntryPoint = "gflEmboss", CharSet = CharSet.Auto)]
236+ public static extern Error Emboss(ref Bitmap src, ref IntPtr dst);
237+
238+ [DllImport(GfleDllName, EntryPoint = "gflEmbossMore", CharSet = CharSet.Auto)]
239+ public static extern Error EmbossMore(ref Bitmap src, ref IntPtr dst);
240+
241+ #endregion
242+
189243 #region Error
190244
191245 [DllImport(GflDllName, EntryPoint = "gflGetErrorString", CharSet = CharSet.Auto)]
@@ -602,7 +656,7 @@
602656 internal static GflBitmap GetGflBitmapFromFile(string path, GflProgressCallback progressCallback){
603657 Gfl.LoadParams prms = new Gfl.LoadParams();
604658 Gfl.GetDefaultLoadParams(ref prms);
605- prms.Options = Gfl.LoadOptions.ForceColorModel;
659+ prms.Options = Gfl.LoadOptions.ForceColorModel | Gfl.LoadOptions.IgnoreReadError | Gfl.LoadOptions.OnlyFirstFrame;
606660 prms.ColorModel = Gfl.BitmapType.Bgra;
607661 if(progressCallback != null){
608662 prms.Callbacks.Progress = new Gfl.ProgressCallback(delegate(int percent, IntPtr userParams){
@@ -667,9 +721,12 @@
667721 private Gfl.Bitmap bitmap;
668722 private GflFileInfo info;
669723
670- internal GflBitmap(Gfl.Bitmap bitmap, Gfl.FileInformation info){
724+ internal GflBitmap(Gfl.Bitmap bitmap, Gfl.FileInformation info) : this(bitmap, new GflFileInfo(info)){
725+ }
726+
727+ internal GflBitmap(Gfl.Bitmap bitmap, GflFileInfo info){
671728 this.bitmap = bitmap;
672- this.info = new GflFileInfo(info);
729+ this.info = info;
673730 }
674731
675732 public static GflBitmap FromFile(string path){
@@ -680,6 +737,15 @@
680737 return GflManager.GetGflBitmapFromFile(path, progressCallback);
681738 }
682739
740+ public GflBitmap ReduceNoise(){
741+ IntPtr ptr = IntPtr.Zero;
742+ if(Gfl.ReduceNoise(ref this.bitmap, ref ptr) == Gfl.Error.None){
743+ return new GflBitmap((Gfl.Bitmap)Marshal.PtrToStructure(ptr, typeof(Gfl.Bitmap)), this.info);
744+ }else{
745+ throw new InvalidOperationException();
746+ }
747+ }
748+
683749 public Drawing.Bitmap ToBitmap(){
684750 int length = (int)this.bitmap.BytesPerLine * this.bitmap.Height;
685751
@@ -704,6 +770,16 @@
704770 }
705771 }
706772
773+ private GflExif exif = null;
774+ public GflExif Exif{
775+ get{
776+ if(this.exif == null){
777+ this.exif = new GflExif(Gfl.GetExif(ref this.bitmap, Gfl.GetExifOptions.None));
778+ }
779+ return this.exif;
780+ }
781+ }
782+
707783 private bool disposed = false;
708784 protected override void Dispose(bool disposing){
709785 if(disposing){
--- kuon/trunk/Document/history.ja.txt (revision 302)
+++ kuon/trunk/Document/history.ja.txt (revision 303)
@@ -8,6 +8,9 @@
88 -改善: ファイル一覧表示処理を高速化。
99 -改善: 起動を高速化。
1010 -改善: 自動更新処理をバックグラウンドで行うように。
11+-改善: アイコンを描き直し。
12+-改善: ファイラの移動履歴を保存するようにした。
13+-改善: リネームマクロ展開をバックグラウンドで行うようにした。
1114
1215 **0.4.0.0β4 (2009-06-18)
1316 -改善: セットアップをInnoSetupに変更。
--- kuon/trunk/Document/Manual/ReplacementMacro.ja.txt (revision 302)
+++ kuon/trunk/Document/Manual/ReplacementMacro.ja.txt (revision 303)
@@ -27,6 +27,11 @@
2727 このアプリケーションが使用するスクリプトを置くディレクトリに置換します。
2828 通常は"$(ExeDir)\Script"です。
2929
30+**$(Global:ResourceDir)
31+ このアプリケーションが使用するリソースを置くディレクトリに置換します。
32+ 通常は"$(ExeDir)\Resource"です。
33+
34+
3035 **$(Global:SpecialFolder:FolderName)
3136 特殊フォルダのパスを取得します。
3237 FolderNameに以下の特殊フォルダ名を指定します。
Show on old repository browser