lantool

ein feines Tool für LANs (damals)
git clone https://git.clttr.info/lantool.git
Log (Feed) | Files | Refs (Tags) | README | LICENSE

commit 49a1f97562e8a4c7253029e729aacf89d6e2f2f0
parent fa9033672a2cb83c117b37181c996bd58f33f591
Author: rwa <apollo@rw-net.de>
Date:   Thu,  6 Sep 2018 19:36:16 +0200

commit code

Diffstat:
ALanTool.sln | 36++++++++++++++++++++++++++++++++++++
ALanTool/AboutBox.Designer.cs | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/AboutBox.cs | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/AboutBox.resx | 777+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/Config.cs | 568+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/Enums.cs | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/GlobalCache.cs | 297+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/NativeMethods.cs | 12++++++++++++
ALanTool/Classes/StuffItem.cs | 648+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/StuffItemPair.cs | 13+++++++++++++
ALanTool/Classes/StuffItemTree.cs | 304+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/TaskBarList.cs | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Classes/TreeViewExtensions.cs | 28++++++++++++++++++++++++++++
ALanTool/ConfigEdit.Designer.cs | 386+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/ConfigEdit.cs | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/ConfigEdit.resx | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/ConfigListBox.Designer.cs | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/ConfigListBox.cs | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/ConfigListBox.resx | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Configurations/rw-net.ruleset | 20++++++++++++++++++++
ALanTool/Configurations/rw-net.snk | 0
ALanTool/Dokumentation/Abgelehnt.txt | 9+++++++++
ALanTool/Dokumentation/LanTool_ChangeLog.txt | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Dokumentation/LanTool_Tipps.txt | 31+++++++++++++++++++++++++++++++
ALanTool/Dokumentation/ToDo.txt | 36++++++++++++++++++++++++++++++++++++
ALanTool/FilterDialog.Designer.cs | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/FilterDialog.cs | 28++++++++++++++++++++++++++++
ALanTool/FilterDialog.resx | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/GlobalSuppressions.cs | 41+++++++++++++++++++++++++++++++++++++++++
ALanTool/Images/Aktualisieren.png | 0
ALanTool/Images/DateiError.png | 0
ALanTool/Images/DateiExcluded.png | 0
ALanTool/Images/DateiExcludedAndDeleted.png | 0
ALanTool/Images/DateiFrischGesaugt.png | 0
ALanTool/Images/DateiGruen.png | 0
ALanTool/Images/DateiLoeschen.png | 0
ALanTool/Images/DateiRot.png | 0
ALanTool/Images/DateiSaugen.png | 0
ALanTool/Images/DateiWeiss.png | 0
ALanTool/Images/Demarkieren.png | 0
ALanTool/Images/DownArrow.png | 0
ALanTool/Images/Entfernen.png | 0
ALanTool/Images/Hinzufuegen.png | 0
ALanTool/Images/Markieren.png | 0
ALanTool/Images/Oeffnen.png | 0
ALanTool/Images/Ordner.png | 0
ALanTool/Images/OrdnerLoeschen.png | 0
ALanTool/Images/UpArrow.png | 0
ALanTool/Images/Zuklappen.png | 0
ALanTool/Images/newcap.ico | 0
ALanTool/LanTool.csproj | 274+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/MainForm.Designer.cs | 611+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/MainForm.cs | 2363+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/MainForm.resx | 344+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/NewFolderDialog.cs | 29+++++++++++++++++++++++++++++
ALanTool/NewFolderDialog.designer.cs | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/NewFolderDialog.resx | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Program.cs | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Properties/AssemblyInfo.cs | 36++++++++++++++++++++++++++++++++++++
ALanTool/Properties/Resources.Designer.cs | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Properties/Resources.resx | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Properties/app.manifest | 48++++++++++++++++++++++++++++++++++++++++++++++++
ALanTool/Resources/DeleteHS.png | 0
ALanTool/Resources/EditTableHS.png | 0
ALanTool/Resources/FindHS.png | 0
ALanTool/Resources/HTMLPage.png | 0
ALanTool/Resources/OpenFile.png | 0
ALanTool/Resources/openfolderHS.png | 0
ALanTool/Resources/saveHS.png | 0
ALanTool/app.config | 3+++
70 files changed, 9450 insertions(+), 0 deletions(-)

diff --git a/LanTool.sln b/LanTool.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanTool", "LanTool\LanTool.csproj", "{30E17D21-D90E-4069-9C40-E960119BA296}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30E17D21-D90E-4069-9C40-E960119BA296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30E17D21-D90E-4069-9C40-E960119BA296}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30E17D21-D90E-4069-9C40-E960119BA296}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30E17D21-D90E-4069-9C40-E960119BA296}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(SourceCodeControl) = preSolution + SccNumberOfProjects = 2 + SccLocalPath0 = . + SccProjectUniqueName1 = LanTool\\LanTool.csproj + SccLocalPath1 = . + SccProjectFilePathRelativizedFromConnection1 = LanTool\\ + EndGlobalSection + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = LanTool.vsmdi + EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection +EndGlobal diff --git a/LanTool/AboutBox.Designer.cs b/LanTool/AboutBox.Designer.cs @@ -0,0 +1,185 @@ +namespace LanTool +{ + partial class AboutBox + { + /// <summary> + /// Erforderliche Designervariable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Verwendete Ressourcen bereinigen. + /// </summary> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Windows Form-Designer generierter Code + + /// <summary> + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// </summary> + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox)); + this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this.logoPictureBox = new System.Windows.Forms.PictureBox(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.labelCompanyName = new System.Windows.Forms.Label(); + this.textBoxDescription = new System.Windows.Forms.TextBox(); + this.okButton = new System.Windows.Forms.Button(); + this.tableLayoutPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); + this.SuspendLayout(); + // + // tableLayoutPanel + // + this.tableLayoutPanel.ColumnCount = 2; + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 160F)); + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0); + this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0); + this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1); + this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2); + this.tableLayoutPanel.Controls.Add(this.labelCompanyName, 1, 3); + this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 1, 4); + this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5); + this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9); + this.tableLayoutPanel.Name = "tableLayoutPanel"; + this.tableLayoutPanel.RowCount = 6; + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.Size = new System.Drawing.Size(480, 244); + this.tableLayoutPanel.TabIndex = 0; + // + // logoPictureBox + // + this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.logoPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("logoPictureBox.Image"))); + this.logoPictureBox.Location = new System.Drawing.Point(3, 3); + this.logoPictureBox.Name = "logoPictureBox"; + this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6); + this.logoPictureBox.Size = new System.Drawing.Size(154, 272); + this.logoPictureBox.TabIndex = 12; + this.logoPictureBox.TabStop = false; + // + // labelProductName + // + this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelProductName.Location = new System.Drawing.Point(166, 0); + this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); + this.labelProductName.MaximumSize = new System.Drawing.Size(0, 21); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(311, 21); + this.labelProductName.TabIndex = 19; + this.labelProductName.Text = "Produktname"; + this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // labelVersion + // + this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelVersion.Location = new System.Drawing.Point(166, 21); + this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); + this.labelVersion.MaximumSize = new System.Drawing.Size(0, 21); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(311, 21); + this.labelVersion.TabIndex = 0; + this.labelVersion.Text = "Version"; + this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // labelCopyright + // + this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelCopyright.Location = new System.Drawing.Point(166, 42); + this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); + this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 21); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(311, 21); + this.labelCopyright.TabIndex = 21; + this.labelCopyright.Text = "Copyright"; + this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // labelCompanyName + // + this.labelCompanyName.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelCompanyName.Location = new System.Drawing.Point(166, 63); + this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0); + this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 21); + this.labelCompanyName.Name = "labelCompanyName"; + this.labelCompanyName.Size = new System.Drawing.Size(311, 21); + this.labelCompanyName.TabIndex = 22; + this.labelCompanyName.Text = "Firmenname"; + this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // textBoxDescription + // + this.textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxDescription.Location = new System.Drawing.Point(166, 87); + this.textBoxDescription.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3); + this.textBoxDescription.Multiline = true; + this.textBoxDescription.Name = "textBoxDescription"; + this.textBoxDescription.ReadOnly = true; + this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.textBoxDescription.Size = new System.Drawing.Size(311, 120); + this.textBoxDescription.TabIndex = 23; + this.textBoxDescription.TabStop = false; + this.textBoxDescription.Text = "Beschreibung"; + // + // okButton + // + this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.okButton.Location = new System.Drawing.Point(402, 213); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 24; + this.okButton.Text = "&OK"; + // + // AboutBox + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(498, 262); + this.Controls.Add(this.tableLayoutPanel); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutBox"; + this.Padding = new System.Windows.Forms.Padding(9); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "AboutBox"; + this.tableLayoutPanel.ResumeLayout(false); + this.tableLayoutPanel.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelVersion; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.Label labelCompanyName; + private System.Windows.Forms.TextBox textBoxDescription; + private System.Windows.Forms.PictureBox logoPictureBox; + private System.Windows.Forms.Button okButton; + } +} diff --git a/LanTool/AboutBox.cs b/LanTool/AboutBox.cs @@ -0,0 +1,101 @@ +using System; +using System.Reflection; +using System.Windows.Forms; + +namespace LanTool +{ + partial class AboutBox : Form + { + public AboutBox() + { + InitializeComponent(); + this.Text = String.Format("Info über {0}", AssemblyTitle); + this.labelProductName.Text = AssemblyProduct; + this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion); + this.labelCopyright.Text = AssemblyCopyright; + this.labelCompanyName.Text = AssemblyCompany; + this.textBoxDescription.Text = AssemblyDescription; + } + + #region Assemblyattributaccessoren + + public static string AssemblyTitle + { + get + { + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); + if (attributes.Length > 0) + { + AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; + if (!String.IsNullOrEmpty(titleAttribute.Title)) + { + return titleAttribute.Title; + } + } + return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); + } + } + + public static string AssemblyVersion + { + get + { + return Assembly.GetExecutingAssembly().GetName().Version.ToString(); + } + } + + public static string AssemblyDescription + { + get + { + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); + if (attributes.Length == 0) + { + return ""; + } + return ((AssemblyDescriptionAttribute)attributes[0]).Description; + } + } + + public static string AssemblyProduct + { + get + { + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); + if (attributes.Length == 0) + { + return ""; + } + return ((AssemblyProductAttribute)attributes[0]).Product; + } + } + + public static string AssemblyCopyright + { + get + { + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); + if (attributes.Length == 0) + { + return ""; + } + return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; + } + } + + public static string AssemblyCompany + { + get + { + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); + if (attributes.Length == 0) + { + return ""; + } + return ((AssemblyCompanyAttribute)attributes[0]).Company; + } + } + #endregion + + } +} diff --git a/LanTool/AboutBox.resx b/LanTool/AboutBox.resx @@ -0,0 +1,776 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="logoPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + 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 + wtwUQIJvbG0swbZ4j5YWpibGBiYmBvZ2Vi7ODm6ujh7uLp4eCJsAf29fH08/Xx8fL6/IiLDwsOC42Mik + xLjEhJikxNjMjJSsjOTsjOSUxNjoiND4uEj4V18fbx8fHxkZmd99Yf6Qf8Dn58DGRC6cO5MY6VWQ7Fmc + 4lbN9efGOmZFGGeHsnND6LlB9CQ39dIozdok/Yp43ZJY3aYc2+xIk4woRz9H7UA3XXtz2ulj+9aKgUIO + bSQMQzLgwIhBQbE1a7x9vNLSUuLiYsLCQiLCQ8F6wsMCAwO8wbAAIfgxOMiP9xgS7A+/cXdzAvMCU4uM + CImOCgNUEuKjAbDkpLjYmIikhITY6Chudjo3K60wn1talF9eUlBWmltTVVxbXVJbVVxalJednlqQn12Q + z01MiIuNjT1w4MAfEp3fe9IQeW7ZuOHS2aPWJtSyDNeqVPOmbNuuEu+8KJ2MAGpOCDsniNmYajRU4tCT + YztQ5FAZzc4LptQkG1bE6+SFsjL9mQkehBg35bwIdlaYXrSvno0RlaAmL75z66aN6zasX7tp/frtm7ek + JaVWVJTl5eVkZKRlZ2WkpSZlZaZkZiSlpcanJMempiSkpyXBAeYFj/AjYBYfF5WdlZaXm5Wfl11YkFNW + WlheVlRRXpzDzSgrLSouymuor2qoq2htrOlsa+jtbunpbOjvae7raenraW1vaairKm9tqW9taSgqzC8q + Kjpx4sTvvTIf//P5W2thUQ0/SBUUFtLnkDIjTAtijRLcidH26rmhBvGe5NQAfGkMtSPXpLfIvLfItJNr + 1p5l3pph0pZp3lPgWBVnlO5DyfKn5YWwsoOYBeEAuV62n2qGPz7MQT3WWycvzq4g0b4yyyMz2iIz2r6+ + KLa5uqi5vrq6qqy+rrKhvqKpsbypsaK2pqi2urC+rhSAqa0qAxBqqsqqKkoK8rJLinJrq8ubGmpbm+va + Wxu7O1t6ulqvdLfX11Z2tbe0NtVNjg9OjPRNjw3NjA8uzo4szAwvzY3NTY3MTA6NDff293QND/QODVyp + q6mor68/e/bsxw/P7z/DlcRjjZiYiLCQsJDgpg0bgtwNCmMN6jKsKpPM49xJYfa4CAccN0QrN5TNDaYn + eapwgwmVsezmNMPmdOPqeMOCUGZJpGZZtH5DumVRtHZ1ollrtt1QhUd9ikl5vK6P2floN0ppomlniUdN + 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 +</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/Classes/Config.cs b/LanTool/Classes/Config.cs @@ -0,0 +1,568 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Windows.Forms; + +namespace LanTool.Classes +{ + /// <summary> + /// Enthält alle über die Konfiguration steuerbaren Parameter des LanTools + /// </summary> + public class Config + { + #region Konstanten für die Konfiguration + + /// Name der Configdatei + private const string _configFile = "LanTool.cfg"; + + #endregion + + #region Fields für Configsettings + + private List<string> _excludeExtension = new List<string>(); + private List<string> _restrictExtension = new List<string>(); + private int _md5FileSize = 10000; + private bool _autoScanMyDisks = false; + private bool _autoScanOtherDisks = false; + private bool _showIgnoredClones = false; + private bool _hideExcludedFiles = false; + private bool _hideExistingFiles = false; + private bool _removeMarks = false; + private bool _treatEqualNames = false; + private bool _lowerPriority = false; + private string _defaultOfflineFile = String.Empty; + private string _basePath; + private string _headerExtension = String.Empty; + + #endregion + + /// <summary> + /// Erstellt eine neue Instanz der Konfiguration + /// </summary> + /// <param name="basePath">Pfad zur LanTool-Executable, ist auch der Pfad zur Konfig-Datei</param> + public Config( string basePath ) + { + this._basePath = basePath; + + ReadConfig(); + } + + #region Properties für die Zugriffe auf die Konfiguration + + /// <summary> + /// Aktuelles Md5FileSize, Anzahl Bytes, die für die Hashwertberechnung genommen werden + /// </summary> + public string HeaderExtension + { + get + { + return _headerExtension; + } + } + + /// <summary> + /// Aktuelles Md5FileSize, Anzahl Bytes, die für die Hashwertberechnung genommen werden + /// </summary> + public int MD5FileSize + { + get + { + return _md5FileSize; + } + } + + /// <summary> + /// Standard-Offlinedatei, die beim Programmstart gelesen wird + /// </summary> + public string DefaultOfflineFile + { + get + { + return _defaultOfflineFile; + } + } + + /// <summary> + /// Prüfen, ob ein Pfadname durch die Extension weggelassen wird. + /// Die Restriction-Liste bleibt dabei unberücksichtig, da sie nur für Files gilt + /// </summary> + /// <param name="path">Pfad</param> + /// <returns>true wenn weggelassen</returns> + public bool IsDirExludedByExtension( string path ) + { + // Wenn kein Pfad angegeben ist, kann dieser auch nicht ausgeschlossen sein + if ( String.IsNullOrEmpty( path ) ) + { + return false; + } + + foreach ( string ext in _excludeExtension ) + { + if ( path.ToLower().EndsWith( ext.ToLower() ) ) + { + return true; + } + } + return false; + } + + /// <summary> + /// Prüfen, ob ein Pfadname durch Extension weggelassen wird. Dabei wird + /// zusätzlich die Restriktionsliste für Filenamen berücksichtigt, die nur bestimmte + /// Files zulässt. + /// </summary> + /// <param name="path"></param> + /// <returns></returns> + public bool IsFileExludedByExtension( string path ) + { + // Wenn kein Pfad angegeben ist, kann dieser auch nicht ausgeschlossen sein + if ( String.IsNullOrEmpty( path ) ) + { + return false; + } + + if ( IsDirExludedByExtension( path ) ) + { + return true; + } + // Wenn es Restriktionen gibt, nachsehen, ob diese Dateitypen angeschaut werden + if ( _restrictExtension.Count > 0 ) + { + foreach ( string ext in _restrictExtension ) + { + if ( path.ToLower().EndsWith( ext.ToLower() ) ) + { + return false; + } + } + return true; + } + return false; + } + + /// <summary> + /// Sollen die eigenen Platten automatisch neu eingescannt werden? + /// </summary> + public bool IsAutoScanMyDisks + { + get { return _autoScanMyDisks; } + } + + /// <summary> + /// Sollen die fremden Platten automatisch neu eingescannt werden? + /// </summary> + public bool IsAutoScanOtherDisks + { + get { return _autoScanOtherDisks; } + } + + /// <summary> + /// Gibt an ob erlaubte Dubletten eingeblendet werden sollen oder nicht + /// </summary> + public bool IsShowIgnoredClones + { + get { return _showIgnoredClones; } + } + + /// <summary> + /// Gibt an ob gesperrte Dateien im TreeView "Fremde Platten" + /// angezeigt werden sollen + /// </summary> + public bool IsHideExcludedFiles + { + get { return _hideExcludedFiles; } + } + + /// <summary> + /// Gibt an ob vorhandene Dateien im Tree "Fremde Platten" + /// angezeigt werden sollen + /// </summary> + public bool IsHideExistingFiles + { + get { return _hideExistingFiles; } + } + + /// <summary> + /// Liefert "true", wenn die Option "Markierungen nach Aktion entfernen" aktiviert ist + /// </summary> + public bool IsRemoveMarks + { + get { return _removeMarks; } + } + + /// <summary> + /// Liefert "true", wenn die Option "identische Dateinamen ausschließen" aktiviert ist + /// </summary> + public bool IsTreatEqualNames + { + get { return _treatEqualNames; } + } + + /// <summary> + /// Gibt an, ob das Programm mit verringerter Priorität ausgeführt werden soll + /// </summary> + public bool IsLowerPriority + { + get { return _lowerPriority; } + } + + #endregion + + /// <summary> + /// Config-File einlesen und MyDisks vorbelegen bzw. OtherDisks aktualisieren + /// </summary> + public void ReadConfig() + { + Boolean requireConfig = false; + + String file = Path.Combine( _basePath, _configFile ); + + // Standard-Konfig schreiben wenn keine vorhanden ist + if ( !File.Exists( file ) ) + { + requireConfig = CreateDefaultConfig( file ); + } + + Program.MainWindow.Log( "" ); + Program.MainWindow.Log( "Konfiguration:" ); + + // Konfigdatei einlesen + using ( StreamReader tr = File.OpenText( file ) ) + { + string line; + while ( ( line = tr.ReadLine() ) != null ) + { + string startChar = line.Substring( 0, 1 ); + + switch ( startChar ) + { + // Kommentarzeilen ignorieren + case "#": + continue; + + // Datei-Negativ-Filter + case "-": + _excludeExtension.Add( line.Substring( 1 ) ); + Program.MainWindow.Log( "Dateien/Ordner ausnehmen: *" + line.Substring( 1 ) ); + continue; + + // Datei-Positiv-Filter + case "+": + _restrictExtension.Add( line.Substring( 1 ) ); + Program.MainWindow.Log( "Erlaubte Dateien: *" + line.Substring( 1 ) ); + continue; + + // Konfigurationszeile + case "%": + GetSpecialSetting( line ); + continue; + + // meine Platten + default: + // bei nur Laufwerksbuchstaben ein \ dranhängen + if ( line.EndsWith( @":" ) ) + { + line = line + @"\"; + } + Program.MainWindow.Log( "Meine Platte: " + line ); + Program.MainWindow.m_MyDisks.AddOrGetChildItemByPath( line ); + + continue; + } + + } + } + Program.MainWindow.Log( "" ); + + // Konfig-Dialog aufrufen + if ( requireConfig ) + { + EditConfig(); + } + } + + private void GetSpecialSetting( string line ) + { + string[] cfg = line.Split( '=' ); + try + { + switch ( cfg[ 0 ].ToLower() ) + { + case "%autoscanmydisks": + _autoScanMyDisks = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "AutoScanMyDisks: " + _autoScanMyDisks ); + break; + + case "%autoscanotherdisks": + _autoScanOtherDisks = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "AutoScanOtherDisks: " + _autoScanOtherDisks ); + break; + + case "%showignoredclones": + _showIgnoredClones = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "ShowIgnoredClones: " + _showIgnoredClones ); + break; + + case "%hideexcludedfiles": + _hideExcludedFiles = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "HideExcludedFiles: " + _hideExcludedFiles ); + break; + + case "%hideexistingfiles": + _hideExistingFiles = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "HideExistingFiles: " + _hideExistingFiles ); + break; + + case "%head": + _md5FileSize = Convert.ToInt32( cfg[ 1 ] ); + Program.MainWindow.Log( "Headerlänge für MD5-Hash: " + MD5FileSize ); + break; + + case "%foreign": + Program.MainWindow.Log( "Fremde Platte: " + cfg[ 1 ] ); + Program.MainWindow.m_OtherDisks.AddOrGetChildItemByPath( cfg[ 1 ] ); + break; + + case "%removemarks": + _removeMarks = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "RemoveMarks: " + _removeMarks ); + break; + + case "%treatequalnames": + _treatEqualNames = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "TreatEqualNames: " + _treatEqualNames ); + break; + + case "%defaultofflinefile": + _defaultOfflineFile = cfg[ 1 ]; + Program.MainWindow.Log( "DefaultOfflineFile: " + _defaultOfflineFile ); + break; + + case "%lowerpriority": + _lowerPriority = Convert.ToBoolean( cfg[ 1 ] ); + Program.MainWindow.Log( "LowerPriority: " + _lowerPriority ); + break; + + case "%headerextension": + _headerExtension = cfg[ 1 ]; + Program.MainWindow.Log( "HeaderExtension: " + _headerExtension ); + break; + } + } + catch ( Exception e ) + { + Program.MainWindow.LogError( "Fehlerhaftes Setting: " + line + " / " + e.Message ); + } + } + + private static Boolean CreateDefaultConfig( String file ) + { + using ( StreamWriter cfgOut = new StreamWriter( file ) ) + { + cfgOut.Write( + @"# Laenge des MD5-Headers zum Dateivergleich +%head=10000 +# Endungen/Dateinamen die explizit ausgeschlossen werden (auch Ordner) +-.bmp +-.gif +-.m3u +-.tif +-.ini +-.db +-.nfo +-.htm +-.html +-.js +-lost+found +-System Volume Information +-RECYCLE.BIN +-RECYCLER +-RECYCLED" ); + } + + Program.MainWindow.Log( "Konfigurationsdatei LanTool.cfg wurde nicht gefunden. Erstelle neue Default-Datei." ); + return true; + } + + /// <summary> + /// Abspeichern der aktuellen Settings + /// </summary> + public void WriteConfig() + { + String file = Path.Combine( _basePath, _configFile ); + + using ( StreamWriter sw = File.CreateText( file ) ) + { + sw.WriteLine( "# Laenge des MD5-Headers zum Dateivergleich" ); + sw.WriteLine( "%head=" + _md5FileSize.ToString() ); + sw.WriteLine( "# Endungen/Dateinamen die explizit ausgeschlossen werden (auch Ordner)" ); + foreach ( string s in _excludeExtension ) + { + sw.WriteLine( "-" + s ); + } + sw.WriteLine( "# Endungen/Dateinamen die überhaupt gelesen werden (nur Dateien, keine Ordner)" ); + foreach ( string s in _restrictExtension ) + { + sw.WriteLine( "+" + s ); + } + sw.WriteLine( "# Eigene Platten" ); + foreach ( StuffItem si in Program.MainWindow.m_MyDisks.ChildItems ) + { + sw.WriteLine( si.Path ); + } + sw.WriteLine( "%AutoScanMyDisks=" + _autoScanMyDisks.ToString() ); + sw.WriteLine( "%ShowIgnoredClones=" + _showIgnoredClones.ToString() ); + sw.WriteLine( "# Fremde Platten" ); + foreach ( StuffItem si in Program.MainWindow.m_OtherDisks.ChildItems ) + { + sw.WriteLine( "%foreign=" + si.Path ); + } + sw.WriteLine( "%AutoScanOtherDisks=" + _autoScanOtherDisks.ToString() ); + sw.WriteLine( "%HideExcludedFiles=" + _hideExcludedFiles.ToString() ); + sw.WriteLine( "%HideExistingFiles=" + _hideExistingFiles.ToString() ); + sw.WriteLine( "%RemoveMarks=" + _removeMarks.ToString() ); + sw.WriteLine( "%TreatEqualNames=" + _treatEqualNames.ToString() ); + sw.WriteLine( "%DefaultOfflineFile=" + _defaultOfflineFile ); + sw.WriteLine( "%LowerPriority=" + _lowerPriority.ToString() ); + sw.WriteLine( "%HeaderExtension=" + _headerExtension ); + } + } + + /// <summary> + /// Konfiguration mittels Dialog aktualisieren + /// </summary> + /// <returns></returns> + public bool EditConfig() + { + // Dialog erstellen + using ( ConfigEdit ce = new ConfigEdit( _basePath ) ) + { + // alle aktuellen Einstellungen an den Dialog übergeben + ce.Md5FileSize = _md5FileSize; + ce.AutoScanMyDisks = _autoScanMyDisks; + ce.AutoScanOtherDisks = _autoScanOtherDisks; + ce.ShowIgnoredClones = _showIgnoredClones; + ce.HideExcludedFiles = _hideExcludedFiles; + ce.HideExistingFiles = _hideExistingFiles; + ce.RemoveMarks = _removeMarks; + ce.TreatEqualNames = _treatEqualNames; + ce.LowerPriority = _lowerPriority; + ce.DefaultOfflineFile = _defaultOfflineFile; + ce.HeaderExtension = _headerExtension; + + foreach ( StuffItem si in Program.MainWindow.m_OtherDisks.ChildItems ) + { + ce.otherDisks.Add( si.Path ); + } + foreach ( StuffItem si in Program.MainWindow.m_MyDisks.ChildItems ) + { + ce.myDisks.Add( si.Path ); + } + foreach ( string ex in _excludeExtension ) + { + ce.excludeExtension.Add( ex ); + } + foreach ( string ex in _restrictExtension ) + { + ce.restrictExtension.Add( ex ); + } + + // Wenn der Dialog mit "OK" abgeschlossen wurde, Einstellungen wieder zurückübernehmen + if ( ce.ShowDialog( Program.MainWindow ) == DialogResult.OK ) + { + _md5FileSize = ce.Md5FileSize; + _autoScanMyDisks = ce.AutoScanMyDisks; + _autoScanOtherDisks = ce.AutoScanOtherDisks; + _showIgnoredClones = ce.ShowIgnoredClones; + _hideExcludedFiles = ce.HideExcludedFiles; + _hideExistingFiles = ce.HideExistingFiles; + _removeMarks = ce.RemoveMarks; + _treatEqualNames = ce.TreatEqualNames; + _excludeExtension = ce.excludeExtension; + _restrictExtension = ce.restrictExtension; + _defaultOfflineFile = ce.DefaultOfflineFile; + _lowerPriority = ce.LowerPriority; + _headerExtension = ce.HeaderExtension; + + + + // nimmt nachher alle Elemente auf, die aus den RootItems entfernt werden + // müssen + List<StuffItem> delList = new List<StuffItem>(); + + // alle fremden Platten hinzufügen, alte entfernen + foreach ( string s in ce.otherDisks ) + { + Program.MainWindow.m_OtherDisks.AddOrGetChildItemByPath( s ); + } + + // alte Einträge in fremden Platten merken + foreach ( StuffItem csi in Program.MainWindow.m_OtherDisks.ChildItems ) + { + if ( !ce.otherDisks.Contains( csi.Path ) ) + { + delList.Add( csi ); + } + } + + // alte Einträge entfernen + foreach ( StuffItem csi in delList ) + { + Program.MainWindow.m_OtherDisks.ChildItems.Remove( csi ); + } + + delList.Clear(); + + // alle eigenen Platten hinzufügen + foreach ( string s in ce.myDisks ) + { + Program.MainWindow.m_MyDisks.AddOrGetChildItemByPath( s ); + } + + // alte Einträge in meinen Platten merken + foreach ( StuffItem csi in Program.MainWindow.m_MyDisks.ChildItems ) + { + if ( !ce.myDisks.Contains( csi.Path ) ) + { + delList.Add( csi ); + } + } + + // alte Einträge entfernen + foreach ( StuffItem csi in delList ) + { + Program.MainWindow.m_MyDisks.ChildItems.Remove( csi ); + } + + // Programm mit niedriger Priorität ausführen + if ( _lowerPriority ) + { + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; + } + else + { + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal; + } + + // Fenstertitel setzen + if ( !String.IsNullOrEmpty( _headerExtension ) ) + { + Program.MainWindow.Text = String.Format( "[{0}] {1}", HeaderExtension, MainForm.DefaultHeader ); + } + else + { + Program.MainWindow.Text = MainForm.DefaultHeader; + } + + // Konfigdatei abspeichern + WriteConfig(); + + return true; + } + } + + return false; + } + } +} diff --git a/LanTool/Classes/Enums.cs b/LanTool/Classes/Enums.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace LanTool.Classes +{ + /// <summary> + /// Auflistung der in der TreeView verfügbaren Icons + /// </summary> + public enum TreeNodeImage : int + { + /// <summary> + /// Ordner-Symbol + /// </summary> + Folder = 0, + /// <summary> + /// Ordner mit Lesefehler + /// </summary> + BrokenFolder = 1, + /// <summary> + /// Datei im "normalen" Zustand + /// </summary> + FileWhite = 2, + /// <summary> + /// Datei mit Dubletten + /// </summary> + FileRed = 3, + /// <summary> + /// Datei auf fremder Platte, noch nicht vorhanden + /// </summary> + FileSaugMich = 4, + /// <summary> + /// Datei auf fremden Platte, bereits vorhanden + /// </summary> + FileHabSchon = 5, + /// <summary> + /// Datei, frisch gesaugt + /// </summary> + FileFrischGesaugt = 6, + /// <summary> + /// Datei grün + /// </summary> + FileGruen = 7, + /// <summary> + /// Datei gesperrt + /// </summary> + FileExcluded = 8, + /// <summary> + /// Datei, Dubletten ignoriert + /// </summary> + FileIngored = 19, + /// <summary> + /// Datei mit Lesefehler + /// </summary> + FileError = 20 + } +} diff --git a/LanTool/Classes/GlobalCache.cs b/LanTool/Classes/GlobalCache.cs @@ -0,0 +1,297 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; + +namespace LanTool.Classes +{ + /// <summary> + /// Beinhaltet die globalen CacheListe des LanTools + /// </summary> + public class GlobalCache : IDisposable + { + #region Konstanten für die Caches + + private const string cHashKeyCacheFile = "LanTool.cache"; + private const string cHashKeyExcludeFile = "LanTool.exclude"; + private const string cHashKeyIgnoreFile = "LanTool.ignore"; + + #endregion + + #region Properties + + /// <summary> + /// Cache mit allen Hash-Werten von bekannten Dateien + /// </summary> + public SortedDictionary<string, string> HashCache { get; private set; } + /// <summary> + /// Cache mit allen Hash-Werten, die gesperrt sind + /// </summary> + public List<String> ExcludeCache { get; private set; } + /// <summary> + /// Cache mit allen Hash-Werten, bei denen Dubletten ignoriert werden + /// </summary> + public List<String> IgnoreCache { get; private set; } + + #endregion + + #region Fields mit den Caches + + private long hashOldInCache = 0; + private long hashNewInCache = 0; + private string _basePath; + + private MD5 md5; + + #endregion + + /// <summary> + /// Konstruktor für den globalen Cache + /// Legt die Cachelisten an und füllt diese von den Platten + /// </summary> + /// <param name="basePath">Standard-Pfad</param> + public GlobalCache(string basePath) + { + this._basePath = basePath; + + this.HashCache = new SortedDictionary<string, string>(); + this.ExcludeCache = new List<string>(); + this.IgnoreCache = new List<string>(); + + md5 = MD5.Create(); + + // Caches einlesen + LoadCacheFromDisk(); + LoadExcludeListFromDisk(); + LoadIgnoreListFromDisk(); + } + + /// <summary> + /// Speichert alle Liste auf Festplatte + /// </summary> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Speichert alle Liste auf Festplatte + /// </summary> + /// <param name="yes"></param> + protected virtual void Dispose(Boolean yes) + { + if (yes) + { + } + + SaveCacheToDisk(); + SaveExcludeListToDisk(); + SaveIgnoreListToDisk(); + } + + #region Behandlung der globalen Cache-Liste + + /// <summary> + /// MD5-Cache von der Platte laden + /// </summary> + private void LoadCacheFromDisk() + { + HashCache.Clear(); + if (File.Exists(_basePath + cHashKeyCacheFile)) + { + using (StreamReader cacheReader = File.OpenText(_basePath + cHashKeyCacheFile)) + { + string s; + while ((s = cacheReader.ReadLine()) != null) + { + if ( s.Length > 44 ) + { + HashCache[ s.Substring( 44 ) ] = s.Substring( 0, 43 ); + } + } + } + Program.MainWindow.Log(cHashKeyCacheFile + " wurde mit " + HashCache.Keys.Count.ToString() + " Einträgen geladen."); + } + else + { + Program.MainWindow.LogWarning(cHashKeyCacheFile + " nicht vorhanden."); + } + } + + /// <summary> + /// MD5-Cache auf Platte speichern + /// </summary> + public void SaveCacheToDisk() + { + try + { + using (StreamWriter sw = File.CreateText(_basePath + cHashKeyCacheFile)) + { + foreach (KeyValuePair<string, string> di in HashCache) + { + sw.WriteLine(di.Value + "/" + di.Key); + } + } + Program.MainWindow.Log(cHashKeyCacheFile + " wurde mit " + HashCache.Keys.Count.ToString() + " Einträgen gespeichert (" + hashNewInCache.ToString() + " neue Einträge, " + hashOldInCache.ToString() + " Treffer)"); + } + catch (Exception e) + { + Program.MainWindow.LogError(cHashKeyCacheFile + " konnte nicht gespeichert werden: " + e.Message); + } + } + + /// <summary> + /// Löschen des Hash-Caches + /// </summary> + public void Clear() + { + HashCache.Clear(); + + hashNewInCache = 0; + hashOldInCache = 0; + + SaveCacheToDisk(); + } + + /// <summary> + /// Aus Datei einen Hashkey erzeugen oder aus dem Cache entnehmen + /// </summary> + /// <param name="file">Datei</param> + /// <returns>Hash-Key</returns> + public string GetHashCodeFromFileHeader(string file) + { + if (String.IsNullOrEmpty(file)) + { + return String.Empty; + } + + Int32 md5HashSize = Program.MainWindow.m_Config.MD5FileSize; + + // Nachsehen, ob der Länge / Dateipfad gecached sind + if (HashCache.ContainsKey(md5HashSize + " " + file)) + { + hashOldInCache++; + return HashCache[md5HashSize + " " + file]; + } + + // wenn die Datei nicht existiert, keinen Fehler melden + // sondern leeren String, Datei wird später als Lesefehler markiert + if (!File.Exists(file)) + { + return String.Empty; + } + + try + { + // Teil 1 des Hashcodes ist die Dateigröße + FileInfo fi = new FileInfo(file); + string hash = fi.Length.ToString("X10"); + // Teil 2 des Hascode ist das md5 über x Bytes. Bei Netzwerkzugriff + // ist das etwas zu viel die ganzen Dateien zu lesen + byte[] buffer = new byte[md5HashSize]; + using (FileStream fs = fi.OpenRead()) + { + int gelesen = fs.Read(buffer, 0, md5HashSize); + + // Wenn die Datei leer ist, den Dateinamen nehmen + if (gelesen == 0) + { + for (int i = 0; i < file.Length; i++) + buffer[i] = (byte)file[i]; + } + } + + byte[] mdhash = md5.ComputeHash(buffer); + hash = "/" + hash; + foreach (byte b in mdhash) + { + hash = b.ToString("X2") + hash; + } + + // Im Cache ablegen für weitere Verwendung + HashCache[md5HashSize + " " + file] = hash; + hashNewInCache++; + return hash; + } + catch + { + return String.Empty; + } + } + + #endregion + + /// <summary> + /// Exclude-Liste von Platte laden + /// </summary> + private void LoadExcludeListFromDisk() + { + ExcludeCache.Clear(); + if (File.Exists(_basePath + cHashKeyExcludeFile)) + { + // Alle Zeilen der Datei in den Cache einlesen + ExcludeCache.AddRange(File.ReadAllLines(_basePath + cHashKeyExcludeFile)); + + Program.MainWindow.Log(cHashKeyExcludeFile + " wurde mit " + ExcludeCache.Count.ToString() + " Einträgen geladen"); + } + else + { + Program.MainWindow.LogWarning(cHashKeyExcludeFile + " nicht vorhanden."); + } + } + + /// <summary> + /// Exclude-Liste auf Platte speichern + /// </summary> + public void SaveExcludeListToDisk() + { + try + { + // Alle Zeilen des Exclude-Caches in die Datei schreiben + File.WriteAllLines(_basePath + cHashKeyExcludeFile, ExcludeCache.ToArray()); + + Program.MainWindow.Log(cHashKeyExcludeFile + " wurde mit " + ExcludeCache.Count.ToString() + " Einträgen gespeichert"); + } + catch (Exception e) + { + Program.MainWindow.LogError(cHashKeyExcludeFile + "konnte nicht gespeichert werden: " + e.Message); + } + } + + /// <summary> + /// Exclude-Liste von Platte laden + /// </summary> + private void LoadIgnoreListFromDisk() + { + IgnoreCache.Clear(); + if (File.Exists(_basePath + cHashKeyIgnoreFile)) + { + // Alle Zeilen in den IgnoreCache laden + IgnoreCache.AddRange(File.ReadAllLines(_basePath + cHashKeyIgnoreFile)); + + Program.MainWindow.Log(cHashKeyIgnoreFile + " wurde mit " + IgnoreCache.Count.ToString() + " Einträgen geladen"); + } + else + { + Program.MainWindow.LogWarning(cHashKeyIgnoreFile + " nicht vorhanden."); + } + } + + /// <summary> + /// Exclude-Liste auf Platte speichern + /// </summary> + public void SaveIgnoreListToDisk() + { + try + { + File.WriteAllLines(_basePath + cHashKeyIgnoreFile, IgnoreCache.ToArray()); + Program.MainWindow.Log(cHashKeyIgnoreFile + " wurde mit " + IgnoreCache.Count.ToString() + " Einträgen gespeichert"); + } + catch (Exception e) + { + Program.MainWindow.LogError(cHashKeyIgnoreFile + "konnte nicht gespeichert werden: " + e.Message); + } + } + } +} diff --git a/LanTool/Classes/NativeMethods.cs b/LanTool/Classes/NativeMethods.cs @@ -0,0 +1,12 @@ +using System; +using System.Runtime.InteropServices; + +namespace LanTool.Classes +{ + static class NativeMethods + { + // Import the SetForeground API to activate it + [DllImport("User32.dll")] + public static extern IntPtr SetForegroundWindow(int hWnd); + } +} diff --git a/LanTool/Classes/StuffItem.cs b/LanTool/Classes/StuffItem.cs @@ -0,0 +1,648 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace LanTool.Classes +{ + internal class StuffItemSorter : System.Collections.IComparer + { + public int Compare( object xx, object yy ) + { + StuffItem x = ( StuffItem )( ( System.Windows.Forms.TreeNode )xx ).Tag; + StuffItem y = ( StuffItem )( ( System.Windows.Forms.TreeNode )yy ).Tag; + string xa = ( x == null ) ? "0" : ( x.IsFile ? "2" + x.Path : "1" + x.Path ); + string ya = ( y == null ) ? "0" : ( y.IsFile ? "2" + y.Path : "1" + y.Path ); + return String.Compare( xa, ya ); + } + } + + /// <summary> + /// Ein Ding des Begehrs, sei es auf der eigenen oder der fremden Platte + /// </summary> + internal class StuffItem + { + #region Parameter eines StuffItems + + /// <summary> + /// Übergeordnetes StuffItem + /// </summary> + public StuffItem Parent = null; + + private string _name = String.Empty; + /// <summary> + /// Name des StuffItems + /// z.B. Dateiname ohne Pfad oder Name des Verzeichnisses + /// </summary> + public string Name + { + get + { + // Field ist noch nicht gefüllt, dann Name aus dem Dateiname oder dem Verzeichnisname ermitteln + if ( String.IsNullOrEmpty( _name ) ) + { + if ( IsFile ) + { + _name = System.IO.Path.GetFileName( Path ); + } + else + { + _name = Path.Substring( Path.LastIndexOf( "\\" ) + 1 ); + } + } + + return _name; + } + private set + { + _name = value; + } + + } + + /// <summary> + /// Kompletter Pfad zum StuffItems + /// </summary> + public string Path = String.Empty; + + /// <summary> + /// Liste aller direkt untergeordneten StuffItems + /// </summary> + public List<StuffItem> ChildItems = new List<StuffItem>(); + + /// <summary> + /// MD5-Hashwert des StuffItems + /// </summary> + public string Hash = ""; + + /// <summary> + /// Dateigröße + /// </summary> + public long Size; + + /// <summary> + /// Dateigröße in lesbarer Ausgabe + /// </summary> + public string ReadableSize + { + get + { + if ( this.Size > 1024 * 1024 ) + return ( ( ( double )( this.Size / 104857 ) ) / 10 ).ToString() + " MB"; + else + return ( ( ( double )( this.Size / 102 ) ) / 10 ).ToString() + " KB"; + } + } + + /// <summary> + /// Dateigröße in Byte-Ausgabe + /// </summary> + public string LongSize + { + get + { + // Zahlenformat: mit 1000er-Punkten ohne Nachkommastellen + return String.Format( "{0:N0} Bytes", this.Size ); + } + } + + private bool _checked = false; + /// <summary> + /// Dateien, die markiert sind aber nicht sichtbar, werden als nicht markiert gehandhabt + /// </summary> + public bool Checked + { + get + { + return _checked && IsVisible; + } + set + { + _checked = value; + } + } + + private bool updateCheck = true; + + private bool _isOnline = true; + /// <summary> + /// Online und Offline wird grundsätzlich für den ganzen Zweig darunter gesetzt + /// </summary> + public bool IsOnline + { + get + { + return _isOnline; + } + set + { + _isOnline = value; + foreach ( StuffItem si in ChildItems ) + si.IsOnline = value; + } + } + + /// <summary> + /// True wenn es sich um eine Datei handelt + /// </summary> + public bool IsFile = false; + + /// <summary> + /// Legt das Icon für die Dateien/Ordner fest + /// </summary> + public TreeNodeImage Icon + { + get + { + if ( this.HasReadError ) + { + if ( this.IsFile ) + { + return TreeNodeImage.FileError; + } + else + { + return TreeNodeImage.BrokenFolder; + } + } + else if ( !this.IsFile ) + { + return TreeNodeImage.Folder; + } + else if ( this.IsIgnored ) + { + return TreeNodeImage.FileIngored; + } + else if ( this.IsExcluded ) + { + return TreeNodeImage.FileExcluded; + } + else if ( this.HasClones ) + { + return TreeNodeImage.FileRed; + } + else if ( this.IsNeeded ) + { + return TreeNodeImage.FileSaugMich; + } + else if ( this.IsOnForeignDisk ) + { + return TreeNodeImage.FileHabSchon; + } + else + { + return TreeNodeImage.FileWhite; + } + } + } + + /// <summary> + /// Liefert den Anzeigetext für TreeNode fest + /// </summary> + public string Text + { + get + { + String dispName = Name.Substring( Name.LastIndexOf( "\\" ) + 1 ); + if ( Parent == Program.MainWindow.m_MyDisks || Parent == Program.MainWindow.m_OtherDisks ) + { + dispName = Name; + } + + if ( IsFile && !HasReadError ) + { + return String.Format( "{0} ({1})", dispName, ReadableSize ); + } + else + { + return dispName; + } + } + } + + /// <summary> + /// Gibt den ToolTip-Text für die Datei zurück + /// </summary> + public string ToolTip + { + get + { + if ( !this.IsFile ) + { + return String.Empty; + } + + string temp; + + // Standardausgaben + temp = "Pfad: " + this.Path + Environment.NewLine; + + // die nachfolgenden Sachen nur anzeigen, wenn keine Lesefehler vorliegen + if ( this.HasReadError ) + { + temp += "Datei hat Lesefehler!"; + + return temp; + } + + temp += "Größe: " + this.LongSize + Environment.NewLine + + "Hash: " + this.Hash + Environment.NewLine; + + // bei schon auf vorhandenen Dateien auf den fremden Platten, die lokalen + // Dateien mit anzeigen + if ( IsOnForeignDisk && !IsNeeded && !IsExcluded ) + { + temp += Environment.NewLine + "Meine Platten: " + Environment.NewLine + + String.Join( Environment.NewLine, this.GetLocalFiles.ToArray() ); + } + + // bei Dubletten auf den eigenen Platten, diese anzeigen + if ( !IsOnForeignDisk && IsFile ) + { + List<StuffItem> clones = Program.MainWindow.m_MyDisks.GetItemClones( this ); + if ( clones.Count > 0 ) + { + temp += Environment.NewLine + "Dubletten: "; + foreach ( StuffItem csi in clones ) + { + temp += Environment.NewLine + csi.Path; + } + } + } + + return temp; + } + } + + /// <summary> + /// Gibt an, ob die Datei im Tree sichtbar ist + /// betrifft nur tatsächliche Dateien auf fremden Platten + /// abhängig vom Status der Datei und den eingestellten Optionen + /// </summary> + public bool IsVisible + { + get + { + // wenn keine Datei oder nicht auf fremden Platten - immer sichtbar + if ( !IsFile || !IsOnForeignDisk ) + { + return true; + } + else + { + // Dateien die gesperrt sind ausblenden falls Option aktiv + if ( IsExcluded && Program.MainWindow.m_Config.IsHideExcludedFiles ) + { + return false; + } + // Dateien die nicht gebraucht werden ausblenden falls Option aktiv + if ( !IsExcluded && !IsNeeded && Program.MainWindow.m_Config.IsHideExistingFiles ) + { + return false; + } + } + + return true; + } + } + + /// <summary> + /// True wenn die Datei ausgeschlossen ist + /// </summary> + public bool IsExcluded + { + get + { + return IsFile && Program.MainWindow.m_Cache.ExcludeCache.Contains( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + } + + /// <summary> + /// True wenn die Datei-Dubletten ignoriert werden + /// </summary> + public bool IsIgnored + { + get + { + return IsFile && !IsOnForeignDisk && HasClones && Program.MainWindow.m_Cache.IgnoreCache.Contains( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + } + + /// <summary> + /// Gibt an, ob beim Lesen des Verzeichnisses/der Datei ein Fehler aufgetreten ist + /// </summary> + public bool HasReadError = false; + + /// <summary> + /// Gibt ab, ob sich die Datei auf einer fremden Platte befindet + /// </summary> + public bool IsOnForeignDisk = false; + + /// <summary> + /// true, wenn die Datei noch nicht auf den eigenen Platten vorhanden ist und nicht + /// ausgeschlossen ist + /// </summary> + public bool IsNeeded + { + get + { + return IsFile && IsOnForeignDisk && !IsExcluded && + ( Program.MainWindow.m_MyDisks.GetRecursiveItemCount( this ) == 0 ); + } + } + + /// <summary> + /// Gibt alle lokalen Dateien eines StuffItems zurück + /// </summary> + public List<String> GetLocalFiles + { + get + { + List<String> localFiles = new List<String>(); + if ( Program.MainWindow.m_MyDisks.GetRecursiveItemCount( this ) > 0 ) + { + foreach ( StuffItem lsi in Program.MainWindow.m_MyDisks.GetItemsRecursive( this ) ) + { + localFiles.Add( lsi.Path ); + } + } + return localFiles; + } + } + + /// <summary> + /// Gibt alle Dateien auf fremden Platten eines StuffItems zurück + /// </summary> + public List<String> GetRemoteFiles + { + get + { + List<String> remoteFiles = new List<String>(); + if ( Program.MainWindow.m_OtherDisks.GetRecursiveItemCount( this ) > 0 ) + { + foreach ( StuffItem lsi in Program.MainWindow.m_OtherDisks.GetItemsRecursive( this ) ) + { + remoteFiles.Add( lsi.Path ); + } + } + return remoteFiles; + } + } + + public bool HasClones + { + get + { + return IsFile && !IsOnForeignDisk && Program.MainWindow.m_MyDisks.GetRecursiveItemCount( this ) > 1; + } + } + + /// <summary> + /// Speicher für Offline-Kopie der Directory-Anfragen + /// </summary> + virtual public Dictionary<string, List<string>> OfflineDirs + { + get + { + return Parent.OfflineDirs; + } + } + + /// <summary> + /// Speicher für Offline-Kopie der Files-Anfragen + /// </summary> + virtual public Dictionary<string, List<string>> OfflineFiles + { + get + { + return Parent.OfflineFiles; + } + } + + /// <summary> + /// Ein StuffItem für einen (Datei-)Pfad hinzufügen, falls + /// für diesen Pfad noch keines existiert + /// </summary> + /// <param name="path">Pfad</param> + /// <returns>Das alte oder neue Item</returns> + public StuffItem AddOrGetChildItemByPath( string path ) + { + // Altes Item suchen (nach Pfadnamen) + foreach ( StuffItem si in this.ChildItems ) + { + if ( si.Path.Equals( path ) ) + { + si.updateCheck = true; + return si; + } + } + + // Neues Item einhängen, wenn das alte nicht exisitert + StuffItem new_si = new StuffItem(); + new_si.IsOnForeignDisk = this.IsOnForeignDisk; + new_si.Name = path; + new_si.Path = path; + new_si.Parent = this; + new_si.IsOnline = IsOnline; + new_si.updateCheck = true; + this.ChildItems.Add( new_si ); + return new_si; + } + + #endregion + + #region Aktionen am Item + + /// <summary> + /// Datei sperren + /// </summary> + public void Exclude() + { + Program.MainWindow.m_Cache.ExcludeCache.Add( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + + /// <summary> + /// Gesperrte Datei wieder reinnehmen + /// </summary> + public void Include() + { + Program.MainWindow.m_Cache.ExcludeCache.Remove( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + + /// <summary> + /// Datei ignorieren + /// </summary> + public void Ignore() + { + Program.MainWindow.m_Cache.IgnoreCache.Add( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + + /// <summary> + /// Ignorierte Datei wieder reinnehmen + /// </summary> + public void UnIgnore() + { + Program.MainWindow.m_Cache.IgnoreCache.Remove( Program.MainWindow.m_Config.MD5FileSize + " " + this.Hash ); + } + + #endregion + + #region Platten scannen + + /// <summary> + /// ChildItems aktualisieren (background task) + /// </summary> + public void UpdateChildsBackground() + { + Program.RunBackgroundTask( this, "UpdateChilds", null ); + } + + /// <summary> + /// ChildItem aktualisieren und MainWindow neu aufbauen (Background Task) + /// </summary> + public void UpdateChilds( object state ) + { + // Statt der RootItems alle deren Kinder scannen + if ( this == Program.MainWindow.m_MyDisks || this == Program.MainWindow.m_OtherDisks ) + { + foreach ( StuffItem si in this.ChildItems.ToArray() ) + { + si.ScanChilds(); + } + } + else + { + this.ScanChilds(); + } + + // Die Caches des jeweiligen Trees aktualisieren, in der das Item aktualisiert wurde + Program.MainWindow.m_MyDisks.CreateStuffItemTreeHash(); + Program.MainWindow.m_OtherDisks.CreateStuffItemTreeHash(); + + // Baum neu zeichnen + Program.MainWindow.UpdateTrees(); + } + + /// <summary> + /// ChildItems eines Items von der Platte einlesen (rekursiv) und Hash-Werte ermitteln + /// </summary> + private void ScanChilds() + { + try + { + // Alle Childs markieren, dass sie nicht aktualisiert wurden + foreach ( StuffItem si in this.ChildItems ) + { + si.updateCheck = false; + } + + // Verzeichnisse lesen, die nicht "excluded" durch Extension sind + string[] dirs = GetDirectories; + foreach ( string dirname in dirs ) + { + if ( !Program.MainWindow.m_Config.IsDirExludedByExtension( dirname ) ) + { + StuffItem si = this.AddOrGetChildItemByPath( dirname ); + si.Path = dirname; + si.IsOnForeignDisk = this.IsOnForeignDisk; + si.ScanChilds(); + } + } + + // Files lesen, die nicht excluded sind. + // Bei "restricted" extensions werden nur diese gelesen, "excluded" zählt dann nicht + string[] files = GetFiles; + foreach ( string filename in files ) + { + if ( !Program.MainWindow.m_Config.IsFileExludedByExtension( filename ) ) + { + StuffItem si = AddOrGetChildItemByPath( filename ); + si.Path = filename; + si.IsFile = true; + si.IsOnForeignDisk = IsOnForeignDisk; + si.Hash = Program.MainWindow.m_Cache.GetHashCodeFromFileHeader( filename ); + // wenn kein Hash ermittelt wurde, kann die Datei nicht gelesen werden + if ( String.IsNullOrEmpty( si.Hash ) ) + { + si.HasReadError = true; + } + else + { + si.Size = Convert.ToInt64( si.Hash.Substring( 33 ), 16 ); + } + } + } + + // Nun alle Items wegwerfen, die kein Update hatten + for ( int i = ChildItems.Count - 1; i >= 0; i-- ) + { + if ( !ChildItems[ i ].updateCheck ) + { + ChildItems.RemoveAt( i ); + } + } + this.HasReadError = false; + } + catch ( Exception e ) + { + Program.MainWindow.LogError( "Fehler beim Einlesen: " + e.Message ); + this.HasReadError = true; + } + } + + /// <summary> + /// Verzeichnisse eines Pfades aus dem SimDirs oder physikalisch lesen. + /// </summary> + /// <returns></returns> + private string[] GetDirectories + { + get + { + if ( IsOnline ) + { + Program.MainWindow.Status( "Lese Verzeichnis (online): " + this.Path + " " ); + OfflineDirs[ Path ] = new List<string>( Directory.GetDirectories( Path ) ); + } + else + { + Program.MainWindow.Status( "Lese Verzeichnis (offline): " + this.Path + " " ); + } + if ( OfflineDirs.ContainsKey( Path ) ) + { + return OfflineDirs[ Path ].ToArray(); + } + else + { + return new string[] { }; + } + } + } + + /// <summary> + /// Files eines Pfades aus dem SimDirs oder physikalisch lesen. + /// </summary> + /// <returns></returns> + private string[] GetFiles + { + get + { + // bei Online-Dateien direkt von der Platte esen + if ( IsOnline ) + { + OfflineFiles[ Path ] = new List<string>( Directory.GetFiles( this.Path ) ); + } + + // Bei Offline-Dateien die Hashcaches prüfen + if ( OfflineFiles.ContainsKey( Path ) ) + { + return OfflineFiles[ Path ].ToArray(); + } + else + { + return new string[] { }; + } + } + } + + #endregion + } +} diff --git a/LanTool/Classes/StuffItemPair.cs b/LanTool/Classes/StuffItemPair.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace LanTool.Classes +{ + internal class StuffItemPair + { + public StuffItem Source; + public StuffItem Target; + } +} +\ No newline at end of file diff --git a/LanTool/Classes/StuffItemTree.cs b/LanTool/Classes/StuffItemTree.cs @@ -0,0 +1,303 @@ +using System.Collections.Generic; +using System.IO; +using LanTool.Classes; +using System; + +namespace LanTool +{ + internal class StuffItemTree : StuffItem + { + #region private fields + + private SortedDictionary<string, List<StuffItem>> stuffItemTreeByHash = new SortedDictionary<string, List<StuffItem>>(); + private SortedDictionary<string, List<StuffItem>> stuffItemTreeByName = new SortedDictionary<string, List<StuffItem>>(); + private long myDisksSpaceByClones = 0; + private long myDisksCountOfClones = 0; + private long myDisksCountOfAllowedClones = 0; + private long myDisksSpaceByAllowedClones = 0; + + #endregion + + /// <summary> + /// Root-Item der eigenen Platten + /// </summary> + public StuffItemTree(String path, Boolean isForeign) + { + Path = path; + IsOnForeignDisk = isForeign; + IsOnline = true; + } + + #region public methods + + public void CreateStuffItemTreeHash() + { + stuffItemTreeByHash.Clear(); + // Rücksetzen der Werte + myDisksCountOfClones = 0; + myDisksSpaceByClones = 0; + myDisksCountOfAllowedClones = 0; + myDisksSpaceByAllowedClones = 0; + // Füllen eigenen Disks + AddStuffItemToHashes( this ); + + if ( !IsOnForeignDisk ) + { + Program.MainWindow.Log( "Dublettensuche auf eigenen Platten..." ); + // Ausgabe der Ergebnisse der Dublettenprüfung + if ( myDisksCountOfClones == 0 && myDisksCountOfAllowedClones == 0 ) + { + Program.MainWindow.LogHighlight( "Keine doppelten Dateien in 'Meine Platten', gut aufgeräumt!" ); + } + else + { + Program.MainWindow.LogError( "Doppelte Dateien in 'Meine Platten': " + myDisksCountOfClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByClones / 104857 ) ) / 10 ).ToString() + " MB wertvoller Plattenplatz!" ); + Program.MainWindow.LogWarning( "Erlaubte doppelte Dateien in 'Meine Platten': " + myDisksCountOfAllowedClones.ToString() + ", das sind ca " + ( ( ( double )( myDisksSpaceByAllowedClones / 104857 ) ) / 10 ).ToString() + " MB Plattenplatz!" ); + } + } + } + + /// <summary> + /// Gibt die Dublettenliste des Items zurück (ohne das Item selbst). + /// Eine leere Liste bedeutet also, dass das Item keine Clones hat. + /// </summary> + public List<StuffItem> GetItemClones( StuffItem item ) + { + List<StuffItem> clonecopy = new List<StuffItem>(); + + // Alle Items mit dem gleichen Hash merken + List<StuffItem> clones = GetItemsRecursive( item ); + + // alle Items durchgehen und das Ursprungsitem wieder raussortieren + foreach ( StuffItem si in clones ) + { + if ( si != item ) + { + clonecopy.Add( si ); + } + } + return clonecopy; + } + + /// <summary> + /// Zurückgeben, wie oft ein Item (Hash-Test) im MyDisks hängt + /// </summary> + /// <param name="item"></param> + /// <returns></returns> + public int GetRecursiveItemCount( StuffItem item ) + { + return GetItemsRecursive( item ).Count; + } + + /// <summary> + /// Liefert alle StuffItems, die den gleichen Hash haben wie das übergebene + /// StuffItem + /// </summary> + /// <param name="item"></param> + /// <returns></returns> + public List<StuffItem> GetItemsRecursive( StuffItem item ) + { + List<StuffItem> retList = new List<StuffItem>(); + + // keine Dubletten bei Dateien mit Lesefehler + if ( item.HasReadError ) + { + return retList; + } + + // wenn die Datei in keiner Liste enthalten ist (weder Hash noch Name), dann raus + if ( !stuffItemTreeByHash.ContainsKey( item.Hash ) && !stuffItemTreeByName.ContainsKey( item.Name ) ) + { + return retList; + } + + // Alle Items by Hash ermitteln + if (stuffItemTreeByHash.ContainsKey( item.Hash ) ) + { + retList.AddRange( stuffItemTreeByHash[ item.Hash ] ); + } + + // restliche Prüfung nur, wenn die Namensprüfung angeschalten ist und die Datei auch enthalten ist + if ( Program.MainWindow.m_Config.IsTreatEqualNames && stuffItemTreeByName.ContainsKey( item.Name ) ) + { + // wenn die Datei überhaupt vorhanden ist, dann checken ob + foreach ( StuffItem si in stuffItemTreeByName[ item.Name ] ) + { + if ( !retList.Contains( si ) ) + { + retList.Add( si ); + } + } + } + + return retList; + } + + #endregion + + #region Private methods + + private void AddStuffItemToHashes( StuffItem si ) + { + // nur Dateien verarbeiten + if ( si.IsFile ) + { + // Name-Cache bearbeiten + if ( !stuffItemTreeByName.ContainsKey( si.Name ) ) + { + stuffItemTreeByName[ si.Name ] = new List<StuffItem>(); + stuffItemTreeByName[ si.Name ].Add( si ); + } + else + { + stuffItemTreeByName[ si.Name ].Add( si ); + } + + // Hash-Cache bearbeiten + if ( !stuffItemTreeByHash.ContainsKey( si.Hash ) ) + { + stuffItemTreeByHash[ si.Hash ] = new List<StuffItem>(); + stuffItemTreeByHash[ si.Hash ].Add( si ); + } + else + { + stuffItemTreeByHash[ si.Hash ].Add( si ); + if ( si.IsIgnored ) + { + try + { + myDisksSpaceByAllowedClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 ); + } + catch + { + } + myDisksCountOfAllowedClones++; + } + else + { + try + { + myDisksSpaceByClones += System.Convert.ToInt64( si.Hash.Substring( 33 ), 16 ); + } + catch + { + } + myDisksCountOfClones++; + } + } + } + else + { + // Verzeichnis -> alle Childs durchgehen + foreach ( StuffItem csi in si.ChildItems ) + { + AddStuffItemToHashes( csi ); + } + } + } + + internal void RemoveStuffItemFromHashes( StuffItem si ) + { + // StuffItem aus der Liste mit Hashes entfernen + stuffItemTreeByHash[ si.Hash ].Remove( si ); + + // StuffItem aus der Namensliste entfernen + stuffItemTreeByName[ si.Name ].Remove( si ); + } + + #endregion + + #region FileSystemCache für Offline-Betrieb + + private Dictionary<string, List<string>> offlineDirs = new Dictionary<string, List<string>>(); + private Dictionary<string, List<string>> offlineFiles = new Dictionary<string, List<string>>(); + + public override Dictionary<string, List<string>> OfflineDirs + { + get + { + return offlineDirs; + } + } + + public override Dictionary<string, List<string>> OfflineFiles + { + get + { + return offlineFiles; + } + } + + /// <summary> + /// Offline Cache in eine Datei schreiben + /// </summary> + /// <param name="filename"></param> + public void SaveOfflineCacheToFile( string filename ) + { + using ( StreamWriter sw = File.CreateText( filename ) ) + { + foreach ( string sa in offlineDirs.Keys ) + { + foreach ( string sb in offlineDirs[ sa ] ) + { + sw.WriteLine( "D|" + sa + "|" + sb ); + } + } + foreach ( string sa in offlineFiles.Keys ) + { + foreach ( string sb in offlineFiles[ sa ] ) + { + sw.WriteLine( "F|" + sa + "|" + sb ); + } + } + } + + Program.MainWindow.Log( "Offline-Verzeichnis wurde nach " + filename + " geschrieben" ); + } + + + /// <summary> + /// Offline-Cache aus einer Datei lesen + /// </summary> + /// <param name="filename"></param> + public void LoadOfflineCacheFromFile( string filename ) + { + using ( StreamReader sr = File.OpenText( filename ) ) + { + string line; + while ( ( line = sr.ReadLine() ) != null ) + { + string[] zeile = line.Split( '|' ); + if ( zeile[ 0 ] == "F" ) + { + if ( !OfflineFiles.ContainsKey( zeile[ 1 ] ) ) + { + OfflineFiles[ zeile[ 1 ] ] = new List<string>(); + } + OfflineFiles[ zeile[ 1 ] ].Add( zeile[ 2 ] ); + } + else + { + if ( !offlineDirs.ContainsKey( zeile[ 1 ] ) ) + { + offlineDirs[ zeile[ 1 ] ] = new List<string>(); + } + offlineDirs[ zeile[ 1 ] ].Add( zeile[ 2 ] ); + } + } + } + IsOnline = false; + } + + /// <summary> + /// Simulation des Filesystems abschalten und zurücksetzen + /// </summary> + public void ResetOfflineCaches() + { + offlineDirs.Clear(); + offlineFiles.Clear(); + } + + #endregion + } +} +\ No newline at end of file diff --git a/LanTool/Classes/TaskBarList.cs b/LanTool/Classes/TaskBarList.cs @@ -0,0 +1,101 @@ +using System; +using System.Runtime.InteropServices; + +namespace LanTool.Classes +{ + [ComImportAttribute()] + [GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + interface ITaskbarList3 + { + [PreserveSig] + void HrInit(); + [PreserveSig] + void AddTab(IntPtr hwnd); + [PreserveSig] + void DeleteTab(IntPtr hwnd); + [PreserveSig] + void ActivateTab(IntPtr hwnd); + [PreserveSig] + void SetActiveAlt(IntPtr hwnd); + + [PreserveSig] + void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen); + + void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal); + void SetProgressState(IntPtr hwnd, TBPFLAG tbpFlags); + void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI); + void UnregisterTab(IntPtr hwndTab); + void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore); + void SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, TBATFLAG tbatFlags); + void ThumbBarAddButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons); + void ThumbBarUpdateButtons(IntPtr hwnd, uint cButtons, [MarshalAs(UnmanagedType.LPArray)] THUMBBUTTON[] pButtons); + void ThumbBarSetImageList(IntPtr hwnd, IntPtr himl); + void SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, [MarshalAs(UnmanagedType.LPWStr)] string pszDescription); + void SetThumbnailTooltip(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszTip); + void SetThumbnailClip(IntPtr hwnd, ref RECT prcClip); + } + [GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")] + [ClassInterfaceAttribute(ClassInterfaceType.None)] + [ComImportAttribute()] + class TaskbarList { } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + struct THUMBBUTTON + { + [MarshalAs(UnmanagedType.U4)] + public THBMASK dwMask; + public uint iId; + public uint iBitmap; + public IntPtr hIcon; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string szTip; + [MarshalAs(UnmanagedType.U4)] + public THBFLAGS dwFlags; + } + enum THBMASK + { + THB_BITMAP = 0x1, + THB_ICON = 0x2, + THB_TOOLTIP = 0x4, + THB_FLAGS = 0x8 + } + + enum THBFLAGS + { + THBF_ENABLED = 0, + THBF_DISABLED = 0x1, + THBF_DISMISSONCLICK = 0x2, + THBF_NOBACKGROUND = 0x4, + THBF_HIDDEN = 0x8 + } + enum TBPFLAG + { + TBPF_NOPROGRESS = 0, + TBPF_INDETERMINATE = 0x1, + TBPF_NORMAL = 0x2, + TBPF_ERROR = 0x4, + TBPF_PAUSED = 0x8 + } + enum TBATFLAG + { + TBATF_USEMDITHUMBNAIL = 0x1, + TBATF_USEMDILIVEPREVIEW = 0x2 + } + struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + + [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", + Justification = "False positive" )] + public RECT(int left, int top, int right, int bottom) + { + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + } + } +} diff --git a/LanTool/Classes/TreeViewExtensions.cs b/LanTool/Classes/TreeViewExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Windows.Forms; + +namespace LanTool.Classes +{ + /// <summary> + /// ExtensionsMethods für das WinForms-TreeView-Control + /// </summary> + public static class TreeViewExtensions + { + /// <summary> + /// Einen einzelnen TreeNode in der kompletten Hierarchie suchen + /// </summary> + /// <param name="treeView">TreeView, dass durchsucht werden soll</param> + /// <param name="path">Name/Pfad des gesuchten TreeNode</param> + /// <returns>den TreeNode, wenn einer gefunden wird, ansonsten null</returns> + public static TreeNode FindSingleNode( this TreeView treeView, String path ) + { + if ( treeView == null ) + { + return null; + } + + TreeNode[] tn = treeView.Nodes.Find( path, true ); + return tn.Length > 0 ? tn[0] : null; + } + } +} diff --git a/LanTool/ConfigEdit.Designer.cs b/LanTool/ConfigEdit.Designer.cs @@ -0,0 +1,386 @@ +namespace LanTool +{ + partial class ConfigEdit + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConfigEdit)); + this.chkHideExcludedFiles = new System.Windows.Forms.CheckBox(); + this.chkShowIgnoredClones = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.chkAutoUpdateOtherDisks = new System.Windows.Forms.CheckBox(); + this.chkAutoUpdateMyDisks = new System.Windows.Forms.CheckBox(); + this.txtMD5Length = new System.Windows.Forms.TextBox(); + this.Md5Label = new System.Windows.Forms.Label(); + this.btnAbbruch = new System.Windows.Forms.Button(); + this.ttiConfig = new System.Windows.Forms.ToolTip(this.components); + this.chkLowerPriority = new System.Windows.Forms.CheckBox(); + this.txtHeaderExtension = new System.Windows.Forms.TextBox(); + this.lblTitelzeile = new System.Windows.Forms.Label(); + this.chkTreatEqualNames = new System.Windows.Forms.CheckBox(); + this.chkRemoveMarks = new System.Windows.Forms.CheckBox(); + this.chkHideExistingFiles = new System.Windows.Forms.CheckBox(); + this.btnRemoveDefaultOfflineFile = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.btnSelectDefaultOfflineFile = new System.Windows.Forms.Button(); + this.txtDefaultOfflineFile = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.OtherDisksBox = new LanTool.ConfigListBox(); + this.MyDisksBox = new LanTool.ConfigListBox(); + this.BlackListBox = new LanTool.ConfigListBox(); + this.WhiteListBox = new LanTool.ConfigListBox(); + this.SuspendLayout(); + // + // chkHideExcludedFiles + // + this.chkHideExcludedFiles.AutoSize = true; + this.chkHideExcludedFiles.Location = new System.Drawing.Point(717, 301); + this.chkHideExcludedFiles.Name = "chkHideExcludedFiles"; + this.chkHideExcludedFiles.Size = new System.Drawing.Size(166, 17); + this.chkHideExcludedFiles.TabIndex = 81; + this.chkHideExcludedFiles.Text = "gesperrte Dateien verstecken"; + this.ttiConfig.SetToolTip(this.chkHideExcludedFiles, "Ist diese Option aktiviert, so werden gesperrte Dateien\r\nnicht mehr in die Baumst" + + "ruktur eingetragen.\r\n\r\nEin Entsperren ist daher auch erst dann möglich, wenn\r\ndi" + + "ese Option deaktiviert wurde."); + this.chkHideExcludedFiles.UseVisualStyleBackColor = true; + // + // chkShowIgnoredClones + // + this.chkShowIgnoredClones.AutoSize = true; + this.chkShowIgnoredClones.Location = new System.Drawing.Point(485, 301); + this.chkShowIgnoredClones.Name = "chkShowIgnoredClones"; + this.chkShowIgnoredClones.Size = new System.Drawing.Size(168, 17); + this.chkShowIgnoredClones.TabIndex = 80; + this.chkShowIgnoredClones.Text = "erlaubte Dubletten einblenden"; + this.ttiConfig.SetToolTip(this.chkShowIgnoredClones, "Wenn aktiviert, werden erlaubte Dubletten beim Anzeigen der\r\nBaumstruktur behande" + + "lt wie normale Dubletten, d.h. die Pfade\r\nmit den Dubletten werden aufgeklappt."); + this.chkShowIgnoredClones.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(21, 278); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(438, 91); + this.label1.TabIndex = 77; + this.label1.Text = resources.GetString("label1.Text"); + // + // chkAutoUpdateOtherDisks + // + this.chkAutoUpdateOtherDisks.AutoSize = true; + this.chkAutoUpdateOtherDisks.Location = new System.Drawing.Point(717, 278); + this.chkAutoUpdateOtherDisks.Name = "chkAutoUpdateOtherDisks"; + this.chkAutoUpdateOtherDisks.Size = new System.Drawing.Size(145, 17); + this.chkAutoUpdateOtherDisks.TabIndex = 79; + this.chkAutoUpdateOtherDisks.Text = "automatisch aktualisieren"; + this.chkAutoUpdateOtherDisks.UseVisualStyleBackColor = true; + // + // chkAutoUpdateMyDisks + // + this.chkAutoUpdateMyDisks.AutoSize = true; + this.chkAutoUpdateMyDisks.Location = new System.Drawing.Point(485, 278); + this.chkAutoUpdateMyDisks.Name = "chkAutoUpdateMyDisks"; + this.chkAutoUpdateMyDisks.Size = new System.Drawing.Size(145, 17); + this.chkAutoUpdateMyDisks.TabIndex = 78; + this.chkAutoUpdateMyDisks.Text = "automatisch aktualisieren"; + this.chkAutoUpdateMyDisks.UseVisualStyleBackColor = true; + // + // txtMD5Length + // + this.txtMD5Length.Location = new System.Drawing.Point(217, 11); + this.txtMD5Length.MaxLength = 20; + this.txtMD5Length.Name = "txtMD5Length"; + this.txtMD5Length.Size = new System.Drawing.Size(100, 20); + this.txtMD5Length.TabIndex = 68; + this.ttiConfig.SetToolTip(this.txtMD5Length, resources.GetString("txtMD5Length.ToolTip")); + // + // Md5Label + // + this.Md5Label.AutoSize = true; + this.Md5Label.Location = new System.Drawing.Point(21, 14); + this.Md5Label.Name = "Md5Label"; + this.Md5Label.Size = new System.Drawing.Size(193, 13); + this.Md5Label.TabIndex = 67; + this.Md5Label.Text = "Bufferlänge für Dateivergleich (in Bytes)"; + this.ttiConfig.SetToolTip(this.Md5Label, resources.GetString("Md5Label.ToolTip")); + // + // btnAbbruch + // + this.btnAbbruch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnAbbruch.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnAbbruch.Location = new System.Drawing.Point(870, 378); + this.btnAbbruch.Name = "btnAbbruch"; + this.btnAbbruch.Size = new System.Drawing.Size(75, 23); + this.btnAbbruch.TabIndex = 86; + this.btnAbbruch.Text = "Abbruch"; + this.btnAbbruch.UseVisualStyleBackColor = true; + // + // ttiConfig + // + this.ttiConfig.AutoPopDelay = 10000; + this.ttiConfig.InitialDelay = 500; + this.ttiConfig.ReshowDelay = 100; + this.ttiConfig.ToolTipTitle = "Konfigurationserklärung"; + // + // chkLowerPriority + // + this.chkLowerPriority.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.chkLowerPriority.AutoSize = true; + this.chkLowerPriority.Location = new System.Drawing.Point(485, 382); + this.chkLowerPriority.Name = "chkLowerPriority"; + this.chkLowerPriority.Size = new System.Drawing.Size(212, 17); + this.chkLowerPriority.TabIndex = 88; + this.chkLowerPriority.Text = "Programm mit geringerer Priorität starten"; + this.ttiConfig.SetToolTip(this.chkLowerPriority, "Aktivieren Sie diese Option, wenn LanTool mit der Priorität \"niedriger als normal" + + "\" gestartet werden soll.\r\nDadurch stört LanTool laufende Spiele weniger."); + this.chkLowerPriority.UseVisualStyleBackColor = true; + // + // txtHeaderExtension + // + this.txtHeaderExtension.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txtHeaderExtension.Location = new System.Drawing.Point(217, 379); + this.txtHeaderExtension.MaxLength = 15; + this.txtHeaderExtension.Name = "txtHeaderExtension"; + this.txtHeaderExtension.Size = new System.Drawing.Size(100, 20); + this.txtHeaderExtension.TabIndex = 87; + this.ttiConfig.SetToolTip(this.txtHeaderExtension, "Dieser Text wird in der Programmtitelzeile des LanTool noch vor dem Programmnamen" + + " angezeigt."); + this.txtHeaderExtension.Validating += new System.ComponentModel.CancelEventHandler(this.txtHeaderExtension_Validating); + // + // lblTitelzeile + // + this.lblTitelzeile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblTitelzeile.AutoSize = true; + this.lblTitelzeile.Location = new System.Drawing.Point(21, 382); + this.lblTitelzeile.Name = "lblTitelzeile"; + this.lblTitelzeile.Size = new System.Drawing.Size(154, 13); + this.lblTitelzeile.TabIndex = 66; + this.lblTitelzeile.Text = "Kennzeichnung in der Titelzeile"; + this.ttiConfig.SetToolTip(this.lblTitelzeile, "Dieser Text wird in der Programmtitelzeile des LanTool noch vor dem Programmnamen" + + " angezeigt."); + // + // chkTreatEqualNames + // + this.chkTreatEqualNames.AutoSize = true; + this.chkTreatEqualNames.Location = new System.Drawing.Point(717, 347); + this.chkTreatEqualNames.Name = "chkTreatEqualNames"; + this.chkTreatEqualNames.Size = new System.Drawing.Size(199, 17); + this.chkTreatEqualNames.TabIndex = 84; + this.chkTreatEqualNames.Text = "identische Dateinamen ausschließen"; + this.ttiConfig.SetToolTip(this.chkTreatEqualNames, "Dateien auf den eigenen und den fremden Platten mit unterschiedlichen Hashes aber" + + " identischen Dateinamen werden als gleiche Dateien behandelt."); + this.chkTreatEqualNames.UseVisualStyleBackColor = true; + // + // chkRemoveMarks + // + this.chkRemoveMarks.AutoSize = true; + this.chkRemoveMarks.Location = new System.Drawing.Point(485, 324); + this.chkRemoveMarks.Name = "chkRemoveMarks"; + this.chkRemoveMarks.Size = new System.Drawing.Size(199, 17); + this.chkRemoveMarks.TabIndex = 82; + this.chkRemoveMarks.Text = "Markierungen nach Aktion entfernen"; + this.ttiConfig.SetToolTip(this.chkRemoveMarks, resources.GetString("chkRemoveMarks.ToolTip")); + this.chkRemoveMarks.UseVisualStyleBackColor = true; + // + // chkHideExistingFiles + // + this.chkHideExistingFiles.AutoSize = true; + this.chkHideExistingFiles.Location = new System.Drawing.Point(717, 324); + this.chkHideExistingFiles.Name = "chkHideExistingFiles"; + this.chkHideExistingFiles.Size = new System.Drawing.Size(179, 17); + this.chkHideExistingFiles.TabIndex = 83; + this.chkHideExistingFiles.Text = "vorhandene Dateien verstecken"; + this.ttiConfig.SetToolTip(this.chkHideExistingFiles, "Aktiviere diese Option, wenn Dateien, die bereits auf\r\nden eigenen Platten liegen" + + ", auf den fremden Platten nicht\r\nmehr angezeigt werden sollen."); + this.chkHideExistingFiles.UseVisualStyleBackColor = true; + // + // btnRemoveDefaultOfflineFile + // + this.btnRemoveDefaultOfflineFile.Image = global::LanTool.Properties.Resources.DeleteHS; + this.btnRemoveDefaultOfflineFile.Location = new System.Drawing.Point(920, 9); + this.btnRemoveDefaultOfflineFile.Name = "btnRemoveDefaultOfflineFile"; + this.btnRemoveDefaultOfflineFile.Size = new System.Drawing.Size(25, 23); + this.btnRemoveDefaultOfflineFile.TabIndex = 72; + this.btnRemoveDefaultOfflineFile.UseVisualStyleBackColor = true; + this.btnRemoveDefaultOfflineFile.Click += new System.EventHandler(this.btnRemoveDefaultOfflineFile_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(367, 14); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(156, 13); + this.label2.TabIndex = 69; + this.label2.Text = "Offline-Datei beim Starten laden"; + // + // btnSelectDefaultOfflineFile + // + this.btnSelectDefaultOfflineFile.Image = global::LanTool.Properties.Resources.OpenFile; + this.btnSelectDefaultOfflineFile.Location = new System.Drawing.Point(889, 9); + this.btnSelectDefaultOfflineFile.Name = "btnSelectDefaultOfflineFile"; + this.btnSelectDefaultOfflineFile.Size = new System.Drawing.Size(25, 23); + this.btnSelectDefaultOfflineFile.TabIndex = 71; + this.btnSelectDefaultOfflineFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.btnSelectDefaultOfflineFile.UseVisualStyleBackColor = true; + this.btnSelectDefaultOfflineFile.Click += new System.EventHandler(this.btnSelectDefaultOfflineFile_Click); + // + // txtDefaultOfflineFile + // + this.txtDefaultOfflineFile.Location = new System.Drawing.Point(529, 11); + this.txtDefaultOfflineFile.Name = "txtDefaultOfflineFile"; + this.txtDefaultOfflineFile.Size = new System.Drawing.Size(354, 20); + this.txtDefaultOfflineFile.TabIndex = 70; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(789, 378); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 85; + this.btnOK.Text = "OK"; + this.btnOK.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.OkButton_Click); + // + // OtherDisksBox + // + this.OtherDisksBox.HasFolderSelectButton = true; + this.OtherDisksBox.HasNewFolderButton = false; + this.OtherDisksBox.Header = "Fremde Platten"; + this.OtherDisksBox.Location = new System.Drawing.Point(708, 37); + this.OtherDisksBox.Name = "OtherDisksBox"; + this.OtherDisksBox.Size = new System.Drawing.Size(237, 234); + this.OtherDisksBox.Sorted = true; + this.OtherDisksBox.TabIndex = 76; + // + // MyDisksBox + // + this.MyDisksBox.HasFolderSelectButton = true; + this.MyDisksBox.HasNewFolderButton = true; + this.MyDisksBox.Header = "Meine Platten"; + this.MyDisksBox.Location = new System.Drawing.Point(476, 37); + this.MyDisksBox.Name = "MyDisksBox"; + this.MyDisksBox.Size = new System.Drawing.Size(226, 234); + this.MyDisksBox.Sorted = true; + this.MyDisksBox.TabIndex = 75; + // + // BlackListBox + // + this.BlackListBox.HasFolderSelectButton = false; + this.BlackListBox.HasNewFolderButton = false; + this.BlackListBox.Header = "Blacklist für Dateiendungen"; + this.BlackListBox.Location = new System.Drawing.Point(244, 37); + this.BlackListBox.Name = "BlackListBox"; + this.BlackListBox.Size = new System.Drawing.Size(226, 234); + this.BlackListBox.Sorted = false; + this.BlackListBox.TabIndex = 74; + // + // WhiteListBox + // + this.WhiteListBox.HasFolderSelectButton = false; + this.WhiteListBox.HasNewFolderButton = false; + this.WhiteListBox.Header = "Whitelist für Dateiendungen"; + this.WhiteListBox.Location = new System.Drawing.Point(12, 37); + this.WhiteListBox.Name = "WhiteListBox"; + this.WhiteListBox.Size = new System.Drawing.Size(226, 234); + this.WhiteListBox.Sorted = false; + this.WhiteListBox.TabIndex = 73; + // + // ConfigEdit + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(957, 413); + this.ControlBox = false; + this.Controls.Add(this.chkHideExcludedFiles); + this.Controls.Add(this.chkShowIgnoredClones); + this.Controls.Add(this.label1); + this.Controls.Add(this.chkAutoUpdateOtherDisks); + this.Controls.Add(this.chkAutoUpdateMyDisks); + this.Controls.Add(this.OtherDisksBox); + this.Controls.Add(this.MyDisksBox); + this.Controls.Add(this.BlackListBox); + this.Controls.Add(this.txtMD5Length); + this.Controls.Add(this.Md5Label); + this.Controls.Add(this.btnAbbruch); + this.Controls.Add(this.chkLowerPriority); + this.Controls.Add(this.txtHeaderExtension); + this.Controls.Add(this.lblTitelzeile); + this.Controls.Add(this.btnRemoveDefaultOfflineFile); + this.Controls.Add(this.label2); + this.Controls.Add(this.btnSelectDefaultOfflineFile); + this.Controls.Add(this.txtDefaultOfflineFile); + this.Controls.Add(this.chkTreatEqualNames); + this.Controls.Add(this.chkRemoveMarks); + this.Controls.Add(this.chkHideExistingFiles); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.WhiteListBox); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "ConfigEdit"; + this.Text = "LanTool - Konfiguration"; + this.Load += new System.EventHandler(this.ConfigEdit_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkHideExcludedFiles; + private System.Windows.Forms.ToolTip ttiConfig; + private System.Windows.Forms.CheckBox chkShowIgnoredClones; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox chkAutoUpdateOtherDisks; + private System.Windows.Forms.CheckBox chkAutoUpdateMyDisks; + private ConfigListBox OtherDisksBox; + private ConfigListBox MyDisksBox; + private ConfigListBox BlackListBox; + private System.Windows.Forms.TextBox txtMD5Length; + private System.Windows.Forms.Label Md5Label; + private System.Windows.Forms.Button btnAbbruch; + private System.Windows.Forms.CheckBox chkLowerPriority; + private System.Windows.Forms.TextBox txtHeaderExtension; + private System.Windows.Forms.Label lblTitelzeile; + private System.Windows.Forms.CheckBox chkTreatEqualNames; + private System.Windows.Forms.CheckBox chkRemoveMarks; + private System.Windows.Forms.CheckBox chkHideExistingFiles; + private System.Windows.Forms.Button btnRemoveDefaultOfflineFile; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Button btnSelectDefaultOfflineFile; + private System.Windows.Forms.TextBox txtDefaultOfflineFile; + private System.Windows.Forms.Button btnOK; + private ConfigListBox WhiteListBox; + + + + + } +} + diff --git a/LanTool/ConfigEdit.cs b/LanTool/ConfigEdit.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text.RegularExpressions; +using System.Windows.Forms; + +namespace LanTool +{ + /// <summary> + /// Formular zur Bearbeitung aller im LanTool bekannten Einstellungen + /// </summary> + internal partial class ConfigEdit: Form + { + public List<string> excludeExtension = new List<string>(); + public List<string> restrictExtension = new List<string>(); + public List<string> myDisks = new List<string>(); + public List<string> otherDisks = new List<string>(); + public int Md5FileSize = 10000; + public bool AutoScanMyDisks = false; + public bool AutoScanOtherDisks = false; + public bool ShowIgnoredClones = false; + public bool HideExcludedFiles = false; + public bool HideExistingFiles = false; + public bool RemoveMarks = false; + public bool TreatEqualNames = false; + public bool LowerPriority = false; + public string HeaderExtension = String.Empty; + public string DefaultOfflineFile = String.Empty; + + private string _basePath; + + /// <summary> + /// Konstruktor + /// </summary> + public ConfigEdit(string basePath) + { + InitializeComponent(); + + _basePath = basePath; + } + + private void ConfigEdit_Load(object sender, EventArgs e) + { + this.txtMD5Length.Text = Md5FileSize.ToString(); + this.chkAutoUpdateMyDisks.Checked = AutoScanMyDisks; + this.chkAutoUpdateOtherDisks.Checked = AutoScanOtherDisks; + this.chkShowIgnoredClones.Checked = ShowIgnoredClones; + this.chkHideExcludedFiles.Checked = HideExcludedFiles; + this.chkHideExistingFiles.Checked = HideExistingFiles; + this.chkRemoveMarks.Checked = RemoveMarks; + this.chkTreatEqualNames.Checked = TreatEqualNames; + this.chkLowerPriority.Checked = LowerPriority; + this.txtDefaultOfflineFile.Text = DefaultOfflineFile; + this.txtHeaderExtension.Text = HeaderExtension; + + foreach (string s in excludeExtension) + { + this.BlackListBox.Items.Add(s); + } + foreach (string s in restrictExtension) + { + this.WhiteListBox.Items.Add(s); + } + foreach (string s in myDisks) + { + this.MyDisksBox.Items.Add(s); + } + foreach (string s in otherDisks) + { + this.OtherDisksBox.Items.Add(s); + } + } + + private void OkButton_Click(object sender, EventArgs e) + { + try + { + this.Md5FileSize = System.Int32.Parse(this.txtMD5Length.Text); + } + catch + { + // Bei Fehleingaben ignorieren + } + AutoScanMyDisks = this.chkAutoUpdateMyDisks.Checked; + AutoScanOtherDisks = this.chkAutoUpdateOtherDisks.Checked; + ShowIgnoredClones = this.chkShowIgnoredClones.Checked; + HideExcludedFiles = this.chkHideExcludedFiles.Checked; + HideExistingFiles = this.chkHideExistingFiles.Checked; + RemoveMarks = this.chkRemoveMarks.Checked; + TreatEqualNames = this.chkTreatEqualNames.Checked; + DefaultOfflineFile = this.txtDefaultOfflineFile.Text; + LowerPriority = this.chkLowerPriority.Checked; + HeaderExtension = this.txtHeaderExtension.Text; + excludeExtension.Clear(); + foreach (string s in this.BlackListBox.Items) + { + excludeExtension.Add(s); + } + restrictExtension.Clear(); + foreach (string s in this.WhiteListBox.Items) + { + restrictExtension.Add(s); + } + myDisks.Clear(); + foreach (string s in this.MyDisksBox.Items) + { + myDisks.Add(s); + } + otherDisks.Clear(); + foreach (string s in this.OtherDisksBox.Items) + { + otherDisks.Add(s); + } + this.DialogResult = DialogResult.OK; + this.Close(); + } + + #region Eventhandler auf diverse Controls + + private void btnRemoveDefaultOfflineFile_Click(object sender, EventArgs e) + { + txtDefaultOfflineFile.Text = String.Empty; + } + + private void btnSelectDefaultOfflineFile_Click(object sender, EventArgs e) + { + using (OpenFileDialog fd = new OpenFileDialog()) + { + fd.Filter = "LanTool-Verzeichnis-Export (*.files)|*.files|Textdateien (*.txt)|*.txt"; + fd.DefaultExt = "*.files"; + fd.FileName = "MeinePlatten.files"; + fd.InitialDirectory = _basePath; + fd.CheckFileExists = true; + fd.CheckPathExists = true; + fd.Multiselect = false; + fd.AutoUpgradeEnabled = true; + if (fd.ShowDialog(this) == DialogResult.OK) + { + // wenn die Datei im gleichen Verzeichnis wie das LanTool liegt, + // dann nur den Dateinamen speichern + if (fd.FileName.StartsWith(_basePath)) + { + fd.FileName = fd.FileName.Remove(0, _basePath.Length); + } + txtDefaultOfflineFile.Text = fd.FileName; + } + } + } + + private void txtHeaderExtension_Validating(object sender, CancelEventArgs e) + { + if (!Regex.IsMatch(txtHeaderExtension.Text, "^[A-Za-z0-9_#+!]*$")) + { + MessageBox.Show("Es wurden ungültige Zeichen eingegeben." + Environment.NewLine + Environment.NewLine + + "Erlaubte Zeichen sind:" + Environment.NewLine + "Groß- und Kleinbuchstaben A bis Z" + Environment.NewLine + + "Ziffern 0 bis 9" + Environment.NewLine + "Sonderzeichen _ # + !"); + e.Cancel = true; + } + } + + #endregion + } +} diff --git a/LanTool/ConfigEdit.resx b/LanTool/ConfigEdit.resx @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <metadata name="ttiConfig.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>9, 18</value> + </metadata> + <data name="label1.Text" xml:space="preserve"> + <value>Mit der Whitelist kann die Suche auf bestimmte Dateiendungen eingeschränkt werden, +z.B. ".pdf" oder ".mp3". Solange kein Eintrag in der Liste ist, werden alle Dateien +gesucht, sonst nur die, deren Endungen in der Liste stehen. +Mit der Blacklist können gezielt Dateien und Ordner ausgenommen werden, z.B. ".mp3", +"Thumbs.db" oder "System Volume Information". Dateien erscheinen nicht, wenn das Ende +ihres Namens mit einem Eintrag in der Liste übereinstimmt. Die Blacklist wird auch auf +Verzeichnisnamen angewendet.</value> + </data> + <data name="txtMD5Length.ToolTip" xml:space="preserve"> + <value>Anzahl Bytes, die für die Ermittlung des Hashes der Datei +benutzt werden. +Achtung: Dieser Hash dient zur eindeutigen Identifizierung einer +Datei und sollte daher nicht zu klein gewählt werden, da es sonst zu +falschen Dublettenerkennungen kommen kann. +Große Werte erhöhen die allerdings Dauer für einen +Festplattenscan benötigt. +Default-Einstellung sind 10.000 Bytes. + +Wird dieser Wert nachträglich geändert, werden die Sperrliste und +die Liste der erlaubten Dubletten ungültig.</value> + </data> + <data name="Md5Label.ToolTip" xml:space="preserve"> + <value>Anzahl Bytes, die für die Ermittlung des Hashes der Datei +benutzt werden. +Achtung: Dieser Hash dient zur eindeutigen Identifizierung einer +Datei und sollte daher nicht zu klein gewählt werden, da es sonst zu +falschen Dublettenerkennungen kommen kann. +Große Werte erhöhen die allerdings Dauer für einen +Festplattenscan benötigt. +Default-Einstellung sind 10.000 Bytes. + +Wird dieser Wert nachträglich geändert, werden die Sperrliste und +die Liste der erlaubten Dubletten ungültig.</value> + </data> + <data name="chkRemoveMarks.ToolTip" xml:space="preserve"> + <value>Wenn aktiviert, werden Markierungen nach dem Ausführen einer Aktion auf alle Markierungen automatisch entfernt. + +Dies umfasst die folgenden Aktionen: +* Alle markierten Dateien sperren +* Alle markierten Dateien entsperren +* Alle fremden selektierten Dateien direkt in diesen Ordner kopieren (flat) +* Alle fremden selektierten Dateien mit Ordnerstruktur in diesen Ordner kopieren</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/ConfigListBox.Designer.cs b/LanTool/ConfigListBox.Designer.cs @@ -0,0 +1,161 @@ +namespace LanTool +{ + /// <summary> + /// Konfigurationslistbox für Pfadauswahl + /// </summary> + partial class ConfigListBox + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConfigListBox)); + this.ConfigurationLabel = new System.Windows.Forms.Label(); + this.ConfigurationListBox = new System.Windows.Forms.ListBox(); + this.AddTextBox = new System.Windows.Forms.TextBox(); + this.AddButton = new System.Windows.Forms.Button(); + this.FolderSelectButton = new System.Windows.Forms.Button(); + this.DeleteButton = new System.Windows.Forms.Button(); + this.DownButton = new System.Windows.Forms.Button(); + this.UpButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // ConfigurationLabel + // + this.ConfigurationLabel.AutoSize = true; + this.ConfigurationLabel.Location = new System.Drawing.Point(-3, 5); + this.ConfigurationLabel.Name = "ConfigurationLabel"; + this.ConfigurationLabel.Size = new System.Drawing.Size(96, 13); + this.ConfigurationLabel.TabIndex = 0; + this.ConfigurationLabel.Text = "Wert nicht gesetzt:"; + // + // ConfigurationListBox + // + this.ConfigurationListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.ConfigurationListBox.FormattingEnabled = true; + this.ConfigurationListBox.Location = new System.Drawing.Point(0, 21); + this.ConfigurationListBox.Name = "ConfigurationListBox"; + this.ConfigurationListBox.Size = new System.Drawing.Size(192, 186); + this.ConfigurationListBox.TabIndex = 1; + this.ConfigurationListBox.SelectedIndexChanged += new System.EventHandler(this.ConfigurationListBox_SelectedIndexChanged); + // + // AddTextBox + // + this.AddTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.AddTextBox.Location = new System.Drawing.Point(0, 211); + this.AddTextBox.Name = "AddTextBox"; + this.AddTextBox.Size = new System.Drawing.Size(161, 20); + this.AddTextBox.TabIndex = 2; + // + // AddButton + // + this.AddButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.AddButton.Image = global::LanTool.Properties.Resources.saveHS; + this.AddButton.Location = new System.Drawing.Point(199, 208); + this.AddButton.Name = "AddButton"; + this.AddButton.Size = new System.Drawing.Size(24, 23); + this.AddButton.TabIndex = 7; + this.AddButton.UseVisualStyleBackColor = true; + this.AddButton.Click += new System.EventHandler(this.AddButton_Click); + // + // FolderSelectButton + // + this.FolderSelectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.FolderSelectButton.Image = global::LanTool.Properties.Resources.openfolderHS; + this.FolderSelectButton.Location = new System.Drawing.Point(167, 209); + this.FolderSelectButton.Name = "FolderSelectButton"; + this.FolderSelectButton.Size = new System.Drawing.Size(25, 23); + this.FolderSelectButton.TabIndex = 6; + this.FolderSelectButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.FolderSelectButton.UseVisualStyleBackColor = true; + this.FolderSelectButton.Click += new System.EventHandler(this.FolderSelectButton_Click); + // + // DeleteButton + // + this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.DeleteButton.Image = global::LanTool.Properties.Resources.DeleteHS; + this.DeleteButton.Location = new System.Drawing.Point(198, 21); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(25, 29); + this.DeleteButton.TabIndex = 5; + this.DeleteButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); + // + // DownButton + // + this.DownButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.DownButton.Image = ((System.Drawing.Image)(resources.GetObject("DownButton.Image"))); + this.DownButton.Location = new System.Drawing.Point(198, 91); + this.DownButton.Name = "DownButton"; + this.DownButton.Size = new System.Drawing.Size(25, 29); + this.DownButton.TabIndex = 4; + this.DownButton.UseVisualStyleBackColor = true; + this.DownButton.Click += new System.EventHandler(this.DownButton_Click); + // + // UpButton + // + this.UpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.UpButton.Image = ((System.Drawing.Image)(resources.GetObject("UpButton.Image"))); + this.UpButton.Location = new System.Drawing.Point(198, 56); + this.UpButton.Name = "UpButton"; + this.UpButton.Size = new System.Drawing.Size(25, 29); + this.UpButton.TabIndex = 3; + this.UpButton.UseVisualStyleBackColor = true; + this.UpButton.Click += new System.EventHandler(this.UpButton_Click); + // + // ConfigListBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.AddButton); + this.Controls.Add(this.FolderSelectButton); + this.Controls.Add(this.DeleteButton); + this.Controls.Add(this.DownButton); + this.Controls.Add(this.UpButton); + this.Controls.Add(this.AddTextBox); + this.Controls.Add(this.ConfigurationListBox); + this.Controls.Add(this.ConfigurationLabel); + this.Name = "ConfigListBox"; + this.Size = new System.Drawing.Size(223, 234); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label ConfigurationLabel; + private System.Windows.Forms.ListBox ConfigurationListBox; + private System.Windows.Forms.TextBox AddTextBox; + private System.Windows.Forms.Button UpButton; + private System.Windows.Forms.Button DownButton; + private System.Windows.Forms.Button DeleteButton; + private System.Windows.Forms.Button FolderSelectButton; + private System.Windows.Forms.Button AddButton; + } +} diff --git a/LanTool/ConfigListBox.cs b/LanTool/ConfigListBox.cs @@ -0,0 +1,188 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; + +namespace LanTool +{ + public partial class ConfigListBox : UserControl + { + /// <summary> + /// spezielle Listbox für die Konfiguration + /// </summary> + public ConfigListBox() + { + InitializeComponent(); + } + + /// <summary> + /// Setzt die Überschrift über die ConfigListBox + /// </summary> + [Browsable(true)] + public string Header + { + get + { + return this.ConfigurationLabel.Text; + } + set + { + this.ConfigurationLabel.Text = value; + } + } + + private bool _hasFolderSelectButton = true; + /// <summary> + /// Gibt an, ob ein Folder-Auswahl-Knopf angeboten wird + /// </summary> + [Browsable(true)] + public bool HasFolderSelectButton + { + get + { + return _hasFolderSelectButton; + } + set + { + _hasFolderSelectButton = value; + this.FolderSelectButton.Visible = _hasFolderSelectButton; + this.AddTextBox.Width = HasFolderSelectButton ? 161 : 192; + } + } + + private bool _hasNewFolderButton = true; + /// <summary> + /// Gibt an, ob der bei der Ordnerauswahl "Neuen Ordner anlegen" angeboten wird + /// </summary> + [Browsable(true)] + public bool HasNewFolderButton + { + get + { + return _hasNewFolderButton; + } + set + { + _hasNewFolderButton = value; + } + } + + private bool _sorted = true; + /// <summary> + /// Gibt an, ob der bei der Ordnerauswahl "Neuen Ordner anlegen" angeboten wird + /// </summary> + [Browsable(true)] + public bool Sorted + { + get + { + return _sorted; + } + set + { + _sorted = value; + if (_sorted) + { + UpButton.Visible = false; + DownButton.Visible = false; + } + } + } + + /// <summary> + /// alle enthaltenen Elemente + /// </summary> + public ListBox.ObjectCollection Items + { + get + { + return this.ConfigurationListBox.Items; + } + } + + /// <summary> + /// Klickt auf den Button "Ordner auswählen" + /// </summary> + private void FolderSelectButton_Click(object sender, EventArgs e) + { + using (FolderBrowserDialog fd = new FolderBrowserDialog()) + { + fd.ShowNewFolderButton = this.HasNewFolderButton; + if (fd.ShowDialog(this).Equals(DialogResult.OK)) + { + this.AddTextBox.Text = fd.SelectedPath; + } + } + } + + /// <summary> + /// Click auf den Button "Speichern" + /// </summary> + private void AddButton_Click(object sender, EventArgs e) + { + if (!String.IsNullOrEmpty(this.AddTextBox.Text)) + { + int sel = this.ConfigurationListBox.SelectedIndex; + if (sel >= 0) + { + this.ConfigurationListBox.Items[sel] = this.AddTextBox.Text; + this.ConfigurationListBox.SelectedIndex = -1; + } + else + { + this.ConfigurationListBox.Items.Add(this.AddTextBox.Text); + } + this.AddTextBox.Text = ""; + } + } + + private void UpButton_Click(object sender, EventArgs e) + { + int sel = this.ConfigurationListBox.SelectedIndex; + if (sel > 0) + { + string wert = this.ConfigurationListBox.Items[sel].ToString(); + this.ConfigurationListBox.Items.RemoveAt(sel); + this.ConfigurationListBox.Items.Insert(sel - 1, wert); + this.ConfigurationListBox.SelectedIndex = sel - 1; + } + } + + private void DownButton_Click(object sender, EventArgs e) + { + int sel = this.ConfigurationListBox.SelectedIndex; + if (sel >= 0 && sel < this.ConfigurationListBox.Items.Count - 1) + { + string wert = this.ConfigurationListBox.Items[sel].ToString(); + this.ConfigurationListBox.Items.RemoveAt(sel); + this.ConfigurationListBox.Items.Insert(sel + 1, wert); + this.ConfigurationListBox.SelectedIndex = sel + 1; + } + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + int sel = this.ConfigurationListBox.SelectedIndex; + this.ConfigurationListBox.SelectedIndex = -1; + if (sel >= 0) + { + this.ConfigurationListBox.Items.RemoveAt(sel); + this.ConfigurationListBox.SelectedIndex = -1; + this.AddTextBox.Text = ""; + } + } + + private int _lastSelection = -1; + private void ConfigurationListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (this.ConfigurationListBox.SelectedIndex == _lastSelection && this.ConfigurationListBox.SelectedIndex != -1) + { + this.ConfigurationListBox.SelectedIndex = -1; + } + _lastSelection = this.ConfigurationListBox.SelectedIndex; + if (_lastSelection >= 0) + { + this.AddTextBox.Text = ConfigurationListBox.Items[_lastSelection].ToString(); + } + } + } +} diff --git a/LanTool/ConfigListBox.resx b/LanTool/ConfigListBox.resx @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="DownButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALDAAA + CwwBP0AiyAAAAFdJREFUOE9jEDIJY6AEU6QZZDH1DWBgYPiPDePyJoYLwJrRIVBs1ABahwFGtGGJBWQ1 + yDECj0as0UdEdKKkA7yG4EgL1E9I4AyCnBrxpEK8mQkWaISyOgDDGOxNYirsLQAAAABJRU5ErkJggg== +</value> + </data> + <data name="UpButton.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALDAAA + CwwBP0AiyAAAAGJJREFUOE9jEDIJY8CHGRgY/oMwLjWENf8HGgCCOAzBaQDYZnSIxRCsBmDVjMMlGAbg + 1YzFEBQDYAEGp7F4AVkNKGBpEwZgkykJxFEDIHkDI0px5Am8eYFQRsObDojRTBUDALQm7E0Mx9AUAAAA + AElFTkSuQmCC +</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/Configurations/rw-net.ruleset b/LanTool/Configurations/rw-net.ruleset @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<RuleSet Name="rw-net Ruleset" Description="This rule set contains all rules. Running this rule set may result in a large number of warnings being reported. Use this rule set to get a comprehensive picture of all issues in your code. This can help you decide which of the more focused rule sets are most appropriate to run for your projects." ToolsVersion="10.0"> + <IncludeAll Action="Warning" /> + <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed"> + <Rule Id="CA1002" Action="None" /> + <Rule Id="CA1031" Action="None" /> + <Rule Id="CA1300" Action="None" /> + <Rule Id="CA1303" Action="None" /> + <Rule Id="CA1304" Action="None" /> + <Rule Id="CA1305" Action="None" /> + <Rule Id="CA1306" Action="None" /> + <Rule Id="CA1307" Action="None" /> + <Rule Id="CA1309" Action="None" /> + <Rule Id="CA1704" Action="None" /> + <Rule Id="CA2201" Action="None" /> + <Rule Id="CA2204" Action="None" /> + <Rule Id="CA2211" Action="None" /> + </Rules> +</RuleSet> +\ No newline at end of file diff --git a/LanTool/Configurations/rw-net.snk b/LanTool/Configurations/rw-net.snk Binary files differ. diff --git a/LanTool/Dokumentation/Abgelehnt.txt b/LanTool/Dokumentation/Abgelehnt.txt @@ -0,0 +1,8 @@ +- bei Datei "Im Explorer öffnen" +Kann schon durch Doppelklick auf die Pfadleiste erreicht werden + +- Ranking im Internet (Hash + Rang) +Internet ist Teufelszeug + +- Konfigurierbare Logausgabe +Das Log hat seinen Zweck. +\ No newline at end of file diff --git a/LanTool/Dokumentation/LanTool_ChangeLog.txt b/LanTool/Dokumentation/LanTool_ChangeLog.txt @@ -0,0 +1,143 @@ +LanTool - Changelog +=================== + +Version 1.6.0: +-------------- +- NEU: Dateien mit identischen Dateinamen aber unterschiedlichem Hash können nun wie eine Datei behandelt werden + * Einstellung in den Optionen +- FIX: höhere DPI-Einstellungen im Windows zerstören die Anzeige nicht mehr + +Version 1.5.0: +-------------- +- NEU: "Alle markierten Dateien sperren und löschen" gibts jetzt auch bei Rechtsklick auf ein Verzeichnis +- NEU: Ãœber die Optionen kann ein Kennzeichen für die Titelzeile angegeben werden, dieses wird dann in eckigen Klammern + vor dem Programmname angezeigt +- NEU: Optional kann das Programm mit der Priorität "Weniger als Normal" ausgeführt werden, dies verringert den Einfluss das LanTools auf Spiele oder ähnliches +- CHG: verbesserter Umgang mit der Baumaktualisierung bei den folgenden Funktionen, dadurch deutlich schneller + * Dubletten zum Löschen markieren (eine bleibt) + * Alle Dateien markieren + * Dateien mit Suchfilter markieren... + * Alle Markierungen entfernen + * Alle fehlenden Dateien markieren + * Alle markierten Dateien sperren + * Alle markierten Dateien entsperren + * Datei sperren + * Datei entsperren +- CHG: LanTool kann wieder mehrfach gestartet werden, wenn sich die Programme in unterschiedlichen Verzeichnissen befinden +- CHG: bei Auswahl der DefaultOfflinedatei wird nur der Dateiname gespeichert, wenn sich die Datei im LanTool-Verzeichnis befindet + (dadurch funktioniert das Laden auch bei Änderung des LanTool-Speicherplatzes) +- CHG: Die Verzeichnisauswahl-Listboxen haben keine Sortierpfeile mehr (die TreeViews sind automatisch sortiert) +- FIX: wird als Platte ein komplettes Laufwerk angegeben, wird ggf. ein "\" hinten angehängt, sonst schaut die Darstellung im Tree komisch aus +- FIX: beim ToolTip auf fremden Platten wird der Dateiname der lokalen Datei nicht mehr doppelt angezeigt + +Version 1.4.0: +-------------- +- NEU: beim Ändern der Einstellungen gehen eingelesene Verzeichnisse und der Offline-Status nicht mehr verloren +- NEU: Offline-Datei per Default beim Start laden und eigene Verzeichnisse gleich offline setzen (per Konfiguration) +- NEU: ToolTip für jede Datei mit dem folgenden Inhalt + - kompletter Pfad + - Dateigröße in Bytes + - Hashwert der Datei + - bei Dateien auf den fremden Platten wird der Speicherort der lokalen Kopie angezeigt, falls bereits vorhanden + - bei Dateien auf den eigenen Platten wird der Speicehrort der Dubletten angezeigt, falls vorhanden +- CHG: Performanceverbesserungen + - Die Cachedateien werden nur noch beim Beenden des Programmes auf die Festplatte geschrieben. + - Starke Beschleunigung beim Darstellen der Fremden Platten, wenn die Optionen "vorhandene Dateien ausblenden" und/oder "gesperrte Dateien ausblenden" aktiv sind. +- CHG: Beim Hinzufügen von eigenen oder fremden Platten, ist die Option "Neuen Ordner erstellen" nur noch bei den eigenen Platten verfügbar. +- FIX: nicht sichtbare Dateien werden nicht mehr als "markiert" behandelt +- FIX: Option "Markierungen nach Aktion entfernen" entfernt bei einer Kopieraktion die Markierungen nun im Baum "Fremde Platten" + +Version 1.3.2: +-------------- +- CHG: "Markierungen nach Aktion entfernen" entfernt die Haken beim Kopieren nun schon, bevor das Kopieren gestartet wird + +Version 1.3.1: +-------------- +- FIX: versteckte Dateien werden wirklich versteckt +- FIX: Wechsel auf .Net 3.5 + +Version 1.3.0: +-------------- +- NEU: LanTool kann FTP (mit Hilfe von NetDrive ;-) ) +- NEU: mehrfacher Programmstart wird unterbunden, die bereits gestartete Instanz wird stattdessen angezeigt +- NEU: Such-Feld im Menü, durchsucht den zuletzt benutzten Verzeichnisbaum nach dem angegebenen Suchstring + * Strg+F aufrufen des Suchfeldes + * F3 zum Weitersuchen +- NEU: neue Option "Entfernen der Markierungen nach Aktion" bei folgenden Aktionen + * Alle markierten Dateien sperren + * Alle markierten Dateien entsperren + * Alle fremden selektierten Dateien direkt in diesen Ordner kopieren (flat) + * Alle fremden selektierten Dateien mit Ordnerstruktur in diesen Ordner kopieren +- NEU: Anzeige der Anzahl aktiver Kopiervorgänge vor dem Fortschrittsbalken +- NEU: Unterstützung der Fortschrittsanzeige in der Superbar von Windows 7 +- CHG: Der Fortschrittsbalken zeigt den Fortschritt über alle aktiven Kopierthreads hinweg an +- FIX: Fortschrittsbalken beim Starten des Kopierens auf 0 setzen + +Version 1.2.0: +-------------- +- NEU: super-tolle InfoBox +- NEU: Option "Alle markierten Dateien sperren und löschen" im Hauptmenü +- NEU: Sicherheitsabfrage bei "Sperren und Löschen" +- NEU: Nach Abschluß des Kopierens wird eine Meldung mit Anzahl und Gesamtgröße der kopierten Dateien, benötigter Zeit und durchschnittlicher Ãœbertragungsrate angezeigt +- CHG: Doppelklick auf einen Ordner führt nicht mehr dazu, dass der Ordner im Explorer aufgerufen wird +- NEU: Anzeige des kompletten Pfades oberhalb der TreeViews + * Doppelklick auf das Feld öffnet den Explorer im angegebenen Pfad +- NEU: Dateien können nun auch durch "Öffnen mit..." aufgerufen werden + * wird eine Datei ohne Programmverknüpfung mittels "Öffnen" aufgerufen, erscheint automatisch der + "Öffnen mit"-Dialog +- CHG: Menüs (Kontext und Programm) logischer strukturiert +- FIX: falsche Benennung der Dateien beim Kopieren von fremden Platten korrigiert + +Version 1.1.0: +-------------- +- NEU: Tooltips bei diversen Konfigurationswerten zur Erklärung hinterlegt +- NEU: Gesperrte/bereits vorhandene Dateien per Option nicht mehr in den "Fremden Platten" anzeigen + * Standard-Einstellung ist, das beide Dateitypen angezeigt werden + * Ist die Option aktiviert, werden die Dateien in der Baumstruktur der Fremden Platten nicht mehr angezeigt +- NEU: Dublette erlauben (z.B. für MP3-Alben/Sampler mit doppelten Liedern) + * Die Anzahl der "erlaubten" Dubletten und deren Größe wird nach dem Einlesen der Platten angezeigt + * Im Kontextmenü werden die Dubletten nach wie vor zum Löschen angeboten + * Mittels Option kann festgelegt werden, ob erlaubte Dubletten zu einem Aufklappen der Baumes führen +- NEU: Warnungen und Fehler werden im Log farbig markiert, Ausgaben in der Statuszeile und im Log vereinheitlicht +- NEU: Fortschrittsbalken in der Statusbar zeigt nun den Fortschritt des Gesamtkopiervorganges an (Größe der bereits kopierten Dateien zur Gesamtgröße der zu kopierenden Dateien) +- NEU: bei Start ohne Config-File wird ein Default-Konfig angelegt und anschließend der Konfigurationsdialog geöffnet + +Version 1.0 rc4: +---------------- +- Markieren aller Dubletten als neues Menü + +Version 1.0 rc1: +---------------- +- Gesperrte Dateien gehören nicht mehr zu den fehlenden Dateien +- Menüpunkte Ãœbersichtlichkeit: Icons und neue Struktur der Menüs +- Markierte Dateien werden nach dem Kopieren demarkiert +- Alphabetisch sortieren innerhab der Ordner +- Alle markierten Dateien sperren/entsperren +- Löschen und sperren in einem Arbeitsgang (Einzeldatei) +- Kopieren von kompletten Hierarchien (mit Verzeichnisnamen) +- Löschen von leeren Verzeichnissen (auch hierarchisch) +- Konfigurationsdialog für Laien +- Verzeichnisse und Dateien getrennt sortieren + +Version 0.3a: +------------- +- Trenung der internen Datenstruktur von der Anzeige +- Oberfläche bleibt beim Kopieren bedienbar (InvokeRequired) + +Version 0.2b: +------------- +- Die "-" Option auch auf Verzeichnisnamen anwenden ("+" nur auf Dateien) + +Version 0.2a: +------------- +- Caching von Hashcodes +- Ignore-Liste + +Version 0.1e: +------------- +- freier Speicher durch dubletten +- Update einschalten nach Exceptions! +- Rechenfehler in grösse +- Menüpunkt auf rot: Menüpunkte für alle Dubletten zum Löschen. +- Alle Dubletten direkt per Menü anschauen. +- Exceptions beim Aufräumen (rechte Liste leer) +\ No newline at end of file diff --git a/LanTool/Dokumentation/LanTool_Tipps.txt b/LanTool/Dokumentation/LanTool_Tipps.txt @@ -0,0 +1,30 @@ +LanTool - Tipps & Tricks +======================== + +1. Hotkeys: +----------- + +- F2 - Konfiguration öffnen +- Strg+O - Offlinedatei laden +- Strg+S - Offlinedatei speichern +- Alt+F4 - Programm schließen + +- Strg+F - Aufrufen des Suchfeldes +- F3 - Weitersuchen + +2. Performance: +--------------- + +Das Hauptproblem bei der Darstellung der Trees ist - neben dem eigentlichen Scannen der Daten - das Erzeugen der Baumstruktur. +Deutliche Geschwindigkeitsvorteile ergeben sich, wenn möglichst wenige Dateien/Ordner von Beginn an sichtbar sind. + +Das heißt bei den eigenen Platten: +Eigene Platten aufräumen und erlaubte Dubletten entsprechend markieren und nicht einblenden lassen. + +Und bei den fremden Platten: +Die Optionen "gesperrte Dateien verstecken" und "vorhandene Dateien verstecken" nutzen. Dadurch müssen wesentlich weniger Dateien überhaupt dargestellt werden. + +Darüber hinaus ist die Anzahl der darzustellenden Dateien noch ausschlaggebend. + +Trenne Dein LanTool in verschiedene Verwendungsbereiche auf, z.B. für MP3s, für Filme etc. +Dazu kopierst Du einfach das LanTool in 2 verschiedene Verzeichnisse, passt die Konfiguration an wie du sie brauchst und markierst das LanTool dann noch entsprechend. +\ No newline at end of file diff --git a/LanTool/Dokumentation/ToDo.txt b/LanTool/Dokumentation/ToDo.txt @@ -0,0 +1,36 @@ +für 1.6: +- Aktion "Markierung nach Aktion entfernen" geht schief, wenn über die oberste Ebene (Meine Platten) aufgerufen (aus dem Hauptmenü) +- Einträge im Remotetree entfernen wenn die Option, gesetzt ist + + +- HotKeys + - F5 -> aktuellen Tree neu einlesen + +- GUI + - Rechtsklick auf Pfad-Feld kopiert den Pfad in die Zwischenablage bzw. eigener Dialog + - Springen zur nächsten Markierung (z.B. bei Dublettensuche) (z.B. zeige dublette jetzt) + - Datei/Ordner umbenennen + - Ordner verschieben + +- Offline-Modus + - Löschen/Ordner anlegen etc. gar nicht erst erlauben! + - Löschen von Dateien im Offline-Modus nimmt die Datei nicht aus dem Tree + +- Änderung an den Dateien (Löschen darf nicht zum kompletten Neulesen des Trees führen) + +- Aktionen + - Ordner zum Kopieren markiert, dann auch untergeordnete Dateien markieren + - nach dem Kopieren übergeordnete Ordner ebenfalls demarkieren + + - Kopieren nur mit x übergeordneten Ordnern, nicht der kompletten Struktur, x wird abgefragt + +- Kopieren + - Dateien, die bereits in einer Kopierliste sind, nicht mehr als "IsNeeded" kennzeichnen + - Kopierthreads pausieren/unterbrechen + +- Config + - Verzeichnisauswahl in der Config beim zuletzt benutzten Verzeichnis starten + +- Größe der transferierten Dateien je Tag/Stunde merken und Auswertung anzeigen + - Speichern Tag/Stunde und Transferierte MB + - Anzeige in einem DataGrid bzw. ChartControl diff --git a/LanTool/FilterDialog.Designer.cs b/LanTool/FilterDialog.Designer.cs @@ -0,0 +1,113 @@ +namespace LanTool +{ + partial class FilterDialog + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterDialog)); + this.cancelButton = new System.Windows.Forms.Button(); + this.executeButton = new System.Windows.Forms.Button(); + this.filterTextBox = new System.Windows.Forms.TextBox(); + this.filterLabel = new System.Windows.Forms.Label(); + this.dokLabel = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // cancelButton + // + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(280, 79); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 2; + this.cancelButton.Text = "Abbruch"; + this.cancelButton.UseVisualStyleBackColor = true; + // + // executeButton + // + this.executeButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.executeButton.Location = new System.Drawing.Point(199, 79); + this.executeButton.Name = "executeButton"; + this.executeButton.Size = new System.Drawing.Size(75, 23); + this.executeButton.TabIndex = 1; + this.executeButton.Text = "Markieren"; + this.executeButton.UseVisualStyleBackColor = true; + // + // filterTextBox + // + this.filterTextBox.Location = new System.Drawing.Point(70, 12); + this.filterTextBox.Name = "filterTextBox"; + this.filterTextBox.Size = new System.Drawing.Size(281, 20); + this.filterTextBox.TabIndex = 0; + // + // filterLabel + // + this.filterLabel.AutoSize = true; + this.filterLabel.Location = new System.Drawing.Point(12, 15); + this.filterLabel.Name = "filterLabel"; + this.filterLabel.Size = new System.Drawing.Size(32, 13); + this.filterLabel.TabIndex = 3; + this.filterLabel.Text = "Filter:"; + // + // dokLabel + // + this.dokLabel.AutoSize = true; + this.dokLabel.Location = new System.Drawing.Point(70, 44); + this.dokLabel.Name = "dokLabel"; + this.dokLabel.Size = new System.Drawing.Size(281, 13); + this.dokLabel.TabIndex = 4; + this.dokLabel.Text = "Filterbedingung eingeben, z.B. \"*.pdf\" oder \"Hallo??.mp3\""; + // + // FilterDialog + // + this.AcceptButton = this.executeButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(365, 116); + this.Controls.Add(this.dokLabel); + this.Controls.Add(this.filterLabel); + this.Controls.Add(this.filterTextBox); + this.Controls.Add(this.executeButton); + this.Controls.Add(this.cancelButton); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.Name = "FilterDialog"; + this.Text = "Filterbedingung eingeben"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.TextBox filterTextBox; + private System.Windows.Forms.Label dokLabel; + private System.Windows.Forms.Button executeButton; + private System.Windows.Forms.Label filterLabel; + } +} +\ No newline at end of file diff --git a/LanTool/FilterDialog.cs b/LanTool/FilterDialog.cs @@ -0,0 +1,27 @@ +using System.Windows.Forms; + +namespace LanTool +{ + /// <summary> + /// Standard-Such- und Filter-Dialog + /// </summary> + public partial class FilterDialog : Form + { + /// <summary> + /// Filterdialog erstellen + /// </summary> + public FilterDialog() + { + InitializeComponent(); + } + + /// <summary> + /// Filter-Ausdruck (kann ein regulärer Ausdruck sein) + /// </summary> + public string Expression + { + get { return filterTextBox.Text; } + set { filterTextBox.Text = value; } + } + } +} +\ No newline at end of file diff --git a/LanTool/FilterDialog.resx b/LanTool/FilterDialog.resx @@ -0,0 +1,249 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + AAABAAMAMDAAAAEACACoDgAANgAAACAgAAABAAgAqAgAAN4OAAAQEAAAAQAIAGgFAACGFwAAKAAAADAA + AABgAAAAAQAIAAAAAACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AADAwMAAwNzAAPDKpgDU8P8AseL/AI7U/wBrxv8ASLj/ACWq/wAAqv8AAJLcAAB6uQAAYpYAAEpzAAAy + UADU4/8Ascf/AI6r/wBrj/8ASHP/ACVX/wAAVf8AAEncAAA9uQAAMZYAACVzAAAZUADU1P8AsbH/AI6O + /wBra/8ASEj/ACUl/wAAAP4AAADcAAAAuQAAAJYAAABzAAAAUADj1P8Ax7H/AKuO/wCPa/8Ac0j/AFcl + /wBVAP8ASQDcAD0AuQAxAJYAJQBzABkAUADw1P8A4rH/ANSO/wDGa/8AuEj/AKol/wCqAP8AkgDcAHoA + uQBiAJYASgBzADIAUAD/1P8A/7H/AP+O/wD/a/8A/0j/AP8l/wD+AP4A3ADcALkAuQCWAJYAcwBzAFAA + UAD/1PAA/7HiAP+O1AD/a8YA/0i4AP8lqgD/AKoA3ACSALkAegCWAGIAcwBKAFAAMgD/1OMA/7HHAP+O + qwD/a48A/0hzAP8lVwD/AFUA3ABJALkAPQCWADEAcwAlAFAAGQD/1NQA/7GxAP+OjgD/a2sA/0hIAP8l + JQD+AAAA3AAAALkAAACWAAAAcwAAAFAAAAD/49QA/8exAP+rjgD/j2sA/3NIAP9XJQD/VQAA3EkAALk9 + AACWMQAAcyUAAFAZAAD/8NQA/+KxAP/UjgD/xmsA/7hIAP+qJQD/qgAA3JIAALl6AACWYgAAc0oAAFAy + AAD//9QA//+xAP//jgD//2sA//9IAP//JQD+/gAA3NwAALm5AACWlgAAc3MAAFBQAADw/9QA4v+xANT/ + jgDG/2sAuP9IAKr/JQCq/wAAktwAAHq5AABilgAASnMAADJQAADj/9QAx/+xAKv/jgCP/2sAc/9IAFf/ + JQBV/wAASdwAAD25AAAxlgAAJXMAABlQAADU/9QAsf+xAI7/jgBr/2sASP9IACX/JQAA/gAAANwAAAC5 + AAAAlgAAAHMAAABQAADU/+MAsf/HAI7/qwBr/48ASP9zACX/VwAA/1UAANxJAAC5PQAAljEAAHMlAABQ + GQDU//AAsf/iAI7/1ABr/8YASP+4ACX/qgAA/6oAANySAAC5egAAlmIAAHNKAABQMgDU//8Asf//AI7/ + /wBr//8ASP//ACX//wAA/v4AANzcAAC5uQAAlpYAAHNzAABQUADy8vIA5ubmANra2gDOzs4AwsLCALa2 + tgCqqqoAnp6eAJKSkgCGhoYAenp6AG5ubgBiYmIAVlZWAEpKSgA+Pj4AMjIyACYmJgAaGhoADg4OAPD7 + /wCkoKAAgICAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADp6enp+O4AAAAA + AAAAAAAAAADu+Onp6ekAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrIAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAACy + srKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAACysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAsgAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAA + ALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////AAD///////8AAP// + /////wAA////////AAD///////8AAP/wD/AP/wAA///gB///AAD//+AP//8AAP//4A///wAA///wD/// + AAD///AP//8AAP//wAf//wAA///AA///AAD//8AB//8AAP//wAH//wAA///AAP//AAD//8AA//8AAP// + gAD//wAA//+AAP//AAD//4AA//8AAP//gAB//wAA//+AAD//AAD//4AAP/8AAP//gAA//wAA//+ACP// + AAD//wAY//8AAP//EBj//wAA//8QP///AAD//jg///8AAP/+PD///wAA//w8P///AAD//jw///8AAP// + /D///wAA///8P///AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA//////// + AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmANTw/wCx4v8AjtT/AGvG + /wBIuP8AJar/AACq/wAAktwAAHq5AABilgAASnMAADJQANTj/wCxx/8Ajqv/AGuP/wBIc/8AJVf/AABV + /wAASdwAAD25AAAxlgAAJXMAABlQANTU/wCxsf8Ajo7/AGtr/wBISP8AJSX/AAAA/gAAANwAAAC5AAAA + lgAAAHMAAABQAOPU/wDHsf8Aq47/AI9r/wBzSP8AVyX/AFUA/wBJANwAPQC5ADEAlgAlAHMAGQBQAPDU + /wDisf8A1I7/AMZr/wC4SP8AqiX/AKoA/wCSANwAegC5AGIAlgBKAHMAMgBQAP/U/wD/sf8A/47/AP9r + /wD/SP8A/yX/AP4A/gDcANwAuQC5AJYAlgBzAHMAUABQAP/U8AD/seIA/47UAP9rxgD/SLgA/yWqAP8A + qgDcAJIAuQB6AJYAYgBzAEoAUAAyAP/U4wD/sccA/46rAP9rjwD/SHMA/yVXAP8AVQDcAEkAuQA9AJYA + MQBzACUAUAAZAP/U1AD/sbEA/46OAP9rawD/SEgA/yUlAP4AAADcAAAAuQAAAJYAAABzAAAAUAAAAP/j + 1AD/x7EA/6uOAP+PawD/c0gA/1clAP9VAADcSQAAuT0AAJYxAABzJQAAUBkAAP/w1AD/4rEA/9SOAP/G + awD/uEgA/6olAP+qAADckgAAuXoAAJZiAABzSgAAUDIAAP//1AD//7EA//+OAP//awD//0gA//8lAP7+ + AADc3AAAubkAAJaWAABzcwAAUFAAAPD/1ADi/7EA1P+OAMb/awC4/0gAqv8lAKr/AACS3AAAerkAAGKW + AABKcwAAMlAAAOP/1ADH/7EAq/+OAI//awBz/0gAV/8lAFX/AABJ3AAAPbkAADGWAAAlcwAAGVAAANT/ + 1ACx/7EAjv+OAGv/awBI/0gAJf8lAAD+AAAA3AAAALkAAACWAAAAcwAAAFAAANT/4wCx/8cAjv+rAGv/ + jwBI/3MAJf9XAAD/VQAA3EkAALk9AACWMQAAcyUAAFAZANT/8ACx/+IAjv/UAGv/xgBI/7gAJf+qAAD/ + qgAA3JIAALl6AACWYgAAc0oAAFAyANT//wCx//8Ajv//AGv//wBI//8AJf//AAD+/gAA3NwAALm5AACW + lgAAc3MAAFBQAPLy8gDm5uYA2traAM7OzgDCwsIAtra2AKqqqgCenp4AkpKSAIaGhgB6enoAbm5uAGJi + YgBWVlYASkpKAD4+PgAyMjIAJiYmABoaGgAODg4A8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A + /wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6enp6fjuAAAAAAAAAAAAAAAA7vjp6enpAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAALKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrIAAAAA + AAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKy + sgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKy + srKysgAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + ALKysrKysrKyAAAAsgAAAAAAAAAAAAAAAAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAA + AAAAALIAALKysrKyAAAAALIAAAAAAAAAAAAAAAAAAAAAAACyAAAAsrKysgAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAsrIAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALIAAAAAAACysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///////////AP8A//4Af//+AP///gD///8A////AP///AB///wAP//8AB///A + Af//wAD//8AA//+AAP//gAD//4AA//+AAH//gAA//4AAP/+AAD//gAj//wAY//8QGP//ED///jg///48 + P//8PD///jw////8P////D///////ygAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYA1PD/ALHi/wCO1P8Aa8b/AEi4 + /wAlqv8AAKr/AACS3AAAerkAAGKWAABKcwAAMlAA1OP/ALHH/wCOq/8Aa4//AEhz/wAlV/8AAFX/AABJ + 3AAAPbkAADGWAAAlcwAAGVAA1NT/ALGx/wCOjv8Aa2v/AEhI/wAlJf8AAAD+AAAA3AAAALkAAACWAAAA + cwAAAFAA49T/AMex/wCrjv8Aj2v/AHNI/wBXJf8AVQD/AEkA3AA9ALkAMQCWACUAcwAZAFAA8NT/AOKx + /wDUjv8Axmv/ALhI/wCqJf8AqgD/AJIA3AB6ALkAYgCWAEoAcwAyAFAA/9T/AP+x/wD/jv8A/2v/AP9I + /wD/Jf8A/gD+ANwA3AC5ALkAlgCWAHMAcwBQAFAA/9TwAP+x4gD/jtQA/2vGAP9IuAD/JaoA/wCqANwA + kgC5AHoAlgBiAHMASgBQADIA/9TjAP+xxwD/jqsA/2uPAP9IcwD/JVcA/wBVANwASQC5AD0AlgAxAHMA + JQBQABkA/9TUAP+xsQD/jo4A/2trAP9ISAD/JSUA/gAAANwAAAC5AAAAlgAAAHMAAABQAAAA/+PUAP/H + sQD/q44A/49rAP9zSAD/VyUA/1UAANxJAAC5PQAAljEAAHMlAABQGQAA//DUAP/isQD/1I4A/8ZrAP+4 + SAD/qiUA/6oAANySAAC5egAAlmIAAHNKAABQMgAA///UAP//sQD//44A//9rAP//SAD//yUA/v4AANzc + AAC5uQAAlpYAAHNzAABQUAAA8P/UAOL/sQDU/44Axv9rALj/SACq/yUAqv8AAJLcAAB6uQAAYpYAAEpz + AAAyUAAA4//UAMf/sQCr/44Aj/9rAHP/SABX/yUAVf8AAEncAAA9uQAAMZYAACVzAAAZUAAA1P/UALH/ + sQCO/44Aa/9rAEj/SAAl/yUAAP4AAADcAAAAuQAAAJYAAABzAAAAUAAA1P/jALH/xwCO/6sAa/+PAEj/ + cwAl/1cAAP9VAADcSQAAuT0AAJYxAABzJQAAUBkA1P/wALH/4gCO/9QAa//GAEj/uAAl/6oAAP+qAADc + kgAAuXoAAJZiAABzSgAAUDIA1P//ALH//wCO//8Aa///AEj//wAl//8AAP7+AADc3AAAubkAAJaWAABz + cwAAUFAA8vLyAObm5gDa2toAzs7OAMLCwgC2trYAqqqqAJ6engCSkpIAhoaGAHp6egBubm4AYmJiAFZW + VgBKSkoAPj4+ADIyMgAmJiYAGhoaAA4ODgDw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAA6enuAAAAAAAA+OnpAAAAAAAAAACysrIAAAAAAAAAAAAAAAAA + srKyAAAAAAAAAAAAAAAAALKysgAAAAAAAAAAAAAAAACysrKyAAAAAAAAAAAAAAAAsrKysrIAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAsrKysgAAAAAA + AAAAAAAAAACysrIAAAAAAAAAAAAAALIAALIAAAAAAAAAAAAAAAAAAACyAAAAAAAAAAAAAAAAAAAAsgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADDwwAA+D8AAPg/AAD4PwAA+B8AAPgPAADwDwAA8A8AAPAH + AADwBwAA4E8AAOR/AADkfwAA5H8AAP5/AAA= +</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/GlobalSuppressions.cs b/LanTool/GlobalSuppressions.cs @@ -0,0 +1,41 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +// +// To add a suppression to this file, right-click the message in the +// Error List, point to "Suppress Message(s)", and click +// "In Project Suppression File". +// You do not need to add suppressions to this file manually. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", + "CA2000:Dispose objects before losing scope", + Scope = "member", + Target = "LanTool.MainForm.#überToolStripMenuItem_Click(System.Object,System.EventArgs)", + Justification = "Will ich aber so.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", + "CA2000:Dispose objects before losing scope", + Scope = "member", + Target = "LanTool.Program.#Main()", + Justification = "Falscherkennung")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", + "CA1800:DoNotCastUnnecessarily", + Scope = "member", + Target = "LanTool.MainForm.#GetStuffItem(System.Object)", + Justification = "Geht net anders")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", + "CA1801:ReviewUnusedParameters", + MessageId = "state", + Scope = "member", + Target = "LanTool.StuffItem.#UpdateChilds(System.Object)", + Justification = "Geht net anders")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + "CA2210:AssembliesShouldHaveValidStrongNames", + Justification = "Hab ich ned")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "LanTool.Config.#EditConfig()")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Reliability", + "CA2000:Dispose objects before losing scope", + Scope = "member", + Target = "LanTool.MainForm.#tree_MouseUp(System.Object,System.Windows.Forms.MouseEventArgs)", + Justification = "Geht nicht anders." )] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "state", Scope = "member", Target = "LanTool.Classes.StuffItem.#UpdateChilds(System.Object)")] diff --git a/LanTool/Images/Aktualisieren.png b/LanTool/Images/Aktualisieren.png Binary files differ. diff --git a/LanTool/Images/DateiError.png b/LanTool/Images/DateiError.png Binary files differ. diff --git a/LanTool/Images/DateiExcluded.png b/LanTool/Images/DateiExcluded.png Binary files differ. diff --git a/LanTool/Images/DateiExcludedAndDeleted.png b/LanTool/Images/DateiExcludedAndDeleted.png Binary files differ. diff --git a/LanTool/Images/DateiFrischGesaugt.png b/LanTool/Images/DateiFrischGesaugt.png Binary files differ. diff --git a/LanTool/Images/DateiGruen.png b/LanTool/Images/DateiGruen.png Binary files differ. diff --git a/LanTool/Images/DateiLoeschen.png b/LanTool/Images/DateiLoeschen.png Binary files differ. diff --git a/LanTool/Images/DateiRot.png b/LanTool/Images/DateiRot.png Binary files differ. diff --git a/LanTool/Images/DateiSaugen.png b/LanTool/Images/DateiSaugen.png Binary files differ. diff --git a/LanTool/Images/DateiWeiss.png b/LanTool/Images/DateiWeiss.png Binary files differ. diff --git a/LanTool/Images/Demarkieren.png b/LanTool/Images/Demarkieren.png Binary files differ. diff --git a/LanTool/Images/DownArrow.png b/LanTool/Images/DownArrow.png Binary files differ. diff --git a/LanTool/Images/Entfernen.png b/LanTool/Images/Entfernen.png Binary files differ. diff --git a/LanTool/Images/Hinzufuegen.png b/LanTool/Images/Hinzufuegen.png Binary files differ. diff --git a/LanTool/Images/Markieren.png b/LanTool/Images/Markieren.png Binary files differ. diff --git a/LanTool/Images/Oeffnen.png b/LanTool/Images/Oeffnen.png Binary files differ. diff --git a/LanTool/Images/Ordner.png b/LanTool/Images/Ordner.png Binary files differ. diff --git a/LanTool/Images/OrdnerLoeschen.png b/LanTool/Images/OrdnerLoeschen.png Binary files differ. diff --git a/LanTool/Images/UpArrow.png b/LanTool/Images/UpArrow.png Binary files differ. diff --git a/LanTool/Images/Zuklappen.png b/LanTool/Images/Zuklappen.png Binary files differ. diff --git a/LanTool/Images/newcap.ico b/LanTool/Images/newcap.ico Binary files differ. diff --git a/LanTool/LanTool.csproj b/LanTool/LanTool.csproj @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{30E17D21-D90E-4069-9C40-E960119BA296}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>LanTool</RootNamespace> + <AssemblyName>LanTool</AssemblyName> + <ApplicationIcon>Images\newcap.ico</ApplicationIcon> + <FileUpgradeFlags> + </FileUpgradeFlags> + <UpgradeBackupLocation> + </UpgradeBackupLocation> + <OldToolsVersion>3.5</OldToolsVersion> + <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> + <StartupObject>LanTool.Program</StartupObject> + <IsWebBootstrapper>false</IsWebBootstrapper> + <TargetFrameworkProfile /> + <SccProjectName>SAK</SccProjectName> + <SccLocalPath>SAK</SccLocalPath> + <SccAuxPath>SAK</SccAuxPath> + <SccProvider>SAK</SccProvider> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>true</UpdateEnabled> + <UpdateMode>Background</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>true</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <TargetCulture>de-DE</TargetCulture> + <ProductName>LanTool</ProductName> + <PublisherName>René Wagner</PublisherName> + <SuiteName>LanTool</SuiteName> + <CreateWebPageOnPublish>true</CreateWebPageOnPublish> + <WebPage>publish.htm</WebPage> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.6.0.0</ApplicationVersion> + <UseApplicationTrust>false</UseApplicationTrust> + <CreateDesktopShortcut>true</CreateDesktopShortcut> + <PublishWizardCompleted>true</PublishWizardCompleted> + <BootstrapperEnabled>true</BootstrapperEnabled> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>TRACE;DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Debug\LanTool.XML</DocumentationFile> + <RunCodeAnalysis>true</RunCodeAnalysis> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <DocumentationFile>bin\Release\LanTool.XML</DocumentationFile> + <RunCodeAnalysis>true</RunCodeAnalysis> + <CodeAnalysisRuleSet>Configurations\rw-net.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup> + <GenerateManifests>false</GenerateManifests> + </PropertyGroup> + <PropertyGroup> + <TargetZone>LocalIntranet</TargetZone> + </PropertyGroup> + <PropertyGroup /> + <PropertyGroup> + <ApplicationManifest>Properties\app.manifest</ApplicationManifest> + </PropertyGroup> + <PropertyGroup> + <SignAssembly>true</SignAssembly> + </PropertyGroup> + <PropertyGroup> + <AssemblyOriginatorKeyFile>..\..\StrongName.snk</AssemblyOriginatorKeyFile> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="AboutBox.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="AboutBox.Designer.cs"> + <DependentUpon>AboutBox.cs</DependentUpon> + </Compile> + <Compile Include="Classes\Enums.cs" /> + <Compile Include="Classes\GlobalCache.cs" /> + <Compile Include="Classes\StuffItemPair.cs" /> + <Compile Include="Classes\Config.cs" /> + <Compile Include="Classes\TreeViewExtensions.cs" /> + <Compile Include="ConfigEdit.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="ConfigEdit.Designer.cs"> + <DependentUpon>ConfigEdit.cs</DependentUpon> + </Compile> + <Compile Include="ConfigListBox.cs"> + <SubType>UserControl</SubType> + </Compile> + <Compile Include="ConfigListBox.Designer.cs"> + <DependentUpon>ConfigListBox.cs</DependentUpon> + </Compile> + <Compile Include="FilterDialog.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="FilterDialog.Designer.cs"> + <DependentUpon>FilterDialog.cs</DependentUpon> + </Compile> + <Compile Include="GlobalSuppressions.cs" /> + <Compile Include="MainForm.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="MainForm.Designer.cs"> + <DependentUpon>MainForm.cs</DependentUpon> + </Compile> + <Compile Include="Classes\StuffItemTree.cs" /> + <Compile Include="Classes\NativeMethods.cs" /> + <Compile Include="NewFolderDialog.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="NewFolderDialog.designer.cs"> + <DependentUpon>NewFolderDialog.cs</DependentUpon> + </Compile> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <EmbeddedResource Include="AboutBox.resx"> + <DependentUpon>AboutBox.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="ConfigEdit.resx"> + <DependentUpon>ConfigEdit.cs</DependentUpon> + <SubType>Designer</SubType> + </EmbeddedResource> + <EmbeddedResource Include="ConfigListBox.resx"> + <SubType>Designer</SubType> + <DependentUpon>ConfigListBox.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="FilterDialog.resx"> + <SubType>Designer</SubType> + <DependentUpon>FilterDialog.cs</DependentUpon> + </EmbeddedResource> + <EmbeddedResource Include="MainForm.resx"> + <DependentUpon>MainForm.cs</DependentUpon> + <SubType>Designer</SubType> + </EmbeddedResource> + <EmbeddedResource Include="NewFolderDialog.resx"> + <DependentUpon>NewFolderDialog.cs</DependentUpon> + <SubType>Designer</SubType> + </EmbeddedResource> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + <SubType>Designer</SubType> + </EmbeddedResource> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Resources.resx</DependentUpon> + <DesignTime>True</DesignTime> + </Compile> + <Compile Include="Classes\StuffItem.cs" /> + <Compile Include="Classes\TaskBarList.cs" /> + </ItemGroup> + <ItemGroup> + <Content Include="Dokumentation\Abgelehnt.txt" /> + <Content Include="Dokumentation\LanTool_Tipps.txt"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="Dokumentation\LanTool_ChangeLog.txt"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="Dokumentation\ToDo.txt" /> + <Content Include="Images\Aktualisieren.png" /> + <Content Include="Images\DateiError.png" /> + <Content Include="Images\DateiExcluded.png" /> + <Content Include="Images\DateiExcludedAndDeleted.png" /> + <Content Include="Images\DateiFrischGesaugt.png" /> + <Content Include="Images\DateiGruen.png" /> + <Content Include="Images\DateiLoeschen.png" /> + <Content Include="Images\DateiRot.png" /> + <Content Include="Images\DateiSaugen.png" /> + <Content Include="Images\DateiWeiss.png" /> + <Content Include="Images\Demarkieren.png" /> + <Content Include="Images\DownArrow.png" /> + <Content Include="Images\Entfernen.png" /> + <Content Include="Images\Hinzufuegen.png" /> + <Content Include="Images\Markieren.png" /> + <Content Include="Images\Oeffnen.png" /> + <Content Include="Images\Ordner.png" /> + <Content Include="Images\OrdnerLoeschen.png" /> + <Content Include="Images\UpArrow.png" /> + <Content Include="Images\Zuklappen.png" /> + <Content Include="Images\newcap.ico" /> + <None Include="..\..\StrongName.snk"> + <Link>StrongName.snk</Link> + </None> + <None Include="Configurations\rw-net.ruleset" /> + <None Include="Resources\openfolderHS.png" /> + <None Include="Resources\FindHS.png" /> + <None Include="Resources\EditTableHS.png" /> + <None Include="Resources\OpenFile.png" /> + <None Include="Resources\saveHS.png" /> + <None Include="Resources\DeleteHS.png" /> + <None Include="Resources\HTMLPage.png" /> + <None Include="Configurations\rw-net.snk" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include=".NETFramework,Version=v4.6"> + <Visible>False</Visible> + <ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> + <Visible>False</Visible> + <ProductName>.NET Framework 2.0 %28x86%29</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.0"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.0 %28x86%29</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>false</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> + <Visible>False</Visible> + <ProductName>Windows Installer 3.1</ProductName> + <Install>true</Install> + </BootstrapperPackage> + </ItemGroup> + <ItemGroup> + <None Include="app.config" /> + <None Include="Properties\app.manifest" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> +\ No newline at end of file diff --git a/LanTool/MainForm.Designer.cs b/LanTool/MainForm.Designer.cs @@ -0,0 +1,611 @@ +namespace LanTool +{ + /// <summary> + /// Hauptfenster vom LanTool + /// </summary> + partial class MainForm + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + m_Cache.Dispose(); + + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.MainMenuToolStrip = new System.Windows.Forms.MenuStrip(); + this.MainMenuDatei = new System.Windows.Forms.ToolStripMenuItem(); + this.FileMenuEditConfig = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.offlineCacheLöschenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.FileMenuHashCacheLoeschen = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); + this.FileMenuProtokollausgabeLoeschen = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.FileMenuExit = new System.Windows.Forms.ToolStripMenuItem(); + this.MainMenuEigenePlatten = new System.Windows.Forms.ToolStripMenuItem(); + this.MainMenuFremdePlatten = new System.Windows.Forms.ToolStripMenuItem(); + this.infoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.lanToolTippsTricksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.lanToolChangeLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.lanToolForumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.fTPMitDemLanToolNetDriveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.überToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.suchenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.searchField = new System.Windows.Forms.ToolStripTextBox(); + this.fileSystemImageList = new System.Windows.Forms.ImageList(this.components); + this.VerticalSplitContainer = new System.Windows.Forms.SplitContainer(); + this.myDisksSplitContainer = new System.Windows.Forms.SplitContainer(); + this.myDisksPath = new System.Windows.Forms.TextBox(); + this.myDisksTree = new System.Windows.Forms.TreeView(); + this.otherDisksSplitContainer = new System.Windows.Forms.SplitContainer(); + this.otherDisksPath = new System.Windows.Forms.TextBox(); + this.otherDisksTree = new System.Windows.Forms.TreeView(); + this.HorizontalSplitContainer = new System.Windows.Forms.SplitContainer(); + this.logTextBox = new System.Windows.Forms.RichTextBox(); + this.stsStatus = new System.Windows.Forms.StatusStrip(); + this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.statusThreads = new System.Windows.Forms.ToolStripStatusLabel(); + this.statusProgress = new System.Windows.Forms.ToolStripProgressBar(); + this.MainMenuToolStrip.SuspendLayout(); + this.VerticalSplitContainer.Panel1.SuspendLayout(); + this.VerticalSplitContainer.Panel2.SuspendLayout(); + this.VerticalSplitContainer.SuspendLayout(); + this.myDisksSplitContainer.Panel1.SuspendLayout(); + this.myDisksSplitContainer.Panel2.SuspendLayout(); + this.myDisksSplitContainer.SuspendLayout(); + this.otherDisksSplitContainer.Panel1.SuspendLayout(); + this.otherDisksSplitContainer.Panel2.SuspendLayout(); + this.otherDisksSplitContainer.SuspendLayout(); + this.HorizontalSplitContainer.Panel1.SuspendLayout(); + this.HorizontalSplitContainer.Panel2.SuspendLayout(); + this.HorizontalSplitContainer.SuspendLayout(); + this.stsStatus.SuspendLayout(); + this.SuspendLayout(); + // + // MainMenuToolStrip + // + this.MainMenuToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.MainMenuDatei, + this.MainMenuEigenePlatten, + this.MainMenuFremdePlatten, + this.infoToolStripMenuItem, + this.suchenToolStripMenuItem, + this.searchField}); + this.MainMenuToolStrip.Location = new System.Drawing.Point(0, 0); + this.MainMenuToolStrip.Name = "MainMenuToolStrip"; + this.MainMenuToolStrip.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2); + this.MainMenuToolStrip.Size = new System.Drawing.Size(1008, 27); + this.MainMenuToolStrip.TabIndex = 0; + // + // MainMenuDatei + // + this.MainMenuDatei.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.FileMenuEditConfig, + this.toolStripMenuItem1, + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem, + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem, + this.offlineCacheLöschenToolStripMenuItem, + this.toolStripMenuItem2, + this.FileMenuHashCacheLoeschen, + this.toolStripMenuItem4, + this.FileMenuProtokollausgabeLoeschen, + this.toolStripMenuItem3, + this.FileMenuExit}); + this.MainMenuDatei.Name = "MainMenuDatei"; + this.MainMenuDatei.Size = new System.Drawing.Size(46, 23); + this.MainMenuDatei.Text = "&Datei"; + // + // FileMenuEditConfig + // + this.FileMenuEditConfig.Image = global::LanTool.Properties.Resources.EditTableHS; + this.FileMenuEditConfig.Name = "FileMenuEditConfig"; + this.FileMenuEditConfig.ShortcutKeyDisplayString = "F2"; + this.FileMenuEditConfig.ShortcutKeys = System.Windows.Forms.Keys.F2; + this.FileMenuEditConfig.Size = new System.Drawing.Size(396, 22); + this.FileMenuEditConfig.Text = "&Konfiguration bearbeiten..."; + this.FileMenuEditConfig.Click += new System.EventHandler(this.konfigurationToolStripMenuItem_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(393, 6); + // + // verzeichnisFürMeinePlattenImportierenToolStripMenuItem + // + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.Image = global::LanTool.Properties.Resources.OpenFile; + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.Name = "verzeichnisFürMeinePlattenImportierenToolStripMenuItem"; + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.ShortcutKeyDisplayString = "Strg+O"; + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.Size = new System.Drawing.Size(396, 22); + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.Text = "Offline-Verzeichnis für \"Meine Platten\" einlesen...."; + this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem.Click += new System.EventHandler(this.verzeichnisFürMeinePlattenImportierenToolStripMenuItem_Click); + // + // verzeichnisFürEinePlattenExortierenToolStripMenuItem + // + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.Image = global::LanTool.Properties.Resources.saveHS; + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.Name = "verzeichnisFürEinePlattenExortierenToolStripMenuItem"; + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.ShortcutKeyDisplayString = "Strg+S"; + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.Size = new System.Drawing.Size(396, 22); + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.Text = "Offline-Verzeichnis für \"Meine Platten\" abspeichern..."; + this.verzeichnisFürEinePlattenExortierenToolStripMenuItem.Click += new System.EventHandler(this.verzeichnisFürMeinePlattenExportierenToolStripMenuItem_Click); + // + // offlineCacheLöschenToolStripMenuItem + // + this.offlineCacheLöschenToolStripMenuItem.Image = global::LanTool.Properties.Resources.DeleteHS; + this.offlineCacheLöschenToolStripMenuItem.Name = "offlineCacheLöschenToolStripMenuItem"; + this.offlineCacheLöschenToolStripMenuItem.Size = new System.Drawing.Size(396, 22); + this.offlineCacheLöschenToolStripMenuItem.Text = "Offline-Caches löschen"; + this.offlineCacheLöschenToolStripMenuItem.Click += new System.EventHandler(this.offlineCacheLöschenToolStripMenuItem_Click); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(393, 6); + // + // FileMenuHashCacheLoeschen + // + this.FileMenuHashCacheLoeschen.Image = global::LanTool.Properties.Resources.DeleteHS; + this.FileMenuHashCacheLoeschen.Name = "FileMenuHashCacheLoeschen"; + this.FileMenuHashCacheLoeschen.Size = new System.Drawing.Size(396, 22); + this.FileMenuHashCacheLoeschen.Text = "Hash-Cache löschen"; + this.FileMenuHashCacheLoeschen.Click += new System.EventHandler(this.hashCacheLöschenToolStripMenuItem_Click); + // + // toolStripMenuItem4 + // + this.toolStripMenuItem4.Name = "toolStripMenuItem4"; + this.toolStripMenuItem4.Size = new System.Drawing.Size(393, 6); + // + // FileMenuProtokollausgabeLoeschen + // + this.FileMenuProtokollausgabeLoeschen.Name = "FileMenuProtokollausgabeLoeschen"; + this.FileMenuProtokollausgabeLoeschen.Size = new System.Drawing.Size(396, 22); + this.FileMenuProtokollausgabeLoeschen.Text = "Protokollausgabe löschen"; + this.FileMenuProtokollausgabeLoeschen.Click += new System.EventHandler(this.protokollausgabeLöschenToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(393, 6); + // + // FileMenuExit + // + this.FileMenuExit.Name = "FileMenuExit"; + this.FileMenuExit.ShortcutKeyDisplayString = "Alt+F4"; + this.FileMenuExit.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); + this.FileMenuExit.Size = new System.Drawing.Size(396, 22); + this.FileMenuExit.Text = "&Beenden"; + this.FileMenuExit.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // MainMenuEigenePlatten + // + this.MainMenuEigenePlatten.Name = "MainMenuEigenePlatten"; + this.MainMenuEigenePlatten.Size = new System.Drawing.Size(92, 23); + this.MainMenuEigenePlatten.Text = "&Meine Platten"; + // + // MainMenuFremdePlatten + // + this.MainMenuFremdePlatten.Name = "MainMenuFremdePlatten"; + this.MainMenuFremdePlatten.Size = new System.Drawing.Size(99, 23); + this.MainMenuFremdePlatten.Text = "&Fremde Platten"; + // + // infoToolStripMenuItem + // + this.infoToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.lanToolTippsTricksToolStripMenuItem, + this.lanToolChangeLogToolStripMenuItem, + this.lanToolForumToolStripMenuItem, + this.toolStripMenuItem5, + this.fTPMitDemLanToolNetDriveToolStripMenuItem, + this.toolStripSeparator1, + this.überToolStripMenuItem}); + this.infoToolStripMenuItem.Name = "infoToolStripMenuItem"; + this.infoToolStripMenuItem.Size = new System.Drawing.Size(40, 23); + this.infoToolStripMenuItem.Text = "&Info"; + // + // lanToolTippsTricksToolStripMenuItem + // + this.lanToolTippsTricksToolStripMenuItem.Image = global::LanTool.Properties.Resources.HTMLPage; + this.lanToolTippsTricksToolStripMenuItem.Name = "lanToolTippsTricksToolStripMenuItem"; + this.lanToolTippsTricksToolStripMenuItem.Size = new System.Drawing.Size(253, 22); + this.lanToolTippsTricksToolStripMenuItem.Text = "LanTool Tipps && Tricks"; + this.lanToolTippsTricksToolStripMenuItem.Click += new System.EventHandler(this.lanToolTippsTricksToolStripMenuItem_Click); + // + // lanToolChangeLogToolStripMenuItem + // + this.lanToolChangeLogToolStripMenuItem.Image = global::LanTool.Properties.Resources.HTMLPage; + this.lanToolChangeLogToolStripMenuItem.Name = "lanToolChangeLogToolStripMenuItem"; + this.lanToolChangeLogToolStripMenuItem.Size = new System.Drawing.Size(253, 22); + this.lanToolChangeLogToolStripMenuItem.Text = "LanTool ChangeLog"; + this.lanToolChangeLogToolStripMenuItem.Click += new System.EventHandler(this.lanToolChangeLogToolStripMenuItem_Click); + // + // lanToolForumToolStripMenuItem + // + this.lanToolForumToolStripMenuItem.Image = global::LanTool.Properties.Resources.HTMLPage; + this.lanToolForumToolStripMenuItem.Name = "lanToolForumToolStripMenuItem"; + this.lanToolForumToolStripMenuItem.Size = new System.Drawing.Size(253, 22); + this.lanToolForumToolStripMenuItem.Text = "LanTool-Forum"; + this.lanToolForumToolStripMenuItem.Visible = false; + this.lanToolForumToolStripMenuItem.Click += new System.EventHandler(this.lanToolForumToolStripMenuItem_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(250, 6); + // + // fTPMitDemLanToolNetDriveToolStripMenuItem + // + this.fTPMitDemLanToolNetDriveToolStripMenuItem.Name = "fTPMitDemLanToolNetDriveToolStripMenuItem"; + this.fTPMitDemLanToolNetDriveToolStripMenuItem.Size = new System.Drawing.Size(253, 22); + this.fTPMitDemLanToolNetDriveToolStripMenuItem.Text = "&FTP mit dem LanTool -> NetDrive"; + this.fTPMitDemLanToolNetDriveToolStripMenuItem.Click += new System.EventHandler(this.fTPMitDemLanToolNetDriveToolStripMenuItem_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(250, 6); + // + // überToolStripMenuItem + // + this.überToolStripMenuItem.Name = "überToolStripMenuItem"; + this.überToolStripMenuItem.Size = new System.Drawing.Size(253, 22); + this.überToolStripMenuItem.Text = "&Über"; + this.überToolStripMenuItem.Click += new System.EventHandler(this.überToolStripMenuItem_Click); + // + // suchenToolStripMenuItem + // + this.suchenToolStripMenuItem.AutoSize = false; + this.suchenToolStripMenuItem.Image = global::LanTool.Properties.Resources.FindHS; + this.suchenToolStripMenuItem.Name = "suchenToolStripMenuItem"; + this.suchenToolStripMenuItem.Size = new System.Drawing.Size(80, 23); + this.suchenToolStripMenuItem.Text = "&Suche:"; + this.suchenToolStripMenuItem.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.suchenToolStripMenuItem.Click += new System.EventHandler(this.suchenToolStripMenuItem_Click); + // + // searchField + // + this.searchField.AutoSize = false; + this.searchField.AutoToolTip = true; + this.searchField.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.searchField.Name = "searchField"; + this.searchField.Size = new System.Drawing.Size(150, 23); + this.searchField.ToolTipText = "Suche"; + this.searchField.KeyUp += new System.Windows.Forms.KeyEventHandler(this.searchField_KeyUp); + // + // fileSystemImageList + // + this.fileSystemImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("fileSystemImageList.ImageStream"))); + this.fileSystemImageList.TransparentColor = System.Drawing.Color.Transparent; + this.fileSystemImageList.Images.SetKeyName(0, "Ordner.png"); + this.fileSystemImageList.Images.SetKeyName(1, "OrdnerErr.png"); + this.fileSystemImageList.Images.SetKeyName(2, "DateiWeiss.png"); + this.fileSystemImageList.Images.SetKeyName(3, "DateiRot.png"); + this.fileSystemImageList.Images.SetKeyName(4, "DateiSaugen.png"); + this.fileSystemImageList.Images.SetKeyName(5, "DateiFingerWeg.png"); + this.fileSystemImageList.Images.SetKeyName(6, "DateiFrischGesaugt.png"); + this.fileSystemImageList.Images.SetKeyName(7, "DateiGruen.png"); + this.fileSystemImageList.Images.SetKeyName(8, "DateiExcluded.png"); + this.fileSystemImageList.Images.SetKeyName(9, "DateiExcludedAndDeleted.png"); + this.fileSystemImageList.Images.SetKeyName(10, "DateiLoeschen.png"); + this.fileSystemImageList.Images.SetKeyName(11, "OrdnerLoeschen.png"); + this.fileSystemImageList.Images.SetKeyName(12, "Oeffnen.png"); + this.fileSystemImageList.Images.SetKeyName(13, "Demarkieren.png"); + this.fileSystemImageList.Images.SetKeyName(14, "Markieren.png"); + this.fileSystemImageList.Images.SetKeyName(15, "Hinzufuegen.png"); + this.fileSystemImageList.Images.SetKeyName(16, "Zuklappen.png"); + this.fileSystemImageList.Images.SetKeyName(17, "Aktualisieren.png"); + this.fileSystemImageList.Images.SetKeyName(18, "Entfernen.png"); + this.fileSystemImageList.Images.SetKeyName(19, "DateiGelb.png"); + // + // VerticalSplitContainer + // + this.VerticalSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.VerticalSplitContainer.Location = new System.Drawing.Point(0, 0); + this.VerticalSplitContainer.Name = "VerticalSplitContainer"; + // + // VerticalSplitContainer.Panel1 + // + this.VerticalSplitContainer.Panel1.Controls.Add(this.myDisksSplitContainer); + // + // VerticalSplitContainer.Panel2 + // + this.VerticalSplitContainer.Panel2.Controls.Add(this.otherDisksSplitContainer); + this.VerticalSplitContainer.Size = new System.Drawing.Size(1008, 426); + this.VerticalSplitContainer.SplitterDistance = 487; + this.VerticalSplitContainer.TabIndex = 9; + // + // myDisksSplitContainer + // + this.myDisksSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.myDisksSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.myDisksSplitContainer.IsSplitterFixed = true; + this.myDisksSplitContainer.Location = new System.Drawing.Point(0, 0); + this.myDisksSplitContainer.Name = "myDisksSplitContainer"; + this.myDisksSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // myDisksSplitContainer.Panel1 + // + this.myDisksSplitContainer.Panel1.Controls.Add(this.myDisksPath); + this.myDisksSplitContainer.Panel1MinSize = 20; + // + // myDisksSplitContainer.Panel2 + // + this.myDisksSplitContainer.Panel2.Controls.Add(this.myDisksTree); + this.myDisksSplitContainer.Size = new System.Drawing.Size(487, 426); + this.myDisksSplitContainer.SplitterDistance = 20; + this.myDisksSplitContainer.TabIndex = 0; + // + // myDisksPath + // + this.myDisksPath.Dock = System.Windows.Forms.DockStyle.Top; + this.myDisksPath.Location = new System.Drawing.Point(0, 0); + this.myDisksPath.Name = "myDisksPath"; + this.myDisksPath.ReadOnly = true; + this.myDisksPath.Size = new System.Drawing.Size(487, 20); + this.myDisksPath.TabIndex = 2; + this.myDisksPath.KeyUp += new System.Windows.Forms.KeyEventHandler(this.DisksPath_KeyUp); + this.myDisksPath.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.DisksPath_OpenPath); + // + // myDisksTree + // + this.myDisksTree.AllowDrop = true; + this.myDisksTree.CheckBoxes = true; + this.myDisksTree.Dock = System.Windows.Forms.DockStyle.Fill; + this.myDisksTree.FullRowSelect = true; + this.myDisksTree.HideSelection = false; + this.myDisksTree.ImageIndex = 0; + this.myDisksTree.ImageList = this.fileSystemImageList; + this.myDisksTree.Location = new System.Drawing.Point(0, 0); + this.myDisksTree.Name = "myDisksTree"; + this.myDisksTree.SelectedImageIndex = 0; + this.myDisksTree.ShowNodeToolTips = true; + this.myDisksTree.Size = new System.Drawing.Size(487, 402); + this.myDisksTree.TabIndex = 1; + this.myDisksTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.myDisksTree_AfterSelect); + this.myDisksTree.DragDrop += new System.Windows.Forms.DragEventHandler(this.myDisksTree_DragDrop); + this.myDisksTree.DragEnter += new System.Windows.Forms.DragEventHandler(this.myDisksTree_DragEnter); + this.myDisksTree.DragOver += new System.Windows.Forms.DragEventHandler(this.myDisksTree_DragEnter); + this.myDisksTree.Enter += new System.EventHandler(this.DisksTree_Enter); + this.myDisksTree.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + this.myDisksTree.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tree_MouseDoubleClick); + this.myDisksTree.MouseUp += new System.Windows.Forms.MouseEventHandler(this.tree_MouseUp); + // + // otherDisksSplitContainer + // + this.otherDisksSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.otherDisksSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.otherDisksSplitContainer.IsSplitterFixed = true; + this.otherDisksSplitContainer.Location = new System.Drawing.Point(0, 0); + this.otherDisksSplitContainer.Name = "otherDisksSplitContainer"; + this.otherDisksSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // otherDisksSplitContainer.Panel1 + // + this.otherDisksSplitContainer.Panel1.Controls.Add(this.otherDisksPath); + this.otherDisksSplitContainer.Panel1MinSize = 20; + // + // otherDisksSplitContainer.Panel2 + // + this.otherDisksSplitContainer.Panel2.Controls.Add(this.otherDisksTree); + this.otherDisksSplitContainer.Size = new System.Drawing.Size(517, 426); + this.otherDisksSplitContainer.SplitterDistance = 20; + this.otherDisksSplitContainer.TabIndex = 0; + // + // otherDisksPath + // + this.otherDisksPath.Dock = System.Windows.Forms.DockStyle.Top; + this.otherDisksPath.Location = new System.Drawing.Point(0, 0); + this.otherDisksPath.Name = "otherDisksPath"; + this.otherDisksPath.ReadOnly = true; + this.otherDisksPath.Size = new System.Drawing.Size(517, 20); + this.otherDisksPath.TabIndex = 3; + this.otherDisksPath.KeyUp += new System.Windows.Forms.KeyEventHandler(this.DisksPath_KeyUp); + this.otherDisksPath.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.DisksPath_OpenPath); + // + // otherDisksTree + // + this.otherDisksTree.CheckBoxes = true; + this.otherDisksTree.Dock = System.Windows.Forms.DockStyle.Fill; + this.otherDisksTree.FullRowSelect = true; + this.otherDisksTree.HideSelection = false; + this.otherDisksTree.ImageIndex = 0; + this.otherDisksTree.ImageList = this.fileSystemImageList; + this.otherDisksTree.Indent = 19; + this.otherDisksTree.LabelEdit = true; + this.otherDisksTree.Location = new System.Drawing.Point(0, 0); + this.otherDisksTree.Name = "otherDisksTree"; + this.otherDisksTree.SelectedImageIndex = 0; + this.otherDisksTree.ShowNodeToolTips = true; + this.otherDisksTree.Size = new System.Drawing.Size(517, 402); + this.otherDisksTree.TabIndex = 3; + this.otherDisksTree.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.otherDisksTree_ItemDrag); + this.otherDisksTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.otherDisksTree_AfterSelect); + this.otherDisksTree.Enter += new System.EventHandler(this.DisksTree_Enter); + this.otherDisksTree.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + this.otherDisksTree.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.tree_MouseDoubleClick); + this.otherDisksTree.MouseUp += new System.Windows.Forms.MouseEventHandler(this.tree_MouseUp); + // + // HorizontalSplitContainer + // + this.HorizontalSplitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.HorizontalSplitContainer.Location = new System.Drawing.Point(0, 30); + this.HorizontalSplitContainer.Name = "HorizontalSplitContainer"; + this.HorizontalSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // HorizontalSplitContainer.Panel1 + // + this.HorizontalSplitContainer.Panel1.Controls.Add(this.VerticalSplitContainer); + this.HorizontalSplitContainer.Panel1MinSize = 15; + // + // HorizontalSplitContainer.Panel2 + // + this.HorizontalSplitContainer.Panel2.Controls.Add(this.logTextBox); + this.HorizontalSplitContainer.Panel2MinSize = 15; + this.HorizontalSplitContainer.Size = new System.Drawing.Size(1008, 549); + this.HorizontalSplitContainer.SplitterDistance = 426; + this.HorizontalSplitContainer.TabIndex = 4; + // + // logTextBox + // + this.logTextBox.DetectUrls = false; + this.logTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.logTextBox.ForeColor = System.Drawing.SystemColors.WindowText; + this.logTextBox.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.logTextBox.Location = new System.Drawing.Point(0, 0); + this.logTextBox.Name = "logTextBox"; + this.logTextBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.logTextBox.Size = new System.Drawing.Size(1008, 119); + this.logTextBox.TabIndex = 2; + this.logTextBox.Text = ""; + this.logTextBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + // + // stsStatus + // + this.stsStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.statusLabel, + this.statusThreads, + this.statusProgress}); + this.stsStatus.Location = new System.Drawing.Point(0, 582); + this.stsStatus.Name = "stsStatus"; + this.stsStatus.ShowItemToolTips = true; + this.stsStatus.Size = new System.Drawing.Size(1008, 22); + this.stsStatus.TabIndex = 6; + this.stsStatus.Text = "statusStrip1"; + // + // statusLabel + // + this.statusLabel.Name = "statusLabel"; + this.statusLabel.Size = new System.Drawing.Size(765, 17); + this.statusLabel.Spring = true; + this.statusLabel.Text = "Guten Tag!"; + this.statusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.statusLabel.ToolTipText = "letzte Statusinfo"; + // + // statusThreads + // + this.statusThreads.Name = "statusThreads"; + this.statusThreads.Size = new System.Drawing.Size(26, 17); + this.statusThreads.Text = "T: 0"; + this.statusThreads.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.statusThreads.ToolTipText = "Anzahl aktiver Kopier-Threads."; + // + // statusProgress + // + this.statusProgress.Name = "statusProgress"; + this.statusProgress.Size = new System.Drawing.Size(200, 16); + this.statusProgress.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.statusProgress.ToolTipText = "Noch nichts kopiert!"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1008, 604); + this.Controls.Add(this.MainMenuToolStrip); + this.Controls.Add(this.HorizontalSplitContainer); + this.Controls.Add(this.stsStatus); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.MainMenuToolStrip; + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "MainForm"; + this.WindowState = System.Windows.Forms.FormWindowState.Maximized; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.Load += new System.EventHandler(this.MainForm_Load); + this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + this.MainMenuToolStrip.ResumeLayout(false); + this.MainMenuToolStrip.PerformLayout(); + this.VerticalSplitContainer.Panel1.ResumeLayout(false); + this.VerticalSplitContainer.Panel2.ResumeLayout(false); + this.VerticalSplitContainer.ResumeLayout(false); + this.myDisksSplitContainer.Panel1.ResumeLayout(false); + this.myDisksSplitContainer.Panel1.PerformLayout(); + this.myDisksSplitContainer.Panel2.ResumeLayout(false); + this.myDisksSplitContainer.ResumeLayout(false); + this.otherDisksSplitContainer.Panel1.ResumeLayout(false); + this.otherDisksSplitContainer.Panel1.PerformLayout(); + this.otherDisksSplitContainer.Panel2.ResumeLayout(false); + this.otherDisksSplitContainer.ResumeLayout(false); + this.HorizontalSplitContainer.Panel1.ResumeLayout(false); + this.HorizontalSplitContainer.Panel2.ResumeLayout(false); + this.HorizontalSplitContainer.ResumeLayout(false); + this.stsStatus.ResumeLayout(false); + this.stsStatus.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip MainMenuToolStrip; + private System.Windows.Forms.ToolStripMenuItem MainMenuDatei; + private System.Windows.Forms.ToolStripMenuItem FileMenuExit; + private System.Windows.Forms.SplitContainer VerticalSplitContainer; + private System.Windows.Forms.SplitContainer HorizontalSplitContainer; + private System.Windows.Forms.ImageList fileSystemImageList; + private System.Windows.Forms.ToolStripMenuItem FileMenuEditConfig; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem FileMenuProtokollausgabeLoeschen; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem FileMenuHashCacheLoeschen; + private System.Windows.Forms.StatusStrip stsStatus; + private System.Windows.Forms.ToolStripStatusLabel statusLabel; + private System.Windows.Forms.ToolStripProgressBar statusProgress; + private System.Windows.Forms.ToolStripMenuItem MainMenuEigenePlatten; + private System.Windows.Forms.ToolStripMenuItem MainMenuFremdePlatten; + private System.Windows.Forms.ToolStripMenuItem verzeichnisFürEinePlattenExortierenToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem verzeichnisFürMeinePlattenImportierenToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem offlineCacheLöschenToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem infoToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fTPMitDemLanToolNetDriveToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem überToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripStatusLabel statusThreads; + private System.Windows.Forms.ToolStripTextBox searchField; + private System.Windows.Forms.ToolStripMenuItem suchenToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem lanToolForumToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; + private System.Windows.Forms.ToolStripMenuItem lanToolTippsTricksToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem lanToolChangeLogToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.TextBox myDisksPath; + private System.Windows.Forms.TreeView myDisksTree; + private System.Windows.Forms.TextBox otherDisksPath; + private System.Windows.Forms.TreeView otherDisksTree; + private System.Windows.Forms.RichTextBox logTextBox; + private System.Windows.Forms.SplitContainer myDisksSplitContainer; + private System.Windows.Forms.SplitContainer otherDisksSplitContainer; + } +} + diff --git a/LanTool/MainForm.cs b/LanTool/MainForm.cs @@ -0,0 +1,2362 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using LanTool.Classes; + +namespace LanTool +{ + public partial class MainForm : Form + { + #region Konstanten + + internal const string DefaultHeader = "LanTool 1.6 - LumpLan #1 Edition"; + + #endregion + + #region Felder + + internal StuffItemTree m_MyDisks = new StuffItemTree("Meine Platten", false); + + internal StuffItemTree m_OtherDisks = new StuffItemTree("Fremde Platten", true); + + // Zähler für die Anzahl der Kopierthreads + int copyThreadCount = 0; + + // Zähler für das Maximum des Fortschrittsbalkens + float maxProgressMB = 0; + float currentProgressMB = 0; + + /// <summary> + /// Pfad für Config/Exclude-Files etc. + /// </summary> + private static string basePath = "c:\\"; + + /// <summary> + /// Alle Konfigurationsdaten + /// </summary> + internal Config m_Config; + + /// <summary> + /// Die Caches für das Hauptfenster + /// </summary> + internal GlobalCache m_Cache; + + #endregion + + #region Hilfsfelder für die Suche + + /// <summary> + /// Speichert das zuletzt benutzte TreeView + /// </summary> + TreeView lastUsedView = null; + /// <summary> + /// Liste mit StuffItems, die bereits angezeigt wurden + /// </summary> + List<string> itemsAlreadyFound = new List<string>(); + /// <summary> + /// Suchstring, nachdem zuletzt gesucht wurde + /// </summary> + string lastSearchString = string.Empty; + + #endregion + + #region Windows 7-Spezialitäten + /// <summary> + /// Zugriff auf Windows 7-Superbar + /// </summary> + ITaskbarList3 tbl = null; + + private bool IsWin7 = Environment.OSVersion.Version.ToString().StartsWith("6.1"); + + #endregion + + /// <summary> + /// Konstruktor für das Formular + /// </summary> + public MainForm() + { + InitializeComponent(); + } + + /// <summary> + /// On Load Config ausführen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void MainForm_Load(object sender, EventArgs e) + { + // Pfad zur Datei ermitteln + basePath = Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf("\\") + 1); + + // Konfiguration von Platte einlesen + m_Config = new Config(basePath); + + // Programm mit niedriger Priorität ausführen + if (m_Config.IsLowerPriority) + { + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; + } + + // Fenstertitel setzen + if (!string.IsNullOrEmpty(m_Config.HeaderExtension)) + { + Text = String.Format("[{0}] {1}", m_Config.HeaderExtension, DefaultHeader); + } + else + { + Text = DefaultHeader; + } + + // Daten von der Platte einlesen + m_Cache = new GlobalCache(basePath); + + // Menüs erweitern + AddFremdePlattenMenu(MainMenuFremdePlatten.DropDownItems); + AddEigenePlattenMenu(MainMenuEigenePlatten.DropDownItems); + + // wenn eine DefaultOfflineDatei hinterlegt ist + if (!String.IsNullOrEmpty(m_Config.DefaultOfflineFile)) + { + if (File.Exists(m_Config.DefaultOfflineFile)) + { + m_MyDisks.LoadOfflineCacheFromFile(m_Config.DefaultOfflineFile); + } + else + { + LogError("DefaultOfflineDatei " + m_Config.DefaultOfflineFile + " existiert nicht."); + } + } + + // Standardeinstellungen für den "Meine Platten"-Tree anlegen + myDisksTree.AfterCheck += new TreeViewEventHandler(TransferCheckToStuffItem); + myDisksTree.TreeViewNodeSorter = (IComparer)new StuffItemSorter(); + + // Standardeinstellungen für den "Andere Platten"-Tree anlegen + otherDisksTree.AfterCheck += new TreeViewEventHandler(TransferCheckToStuffItem); + otherDisksTree.TreeViewNodeSorter = (IComparer)new StuffItemSorter(); + + StartUpdate(); + + // nur Windows 7/Server 2008 R2 + if (IsWin7) + { + tbl = (ITaskbarList3)new TaskbarList(); + } + } + + /// <summary> + /// Kopiert eine Liste von Dateien an den angegebenen Zielort + /// </summary> + /// <param name="state"></param> + public void CopyFiles(object state) + { + // Thread-Zähler erhöhen + copyThreadCount++; + + // Fehlerzähler + int errorCount = 0; + // Zähler für die kopierten Dateien + int copiedFileCount = 0; + float copiedFileSizeMB = 0; + + List<StuffItemPair> copylist = (List<StuffItemPair>)state; + + if (copylist.Count < 1) + return; + + // Größe aller Dateien für die Einrichtung des Fortschrittsbalkens ermitteln + float allFileSizeMB = 0; + foreach (StuffItemPair pair in copylist) + { + try + { + FileInfo sourceInfo = new FileInfo(pair.Source.Path); + allFileSizeMB += sourceInfo.Length / 1024 / 1024; + } + catch { } + { + // mit 1 vorbelegen wegen division durch 0 + if (allFileSizeMB == 0) + allFileSizeMB = 1; + } + } + + // Setzen des Maximalwerts des Fortschrittsbalkens + maxProgressMB += allFileSizeMB; + + Progress(copyThreadCount + "|0"); + + DateTime startTime = DateTime.Now; + + // jede Datei kopieren + foreach (StuffItemPair sip in copylist) + { + float sourceSizeMB = 0; + try + { + // Quelle und Ziel bestimmen + string source = sip.Source.Path; + string target = Path.Combine(sip.Target.Path, Path.GetFileName(sip.Source.Path)); + + // Dateigröße der Quelldatei bestimmen + try + { + FileInfo sourceInfo = new FileInfo(source); + sourceSizeMB = (sourceInfo.Length / 1024 / 1024); + } + catch (Exception ex) + { + sourceSizeMB = 0; + LogWarning("Fehler: Größe der Datei " + source + " konnte nicht ermittelt werden: " + ex.Message); + } + + // Dateianzahl erhöhen + copiedFileCount++; + + Status("Kopiere Datei " + copiedFileCount.ToString() + " von " + copylist.Count.ToString() + ": " + source + " -> " + target + " (" + sourceSizeMB.ToString() + " MB)"); + Log("Kopiere Datei " + copiedFileCount.ToString() + " von " + copylist.Count.ToString() + ": " + source + " -> " + target + " (" + sourceSizeMB.ToString() + " MB)"); + try + { + Directory.CreateDirectory(sip.Target.Path); + } + catch (Exception ee) + { + LogError("Fehler beim Erstellen des Verzeichnisses: " + ee.Message); + } + File.Copy(source, target); + // Markierung entfernen + sip.Source.Checked = false; + } + catch (Exception e) + { + LogError("Fehler beim Kopieren der Datei " + sip.Source.Path + " : " + e.Message); + errorCount++; + } + finally + { + // Fortschritt aktualisieren + copiedFileSizeMB += sourceSizeMB; + Progress(copyThreadCount + "|" + sourceSizeMB); + } + } + + // Thread-Zähler verringern + copyThreadCount--; + + // Fortschrittsbalkenmaximum verringern + maxProgressMB -= allFileSizeMB; + currentProgressMB -= copiedFileSizeMB; + + // Fortschrittsbalken zurücksetzen + Progress(copyThreadCount + "|0"); + + DateTime endTime = DateTime.Now; + + // Anzeige der eigenen Platten aktualisieren + m_MyDisks.UpdateChildsBackground(); + + Status("Kopieren abgeschlossen! " + errorCount.ToString() + " von " + copylist.Count.ToString() + " Dateien konnten nicht kopiert werden."); + + // Meldung über Kopiervorgang anzeigen + TimeSpan copyTime = endTime - startTime; + LogHighlight("Kopiervorgang abgeschlossen! Dateien kopiert: " + copiedFileCount + " - Gesamtgröße: " + String.Format("{0:F2}", copiedFileSizeMB) + " MB - Dauer: " + String.Format("{0:F0}:{1:D2}:{2:D2}", copyTime.TotalHours, copyTime.Minutes, copyTime.Seconds) + " - Transferrate: " + String.Format("{0:F2}", copiedFileSizeMB / copyTime.TotalSeconds) + " MB/s"); + Message("Kopiervorgang abgeschlossen!" + Environment.NewLine + Environment.NewLine + "Dateien kopiert:\t" + copiedFileCount + Environment.NewLine + "Gesamtgröße:\t" + String.Format("{0:F2}", copiedFileSizeMB) + " MB" + Environment.NewLine + "Dauer:\t\t" + String.Format("{0:F0}:{1:D2}:{2:D2}", copyTime.TotalHours, copyTime.Minutes, copyTime.Seconds) + Environment.NewLine + "Transferrate:\t" + String.Format("{0:F2}", copiedFileSizeMB / copyTime.TotalSeconds) + " MB/s"); + } + + #region Klicks auf Menuepunkte + + /// <summary> + /// KLick auf Exit + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + /// <summary> + /// Klick auf "Ordner aktualisieren" + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void UpdateFolderClick(object sender, EventArgs e) + { + GetStuffItem(sender).UpdateChildsBackground(); + } + + /// <summary> + /// Klick auf "Löschen des Logs" + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void protokollausgabeLöschenToolStripMenuItem_Click(object sender, EventArgs e) + { + logTextBox.Clear(); + } + + /// <summary> + /// Konfiguration aufrufen und bei OK gleich scannen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void konfigurationToolStripMenuItem_Click(object sender, EventArgs e) + { + if (m_Config.EditConfig()) + { + StartUpdate(); + } + } + + /// <summary> + /// Eigene Platten erneut einlesen (z.zt nur default Konfiguration) + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void eigenePlattenAktualisierenToolStripMenuItem_Click(object sender, EventArgs e) + { + m_MyDisks.UpdateChildsBackground(); + } + + /// <summary> + /// Erneutes einlesen der fremden Platte + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void fremdePlatteAktualisierenToolStripMenuItem_Click(object sender, EventArgs e) + { + Program.MainWindow.m_OtherDisks.UpdateChildsBackground(); + } + + /// <summary> + /// Löschen des Hash-Caches (Datei löschen ginge auch ;-) + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void hashCacheLöschenToolStripMenuItem_Click(object sender, EventArgs e) + { + m_Cache.Clear(); + } + + #endregion + + #region Aktualisierung der Bäume (von Hintergrundthread aufrufbar) + + /// <summary> + /// Henkel um von einem Background-Prozess die Trees wieder zu aktualisieren + /// </summary> + public void UpdateTrees() + { + if ( InvokeRequired ) + { + Invoke( new MethodInvoker(UpdateTrees)); + } + else + { + UpdateMyDisksTreesInvoked(false); + UpdateOtherDisksTreesInvoked(false); + } + } + + /// <summary> + /// Henkel um von einem Background-Prozess die Trees wieder zu aktualisieren + /// Dabei werden unmarkierte und Zweige ohne Fehler zugeklappt + /// </summary> + public void CollapseMyDisks() + { + if ( InvokeRequired ) + { + Invoke( new MethodInvoker(CollapseMyDisks)); + } + else + { + UpdateMyDisksTreesInvoked(true); + } + } + + /// <summary> + /// Henkel um von einem Background-Prozess die Trees wieder zu aktualisieren + /// Dabei werden unmarkierte und Zweige ohne Fehler zugeklappt + /// </summary> + public void CollapseOtherDisks() + { + if ( InvokeRequired ) + { + Invoke( new MethodInvoker(CollapseOtherDisks)); + } + else + { + UpdateOtherDisksTreesInvoked(true); + } + } + + /// <summary> + /// Nur im Invoke-Zyklus rufbar! + /// </summary> + /// <param name="autoCollapse"></param> + private void UpdateMyDisksTreesInvoked(bool autoCollapse) + { + if ( InvokeRequired ) + { + throw new Exception("Dieser Aufruf ist nur im Invoke-Zylus erlaubt"); + } + + myDisksTree.BeginUpdate(); + + if (myDisksTree.Nodes.Count == 0) + { + myDisksTree.Nodes.Add(new TreeNode()); + } + + UpdateTreeRecursive( myDisksTree.Nodes[ 0 ], m_MyDisks, autoCollapse ); + + myDisksTree.Nodes[0].Expand(); + myDisksTree.Sort(); + + myDisksTree.EndUpdate(); + Status("Aktualisierung abgeschlossen!"); + } + + /// <summary> + /// Nur im Invoke-Zyklus rufbar! + /// </summary> + /// <param name="autoCollapse"></param> + private void UpdateOtherDisksTreesInvoked(bool autoCollapse) + { + if (this.InvokeRequired) + { + throw new Exception("Dieser Aufruf ist nur im Invoke-Zylus erlaubt"); + } + //---Rechter Baum + + otherDisksTree.BeginUpdate(); + if (otherDisksTree.Nodes.Count == 0) + { + otherDisksTree.Nodes.Add(new TreeNode()); + } + + UpdateTreeRecursive(otherDisksTree.Nodes[0], Program.MainWindow.m_OtherDisks, autoCollapse); + + otherDisksTree.Nodes[0].Expand(); + otherDisksTree.Sort(); + otherDisksTree.EndUpdate(); + Status("Aktualisierung abgeschlossen!"); + } + + /// <summary> + /// Checkboxstatus bei Änderungen in StuffItem (im Tag) übertragen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void TransferCheckToStuffItem(object sender, TreeViewEventArgs e) + { + StuffItem si = (StuffItem)e.Node.Tag; + + if (si != null) + { + si.Checked = e.Node.Checked; + } + } + + /// <summary> + /// TreeNode aus StuffItem aktualisieren (Rekursiv) + /// </summary> + /// <param name="tn">Node</param> + /// <param name="si">Item</param> + /// <param name="autoCollapse">Automatisch zuklappen</param> + private void UpdateTreeRecursive(TreeNode tn, StuffItem si, Boolean autoCollapse) + { + List<string> delKeys = new List<string>(); + + // StuffItem immer in Tag hängen + tn.Tag = si; + // Mit AutoCollapse erst mal alles zuklappen und nur bei Bedarf wieder öffnen + if (autoCollapse) + { + tn.Collapse(); + } + // Sicherstellen, dass Fehler und Markierungen immer sichtbar sind, + // erlaubte Dubletten nicht immer sichtbar machen + if ((si.HasClones && (!si.IsIgnored || m_Config.IsShowIgnoredClones)) || si.IsNeeded || si.Checked) + { + TreeNode pn = tn.Parent; + while (pn != null) + { + pn.Expand(); + pn = pn.Parent; + } + } + + tn.Text = si.Text; + tn.ImageIndex = tn.SelectedImageIndex = (int)si.Icon; + tn.ToolTipText = si.ToolTip; + + // Checkboxes aus StuffItems setzen + tn.Checked = si.Checked; + + // Offline duch Textfarbe anzeigen + tn.ForeColor = si.IsOnline ? Color.Black : Color.SteelBlue; + + // Alle ChildItems durchlaufen, ggf. hinzufügen und rekursiv aktualisieren + foreach (StuffItem csi in si.ChildItems.ToArray()) + { + // Wenn die Datei gesperrt/vorhanden ist und keine gesperrten/vorhandenen Dateien + // angezeigt werden sollen, dann gar nicht erst hinzufügen + if (!csi.IsVisible) + { + if (tn.Nodes.ContainsKey(csi.Path)) + { + delKeys.Add(csi.Path); + } + continue; + } + + // neuen Node anlegen, wenn noch nicht bekannt + if (!tn.Nodes.ContainsKey(csi.Path)) + { + tn.Nodes.Add(csi.Path, csi.Name); + } + TreeNode ntn = tn.Nodes[csi.Path]; + UpdateTreeRecursive(ntn, csi, autoCollapse); + } + + // Alle TreeNodes löschen, die nicht mehr in den ChildItems sind (Das TreeNode.Tag zeigt auf das StuffItem) + foreach (TreeNode ntn in tn.Nodes) + { + if (!si.ChildItems.Contains((StuffItem)ntn.Tag)) + { + delKeys.Add(((StuffItem)ntn.Tag).Path); + } + } + + // Zweistufiges rauswerfen, damit die Liste nicht beim Durchlaufen manipuliert wird + foreach (string k in delKeys) + { + tn.Nodes.RemoveByKey(k); + } + } + + #endregion + + #region Logging/Messagebox/Status/Progress (auch von Hintergrundthreads nutzbar) + + private delegate void MethodInvokerWithString(string s); + + /// <summary> + /// Logausgabe. Diese Methode kann von Hintergrundthreads gerufen werden + /// </summary> + /// <param name="logText"></param> + public void Log(string logText) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(Log), "*BG* " + logText); + } + else + { + logTextBox.SelectionColor = Color.Black; + LogMessage(logText); + } + } + + /// <summary> + /// Logausgabe in Grün als Highlight. Diese Methode kann von Hintergrundthreads gerufen werden + /// </summary> + /// <param name="log"></param> + public void LogHighlight(string log) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(LogHighlight), "*BG* " + log); + } + else + { + logTextBox.SelectionColor = Color.DarkGreen; + LogMessage(log); + } + } + + /// <summary> + /// Logausgabe in Gelb als Warnung. Diese Methode kann von Hintergrundthreads gerufen werden + /// </summary> + /// <param name="log"></param> + public void LogWarning(string log) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(LogWarning), "*BG* " + log); + } + else + { + logTextBox.SelectionColor = Color.Orange; + LogMessage(log); + } + } + + /// <summary> + /// Logausgabe in Rot als Fehler. Diese Methode kann von Hintergrundthreads gerufen werden + /// </summary> + /// <param name="log"></param> + public void LogError(string log) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(LogError), "*BG* " + log); + } + else + { + logTextBox.SelectionColor = Color.Red; + LogMessage(log); + } + } + + private void LogMessage(string message) + { + if (String.IsNullOrEmpty(message)) + logTextBox.AppendText("\r\n"); + else + logTextBox.AppendText("\r\n" + DateTime.Now.ToString() + " | " + message); + + logTextBox.ScrollToCaret(); + logTextBox.Refresh(); + } + + /// <summary> + /// Statustext ausgeben + /// </summary> + /// <param name="message">Nachricht, die in der Statuszeile ausgegeben werden soll</param> + public void Status(string message) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(Status), message); + } + else + { + stsStatus.Items[0].Text = message; + } + } + + /// <summary> + /// Messagebox ausgeben + /// </summary> + public void Message(string messageText) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(Message), messageText); + } + else + { + MessageBox.Show(messageText, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + /// <summary> + /// Progress anzeigen + /// </summary> + /// <param name="value">|</param> + public void Progress(string value) + { + if (this.InvokeRequired) + { + this.Invoke(new MethodInvokerWithString(Progress), value); + } + else + { + try + { + if (value is String) + { + String[] args = value.Split("|".ToCharArray()); + + if (args[0].Equals("0")) + { + statusProgress.Value = 0; + + // nur Windows 7/Server 2008 R2 + if (IsWin7) + { + tbl.SetProgressState(this.Handle, TBPFLAG.TBPF_NOPROGRESS); + } + + + } + else + { + // Fortschrittsbalken + if (maxProgressMB > 0) + { + // neuen Fortschritt an Hand der Dateigröße berechnen + currentProgressMB += Convert.ToInt32(args[1]); + int progressValue = (int)((currentProgressMB * 100) / maxProgressMB); + statusProgress.Value = progressValue; + statusProgress.ToolTipText = "Fortschritt: " + progressValue + " % (" + currentProgressMB + + " MB von " + maxProgressMB + " MB"; + + // nur Windows 7/Server 2008 R2 + if (IsWin7) + { + tbl.SetProgressValue(this.Handle, (ulong)progressValue, 100); + } + } + } + + // Anzahl Threads + statusThreads.Text = "T: " + args[0]; + } + } + catch + { + // ignore + } + } + } + + #endregion + + #region Drag & Drop + + private void otherDisksTree_ItemDrag(object sender, ItemDragEventArgs e) + { + TreeNode tn = (TreeNode)e.Item; + if (tn != null /*&& ((StuffItem)tn.Tag).IsNeeded*/) + { + DoDragDrop(e.Item, DragDropEffects.Move); + } + } + + private void myDisksTree_DragEnter(object sender, DragEventArgs e) + { + TreeNode trgt = myDisksTree.GetNodeAt(myDisksTree.PointToClient(new Point(e.X, e.Y))); + if (trgt != null && trgt.ImageIndex == (int)TreeNodeImage.Folder) + { + e.Effect = DragDropEffects.Move; + } + else + { + e.Effect = DragDropEffects.None; + } + } + + private void myDisksTree_DragDrop(object sender, DragEventArgs e) + { + // Source und Target aus dem Drag&Drog-Object ermitteln + TreeNode src = (TreeNode)e.Data.GetData(typeof(TreeNode)); + TreeNode trgt = myDisksTree.GetNodeAt(myDisksTree.PointToClient(new Point(e.X, e.Y))); + List<StuffItemPair> copylist = new List<StuffItemPair>(); + copylist.Add(new StuffItemPair()); + copylist[0].Source = ((StuffItem)src.Tag); + copylist[0].Target = ((StuffItem)trgt.Tag); + + Program.RunBackgroundTask(this, "CopyFiles", copylist); + } + + #endregion + + #region Funktionen für die Arbeit mit MainMenü / PopupMenü + + /// <summary> + /// Einhängen eines Menüpunktes mit Event, Bild (opt) und StuffItem + /// </summary> + private void AddToMenuCollection(ToolStripItemCollection menuCollection, string name, string image, EventHandler eventHandler, StuffItem stuffItem) + { + ToolStripItem ts = menuCollection.Add(name); + ts.Click += eventHandler; + ts.Tag = stuffItem; + if (image != null && fileSystemImageList.Images.ContainsKey(image)) + { + ts.Image = fileSystemImageList.Images[image]; + } + } + + /// <summary> + /// StuffItem aus ToolStripItem oder MenuItem extrahieren (damit können Events + /// von beiden Menüs aus verwendet werden) + /// </summary> + /// <param name="menuItem"></param> + /// <returns></returns> + private static StuffItem GetStuffItem(object menuItem) + { + if (menuItem is MenuItem) + { + return (StuffItem)((MenuItem)menuItem).Tag; + } + + if (menuItem is ToolStripItem) + { + return (StuffItem)((ToolStripItem)menuItem).Tag; + } + + return null; + } + + /// <summary> + /// Menü für eigene Platten aufbauen (Hauptmenü und Popup-Menü) + /// </summary> + /// <param name="menuCollection"></param> + private void AddEigenePlattenMenu(ToolStripItemCollection menuCollection) + { + // Konfiguration öffnen + AddToMenuCollection(menuCollection, "Platten hinzufügen oder entfernen...", "Hinzufuegen.png", new EventHandler(konfigurationToolStripMenuItem_Click), m_MyDisks); + // Menüpunkt für Aktualisieren links + AddToMenuCollection(menuCollection, "Meine Platten aktualisieren", "Aktualisieren.png", new EventHandler(eigenePlattenAktualisierenToolStripMenuItem_Click), m_MyDisks); + // Online / Offline Wechsel + AddToMenuCollection( menuCollection, "Meine Platten " + ( m_MyDisks.IsOnline ? "offline" : "online" ) + " schalten", m_MyDisks.IsOnline ? "DateiWeiss.png" : "DateiGruen.png", new EventHandler( ToggleOnline ), m_MyDisks ); + // Separator + menuCollection.Add("-"); + // Markieren aller Dateien ab Root, die gelöscht werden können + AddToMenuCollection(menuCollection, "Dubletten zum Löschen markieren (eine bleibt)", "Markieren.png", new EventHandler(ContextMarkDoubleEntries), m_MyDisks); + // Allgemeines Menü für alle Platten dazu + AddAllePlattenMenu( menuCollection, m_MyDisks ); + // Löschen aller links makierten Dateien + AddToMenuCollection(menuCollection, "Alle markierten Dateien sperren und löschen", "DateiExcludedAndDeleted.png", new EventHandler(ContextExcludeAndDeleteAllMarkedFiles), m_MyDisks); + AddToMenuCollection(menuCollection, "Alle markierten Dateien löschen", "DateiLoeschen.png", new EventHandler(ContextDeleteAllMarkedFiles), m_MyDisks); + } + + /// <summary> + /// Menü für fremde Platten aufbauen (Hauptmenü und Popup-Menü) + /// </summary> + /// <param name="menuCollection"></param> + private void AddFremdePlattenMenu(ToolStripItemCollection menuCollection) + { + // Konfiguration öffnen + AddToMenuCollection(menuCollection, "Platten hinzufügen oder entfernen...", "Hinzufuegen.png", new EventHandler(konfigurationToolStripMenuItem_Click), Program.MainWindow.m_OtherDisks); + // AddToMenuCollection(menuCollection, "Fremde Platte hinzufügen...", "Hinzufuegen.png", new EventHandler(FremdePlatteAuswaehlenClick), Program.MainWindow.m_OtherDisks); + // Menüpunkt für Aktualisieren rechts + AddToMenuCollection(menuCollection, "Fremde Platten aktualisieren", "Aktualisieren.png", new EventHandler(fremdePlatteAktualisierenToolStripMenuItem_Click), Program.MainWindow.m_OtherDisks); + // Online / Offline Wechsel + AddToMenuCollection(menuCollection, "Fremde Platten " + (Program.MainWindow.m_OtherDisks.IsOnline ? "offline" : "online") + " schalten", Program.MainWindow.m_OtherDisks.IsOnline ? "DateiWeiss.png" : "DateiGruen.png", new EventHandler(ToggleOnline), Program.MainWindow.m_OtherDisks); + // Separator + menuCollection.Add("-"); + // Markieren aller zu saugenden Dateien ab Root + AddToMenuCollection(menuCollection, "Alle fehlenden Dateien markieren", "Markieren.png", new EventHandler(ContextMarkMissingFiles), Program.MainWindow.m_OtherDisks); + // Allgemeines Menü für alle Platten dazu + AddAllePlattenMenu(menuCollection, Program.MainWindow.m_OtherDisks); + } + + /// <summary> + /// Menü für beide Platten, wird von AddFremde/EigenenPlattenMenu verwendet + /// </summary> + /// <param name="menuCollection"></param> + /// <param name="stuffItem"></param> + private void AddAllePlattenMenu(ToolStripItemCollection menuCollection, StuffItem stuffItem) + { + // Markieren aller Dateien ab Root + AddToMenuCollection(menuCollection, "Alle Dateien markieren", "Markieren.png", new EventHandler(ContextMark), stuffItem); + // Markierung mit Suchfilter setzen + AddToMenuCollection(menuCollection, "Dateien mit Suchfilter markieren...", "Markieren.png", new EventHandler(ContextMarkByFilter), stuffItem); + // Markierung entfernen aller Dateien ab Root + AddToMenuCollection(menuCollection, "Alle Markierungen entfernen", "Demarkieren.png", new EventHandler(ContextRemoveMark), stuffItem); + // Separator + menuCollection.Add("-"); + // Unbenötigte Teile zuklappen + AddToMenuCollection(menuCollection, "Alle Ordner ohne Markierungen/Hinweise zuklappen", "Zuklappen.png", new EventHandler(ContextCollapse), stuffItem); + // Separator + menuCollection.Add("-"); + // Markieren/Demarkieren + AddToMenuCollection(menuCollection, "Alle markierten Dateien entsperren", "DateiFrischGesaugt.png", new EventHandler(ContextIncludeMarkers), stuffItem); + AddToMenuCollection(menuCollection, "Alle markierten Dateien sperren", "DateiExcluded.png", new EventHandler(ContextExcludeMarkers), stuffItem); + } + + /// <summary> + /// Kontextmenu aufbauen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void tree_MouseUp( object sender, MouseEventArgs e ) + { + TreeView tv = ( TreeView )sender; + if ( e.Button != MouseButtons.Right ) + { + return; + } + + Point clickPoint = new Point( e.X, e.Y ); + TreeNode clickNode = tv.GetNodeAt( clickPoint ); + if ( clickNode == null ) + { + return; + } + + StuffItem clickItem = ( StuffItem )clickNode.Tag; + bool isRoot = clickItem.Equals( m_MyDisks ) || clickItem.Equals( Program.MainWindow.m_OtherDisks ); + // Convert from Tree coordinates to Screen coordinates + Point ScreenPoint = tv.PointToScreen( clickPoint ); + // Convert from Screen coordinates to Form coordinates + Point FormPoint = this.PointToClient( ScreenPoint ); + + // Show context menu + ContextMenuStrip contextmenu = new ContextMenuStrip(); + contextmenu.Items.Clear(); + // Fremde Platte entfernen + + // Menüs für die + if ( isRoot ) + { + if ( !clickItem.IsOnForeignDisk ) + { + AddEigenePlattenMenu( contextmenu.Items ); + } + else + { + AddFremdePlattenMenu( contextmenu.Items ); + } + } + else + { + if ( !clickItem.IsFile ) + { + AddToMenuCollection( contextmenu.Items, "Ordner " + clickItem.Path + " aktualisieren" + ( clickItem.IsOnline ? "" : " (offline)" ), "Aktualisieren.png", new EventHandler( UpdateFolderClick ), clickItem ); + AddToMenuCollection( contextmenu.Items, "Ordner " + clickItem.Path + ( clickItem.IsOnline ? " offline" : " online" ) + " schalten", clickItem.IsOnline ? "DateiWeiss.png" : "DateiGruen.png", new EventHandler( ToggleOnline ), clickItem ); + contextmenu.Items.Add( "-" ); + } + // Menüpunkt für Ansehen + if ( !clickItem.HasReadError ) + { + AddToMenuCollection( contextmenu.Items, "Öffnen", "Oeffnen.png", new EventHandler( ContextExecute ), clickItem ); + // Öffnen mit Anbieten bei Dateien + if ( clickItem.IsFile ) + { + AddToMenuCollection( contextmenu.Items, "Öffnen mit...", "Oeffnen.png", new EventHandler( ContextExecuteWith ), clickItem ); + } + } + + // Ordner mit Unterordnern + if ( !clickItem.IsFile && clickItem.ChildItems.Count > 0 ) + { + contextmenu.Items.Add( "-" ); + // Markieren aller Dateien ab Folder + AddToMenuCollection( contextmenu.Items, "Alle Dateien unterhalb " + clickItem.Path + " markieren", "Markieren.png", new EventHandler( ContextMark ), clickItem ); + // Markieren aller Dateien ab Folder mit Filter + AddToMenuCollection( contextmenu.Items, "Dateien unterhalb " + clickItem.Path + " mit Suchfilter markieren...", "Markieren.png", new EventHandler( ContextMarkByFilter ), clickItem ); + // Markieren aller zu saugenden Dateien ab Folder + if ( clickItem.IsOnForeignDisk ) + { + AddToMenuCollection( contextmenu.Items, "Alle fehlenden Dateien unterhalb " + clickItem.Path + " markieren", "Markieren.png", new EventHandler( ContextMarkMissingFiles ), clickItem ); + } + // Markierung entfernen aller Dateien ab Folder + AddToMenuCollection( contextmenu.Items, "Alle Markierungen unterhalb " + clickItem.Path + " entfernen", "Demarkieren.png", new EventHandler( ContextRemoveMark ), clickItem ); + } + + if ( !clickItem.IsOnForeignDisk && !clickItem.IsFile && !clickItem.HasReadError ) + { + contextmenu.Items.Add( "-" ); + // Kopieren aller rechts markierten Dateien in einen Folder (flat) + AddToMenuCollection( contextmenu.Items, "Alle fremden selektierten Dateien direkt in diesen Ordner kopieren (flat)", "DateiSaugen.png", new EventHandler( ContextCopyAllClick ), clickItem ); + // Kopieren aller rechts markierten Dateien in einen Folder (hierarchisch) + AddToMenuCollection( contextmenu.Items, "Alle fremden selektierten Dateien mit Ordnerstruktur in diesen Ordner kopieren", "DateiSaugen.png", new EventHandler( ContextCopyAllWithFoldersClick ), clickItem ); + // Ordner anlegen + AddToMenuCollection( contextmenu.Items, "Neuen Ordner unterhalb " + clickItem.Path + " anlegen", "Ordner.png", new EventHandler( ContextNewFolder ), clickItem ); + + } + + if ( clickItem.IsFile && clickItem.HasClones ) + { + contextmenu.Items.Add( "-" ); + + List<StuffItem> clones = Program.MainWindow.m_MyDisks.GetItemClones( clickItem ); + for ( int i = 0 ; i < clones.Count ; i++ ) + { + if ( !clones[ i ].Equals( clickItem ) ) + { + AddToMenuCollection( contextmenu.Items, "Öffnen Dublette " + clones[ i ].Path, "Oeffnen.png", new EventHandler( ContextExecute ), clones[ i ] ); + } + } + + AddToMenuCollection( contextmenu.Items, "Markieren aller Dubletten dieser Datei", "Markieren.png", new EventHandler( ContextMarkClones ), clickItem ); + // Dubletten ignorieren ja/nein + if ( !clickItem.IsIgnored ) + { + AddToMenuCollection( contextmenu.Items, "Dubletten dieser Datei erlauben", "", new EventHandler( ContextIgnore ), clickItem ); + } + else + { + AddToMenuCollection( contextmenu.Items, "Dubletten dieser Datei wieder markieren", "", new EventHandler( ContextUnIgnore ), clickItem ); + } + + // Für Dubletten Menüs anbieten (auf rot) + for ( int i = 0 ; i < clones.Count ; i++ ) + { + if ( !clones[ i ].Equals( clickItem ) ) + { + AddToMenuCollection( contextmenu.Items, "Löschen Dublette " + clones[ i ].Path, "DateiLoeschen.png", new EventHandler( ContextDeleteFile ), clones[ i ] ); + } + } + + } + // Datei in die Sperrliste ein-/austragen + if ( clickItem.IsFile ) + { + // Linie nach Markieren + contextmenu.Items.Add( "-" ); + if ( !clickItem.IsExcluded ) + { + AddToMenuCollection( contextmenu.Items, "Sperren der Datei", "DateiExcluded.png", new EventHandler( ContextExclude ), clickItem ); + } + else + { + AddToMenuCollection( contextmenu.Items, "Entsperren der Datei", "DateiFrischGesaugt.png", new EventHandler( ContextInclude ), clickItem ); + } + // Sperren und zugleich löschen + if ( !clickItem.IsExcluded && !clickItem.IsOnForeignDisk ) + { + AddToMenuCollection( contextmenu.Items, "Sperren und Löschen der Datei", "DateiExcludedAndDeleted.png", new EventHandler( ContextExcludeAndDelete ), clickItem ); + } + // Löschen einer Einzeldatei, nur links + if ( !clickItem.IsOnForeignDisk ) + { + AddToMenuCollection( contextmenu.Items, "Löschen der Datei", "DateiLoeschen.png", new EventHandler( ContextDeleteFile ), clickItem ); + } + } + // Löschen eines (leeren) Ordners + if ( !clickItem.HasReadError && !clickItem.IsOnForeignDisk && !clickItem.IsFile && clickItem.ChildItems.Count == 0 ) + { + AddToMenuCollection( contextmenu.Items, "Ordner löschen", "OrdnerLoeschen.png", new EventHandler( ContextDeleteFolder ), clickItem ); + } + // Sperren/Entsperren multi + if ( !clickItem.IsFile && clickItem.ChildItems.Count > 0 ) + { + // Linie nach Markieren + contextmenu.Items.Add( "-" ); + AddToMenuCollection( contextmenu.Items, "Alle markierten Dateien entsperren", "DateiFrischGesaugt.png", new EventHandler( ContextIncludeMarkers ), clickItem ); + AddToMenuCollection( contextmenu.Items, "Alle markierten Dateien sperren", "DateiExcluded.png", new EventHandler( ContextExcludeMarkers ), clickItem ); + AddToMenuCollection( contextmenu.Items, "Alle markierten Dateien sperren und löschen", "DateiExcludedAndDeleted.png", new EventHandler( ContextExcludeAndDeleteAllMarkedFiles ), clickItem ); + // Löschen aller links markierten Dateien + if ( !clickItem.IsOnForeignDisk ) + { + AddToMenuCollection( contextmenu.Items, "Alle markierten Dateien unterhalb " + clickItem.Path + " löschen", "DateiLoeschen.png", new EventHandler( ContextDeleteAllMarkedFiles ), clickItem ); + } + } + } + contextmenu.Show( this, FormPoint ); + } + + #endregion + + #region Popup Menü Aktionen + + /// <summary> + /// Teilbaum von Offline auf Online und umgekehrt setzen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ToggleOnline(object sender, EventArgs e) + { + // StuffItem ermitteln + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + // Onlinestatus umsetzen + if (si.IsOnline) + { + Log("Setze Offline: " + si.Path); + si.IsOnline = false; + } + else + { + Log("Setze Online: " + si.Path); + si.IsOnline = true; + } + + // Menüs bauen sich dabei um! + MainMenuFremdePlatten.DropDownItems.Clear(); + AddFremdePlattenMenu(MainMenuFremdePlatten.DropDownItems); + MainMenuEigenePlatten.DropDownItems.Clear(); + AddEigenePlattenMenu(MainMenuEigenePlatten.DropDownItems); + + UpdateTrees(); + } + + /// <summary> + /// Eine Datei excluden + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExclude(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + // wenn kein StuffItem ausgewählt wurde, dann tun wir hier nix + if (si == null) + { + return; + } + + // Datei sperren + si.Exclude(); + Log("Sperre Datei: " + si.Path); + + UpdateTreeNodeIcon(si); + } + catch (Exception e2) + { + LogError("Fehler beim Sperren: " + e2.Message); + } + } + + /// <summary> + /// Eine Datei excluden und löschen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExcludeAndDelete( object sender, EventArgs e ) + { + try + { + StuffItem si = GetStuffItem( sender ); + if ( si == null ) + { + return; + } + DialogResult res = MessageBox.Show( "Datei " + si.Name + " wirklich sperren und löschen?", + "Vorsicht, sie trennen sich von Material!", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation ); + if ( res == DialogResult.OK ) + { + Log( "Sperre und lösche Datei: " + si.Path ); + si.Exclude(); + File.Delete( si.Path ); + + RemoveStuffItemFromMyDisksTree( si ); + } + } + catch ( Exception e2 ) + { + LogError( "Fehler beim Sperren und Löschen: " + e2.Message ); + } + } + + /// <summary> + /// Eine Datei includen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextInclude(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Log("Entsperre Datei: " + si.Path); + si.Include(); + + UpdateTreeNodeIcon(si); + } + catch (Exception ex) + { + LogError("Fehler beim Entsperren: " + ex.Message); + } + } + + + /// <summary> + /// Eine Datei ignorieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextIgnore(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Log("Erlaube Dubletten der Datei: " + si.Path); + si.Ignore(); + + // Icon der Datei und möglicher Clones anpassen + UpdateTreeNodeIcon(si); + } + catch (Exception ex) + { + LogError("Fehler beim Erlauben: " + ex.Message); + } + } + + /// <summary> + /// Eine Datei un-ignorieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextUnIgnore(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Log("Markiere Dubletten der Datei: " + si.Path); + si.UnIgnore(); + + // Icon der Datei und möglicher Clones anpassen + UpdateTreeNodeIcon( si ); + } + catch (Exception ex) + { + LogError("Fehler beim Markieren: " + ex.Message); + } + } + + /// <summary> + /// Eine Datei ausführen durch Menüeintrag + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExecute(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if ( si == null ) + { + return; + } + if ( si.IsFile ) + { + Status( "Starte Datei: " + si.Path ); + } + else + { + Status( "Öffne Verzeichnis: " + si.Path ); + } + + try + { + Process.Start(si.Path); + } + catch + { + ContextExecuteWith(sender, e); + } + } + catch (Exception e2) + { + LogError("Fehler beim Ausführen: " + e2.Message); + } + } + + /// <summary> + /// Eine Datei ausführen mit Auswahl durch Programm durch Menüeintrag + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExecuteWith(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if ( si == null ) + { + return; + } + if ( si.IsFile ) + { + Status( "Starte Datei: " + si.Path ); + } + else + { + Status( "Öffne Verzeichnis: " + si.Path ); + } + + using (Process p = new Process()) + { + ProcessStartInfo pi = new ProcessStartInfo("rundll32.exe"); + pi.UseShellExecute = false; + pi.RedirectStandardOutput = true; + pi.Arguments = "shell32.dll,OpenAs_RunDLL " + si.Path; + p.StartInfo = pi; + p.Start(); + } + } + catch (Exception e2) + { + LogError("Fehler beim Ausführen: " + e2.Message); + } + } + + /// <summary> + /// Eine Datei löschen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextDeleteFile(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + if (MessageBox.Show("Datei " + si.Name + " wirklich löschen?", "Vorsicht, sie trennen sich von Material!", + MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK) + { + // Datei löschen + Log("Lösche Datei: " + si.Path); + File.Delete(si.Path); + + RemoveStuffItemFromMyDisksTree( si ); + } + } + catch (Exception e2) + { + LogError("Fehler beim Löschen: " + e2.Message); + } + } + + /// <summary> + /// Eine leeren Ordner löschen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextDeleteFolder(object sender, EventArgs e) + { + try + { + StuffItem si = GetStuffItem(sender); + if ( si == null ) + { + return; + } + + DialogResult res = System.Windows.Forms.MessageBox.Show("Ordner " + si.Name + " wirklich löschen?", "Leeren Ordner löschen", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); + if (res == DialogResult.OK) + { + Log("Lösche Ordner: " + si.Path); + Directory.Delete(si.Path); + + RemoveStuffItemFromMyDisksTree( si ); + } + } + catch (Exception e2) + { + LogError("Fehler beim Löschen: " + e2.Message); + } + } + /// <summary> + /// Alle markierten unterhalb eines Ordners löschen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextDeleteAllMarkedFiles(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null || si.IsFile || si.IsOnForeignDisk) + { + return; + } + + string meld = ""; + if (si.Parent == null) + { + meld = "Alle markierten Dateien wirklich löschen?"; + } + else + { + meld = "Alle markierten Dateien unterhalb " + si.Path + " wirklich löschen?"; + } + + DialogResult res = MessageBox.Show(meld, "Vorsicht, sie trennen sich von Material!", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); + if (res == DialogResult.OK) + { + DeleteAllMarkedFilesRecursive(si); + } + } + + /// <summary> + /// Alle markierten unterhalb eines Ordners sperren und löschen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExcludeAndDeleteAllMarkedFiles(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null || si.IsFile ||si.IsOnForeignDisk) + { + return; + } + + string meld = ""; + if (si.Parent == null) + { + meld = "Alle markierten Dateien wirklich sperren und löschen?"; + } + else + { + meld = "Alle markierten Dateien unterhalb " + si.Path + " wirklich sperren und löschen?"; + } + + if (MessageBox.Show(meld, "Vorsicht, sie trennen sich von Material!", + MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) + { + Recursive_ExcludeMarkers(si, true); + DeleteAllMarkedFilesRecursive(si); + } + } + + /// <summary> + /// Hilfsfunktion um alle markierten Dateien rekrusiv zu löschen + /// </summary> + /// <param name="si"></param> + private void DeleteAllMarkedFilesRecursive(StuffItem si) + { + try + { + if ( si.IsFile ) + { + if ( !si.Checked ) + { + return; + } + // Datei löschen + Log( "Datei wird gelöscht: " + si.Path ); + File.Delete( si.Path ); + + // aus der StuffItem-Liste löschen + RemoveStuffItemFromMyDisksTree( si ); + } + else + { + // Rückwärts durchlaufen wegen Löschen + for ( int j = si.ChildItems.Count - 1 ; j >= 0 ; j-- ) + { + StuffItem csi = si.ChildItems[ j ]; + DeleteAllMarkedFilesRecursive( csi ); + } + + // Leeres Verzeichnis löschen + if ( si.ChildItems.Count == 0 && si.Checked ) + { + Log( "Leeres Verzeichnis wird gelöscht: " + si.Path ); + Directory.Delete( si.Path ); + + RemoveStuffItemFromMyDisksTree( si ); + } + } + } + catch (Exception e2) + { + LogError("Fehler beim Löschen: " + e2.Message); + } + } + + private void RemoveStuffItemFromMyDisksTree( StuffItem si ) + { + // Verweis vom Elternteil entfernen + si.Parent.ChildItems.Remove( si ); + + // Datei aus dem Tree entfernen + myDisksTree.FindSingleNode(si.Path).Remove(); + + // Einträge auch aus der MyDisksByHash-Liste entfernen + m_MyDisks.RemoveStuffItemFromHashes( si ); + + // Anzeige aktualisieren + UpdateTreeNodeIcon( si ); + } + + /// <summary> + /// Alle markierten unterhalb eines Ordners sperren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextExcludeMarkers(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null || si.IsFile) + { + return; + } + Recursive_ExcludeMarkers(si, true); + + // Markierungen entfernen, falls gewünscht + if (m_Config.IsRemoveMarks) + { + // Markierungen im aktuellen Tree entfernen + ContextRemoveMark(sender, e); + } + } + + /// <summary> + /// Alle markierten unterhalb eines Ordners entsperren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextIncludeMarkers(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null || si.IsFile) + { + return; + } + Recursive_ExcludeMarkers(si, false); + + // Markierungen entfernen, falls gewünscht + if (m_Config.IsRemoveMarks) + { + // Markierungen im aktuellen Tree entfernen + ContextRemoveMark(sender, e); + } + } + + /// <summary> + /// Hilfsfunktion um alle markierten Dateien rekursiv zu sperren + /// </summary> + /// <param name="si"></param> + /// <param name="exclude">true für Dateien sperren, false wenn die Dateien entsperren</param> + private void Recursive_ExcludeMarkers( StuffItem si, bool exclude ) + { + try + { + if ( si.IsFile ) + { + if ( si.Checked ) + { + if ( exclude ) + { + Log( "Datei gesperrt: " + si.Path ); + si.Exclude(); + } + else + { + Log( "Datei entsperrt: " + si.Path ); + si.Include(); + } + + // TreeNodeIcon aktualisieren + UpdateTreeNodeIcon( si ); + } + } + else + { + foreach ( StuffItem csi in si.ChildItems ) + { + Recursive_ExcludeMarkers( csi, exclude ); + } + } + } + catch ( Exception e2 ) + { + LogError( "Fehler beim Sperren/Entsperren: " + e2.Message ); + } + } + + /// <summary> + /// Alle markierten Items in Kopierliste zusammenfassen und im Hintergrund kopieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextCopyAllClick(object sender, EventArgs e) + { + StuffItem trgt = GetStuffItem(sender); + if (trgt == null || trgt.IsFile) + return; + List<StuffItemPair> copylist = new List<StuffItemPair>(); + ContextCopyAllClickAddChecked(copylist, otherDisksTree.Nodes[0]); + + // Markierungen entfernen, falls gewünscht + // beim Kopieren schon jetzt, denn entfällt das manuelle Demarkieren + if (m_Config.IsRemoveMarks) + { + // Markierung immer im Tree "Fremde Platten" entfernen + ContextRemoveMark(otherDisksTree.Nodes[0].Tag, e); + } + + foreach (StuffItemPair pair in copylist) + { + pair.Target = trgt; + } + // Kopieraktion starten + Program.RunBackgroundTask(this, "CopyFiles", copylist); + } + + /// <summary> + /// Alle markierten Items in Kopierliste zusammenfassen und mit Pfad kopieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + void ContextCopyAllWithFoldersClick(object sender, EventArgs e) + { + StuffItem trgt = GetStuffItem(sender); + if (trgt == null || trgt.IsFile) + return; + + List<StuffItemPair> copylist = new List<StuffItemPair>(); + ContextCopyAllClickAddChecked(copylist, otherDisksTree.Nodes[0]); + foreach (StuffItemPair pair in copylist) + { + FileInfo fi = new FileInfo(pair.Source.Path); + string subpath = fi.DirectoryName.Replace(":", "").Replace("\\\\", ""); + pair.Target = new StuffItem(); + pair.Target.Path = trgt.Path + "\\" + subpath; + } + + // Markierungen entfernen, falls gewünscht + // beim Kopieren schon jetzt, denn entfällt das manuelle Demarkieren + // beim Kopieren immer im Tree "Fremde Platten" + if (m_Config.IsRemoveMarks) + { + ContextRemoveMark(otherDisksTree.Nodes[0].Tag, e); + } + + // Dateien kopieren + Program.RunBackgroundTask(this, "CopyFiles", copylist); + } + + /// <summary> + /// Hilfsfunktion zum rekursiven Kopieren (ohne Erhalt der Hierarchie) + /// </summary> + /// <param name="copylist"></param> + /// <param name="node"></param> + void ContextCopyAllClickAddChecked(List<StuffItemPair> copylist, TreeNode node) + { + if (node.Checked) + { + StuffItem item = (StuffItem)node.Tag; + if (item != null && item.IsFile) + { + copylist.Add(new StuffItemPair()); + copylist[copylist.Count - 1].Source = item; + } + } + foreach (TreeNode n in node.Nodes) + { + ContextCopyAllClickAddChecked(copylist, n); + } + } + + /// <summary> + /// Aktualisiert das Icon eines bestimmten StuffItems in den TreeViews + /// </summary> + /// <param name="si">StuffItem, welches es zu aktualisieren gilt</param> + void UpdateTreeNodeIcon(StuffItem si) + { + TreeView currentTree = si.IsOnForeignDisk ? otherDisksTree : myDisksTree; + TreeNode tn = currentTree.FindSingleNode( si.Path ); + if ( tn != null ) + { + tn.ImageIndex = tn.SelectedImageIndex = ( int )si.Icon; + } + + // lokale Dateien eines entfernten StuffItems ebenfalls anpassen + if ( si.IsOnForeignDisk ) + { + foreach ( String localpath in si.GetLocalFiles ) + { + tn = myDisksTree.FindSingleNode( localpath ); + tn.ImageIndex = tn.SelectedImageIndex = ( int )( ( StuffItem )tn.Tag ).Icon; + } + } + else + { + // ggf. den anderen Tree auch anpassen (wg. Exludes) + foreach ( String remotepath in si.GetRemoteFiles ) + { + tn = otherDisksTree.FindSingleNode( remotepath ); + tn.ImageIndex = tn.SelectedImageIndex = ( int )( ( StuffItem )tn.Tag ).Icon; + } + // TODO: bei Excludes und aktiver Option zum Ausblenden von Items, dann muss das Ding ganz raus + } + } + + #endregion + + #region Markierungen setzen und entfernen (Kontextmenu) + + /// <summary> + /// Alle Zweige ohne Markierung zuklappen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextCollapse(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + if (si.IsOnForeignDisk) + { + CollapseOtherDisks(); + } + else + { + CollapseMyDisks(); + } + } + + /// <summary> + /// Alle markieren, die zu saugen sind + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextMarkMissingFiles(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Recursive_UpdateMark( si, true ); + Recursive_MarkMissingFiles(si); + } + + /// <summary> + /// Alle Dateien die ein Clone einer anderen sind markieren + /// </summary> + private void ContextMarkClones(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + si.Checked = false; + foreach ( StuffItem clone in Program.MainWindow.m_MyDisks.GetItemClones( si ) ) + { + TreeNode node = myDisksTree.FindSingleNode( clone.Path ); + node.Checked = true; + node.Expand(); + } + } + + /// <summary> + /// Alle Dateien unterhalb eines Knotens markieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextMark(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Recursive_UpdateMark( si, true ); + } + + /// <summary> + /// Alle Markierungen entfernen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextRemoveMark(object sender, EventArgs e) + { + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + Recursive_UpdateMark( si, false ); + } + + /// <summary> + /// Alle markieren, die zu gelöscht werden können, weil doppelt + /// Das klappt nur auf dem Root-Node, dehalb nur da anbieten + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextMarkDoubleEntries(object sender, EventArgs e) + { + StuffItem se = GetStuffItem(sender); + if (se == null) + { + return; + } + Recursive_UpdateMark( se, false ); + Recursive_MarkDoubleEntries(se); + } + + + /// <summary> + /// Alle Dateien unterhalb eines Knotens mit einem manuellen Filterstring markieren + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextMarkByFilter(object sender, EventArgs e) + { + // Ohne Startitem gehts nicht + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + // Dialog aufbauen / abfragen + using (LanTool.FilterDialog filterDlg = new LanTool.FilterDialog()) + { + filterDlg.Text = "Filtern unterhalb \"" + si.Path + "\""; + + if (filterDlg.ShowDialog() == DialogResult.OK) + { + string filter = filterDlg.Expression; + // RegExp-Sonderzeichen per backslash quoten + string[] quote = new string[] { "\\", ".", "(", ")", "[", "]" }; + foreach (string q in quote) + filter = filter.Replace(q, "\\" + q); + + // Dos Wildcards durch RegExp ersetzen + filter = filter.Replace("*", ".*").Replace("?", "."); + + // Losfiltern ab Item + Recursive_MarkByFilter(si, filter); + } + } + } + + /// <summary> + /// Rekursion zum Markieren mit einem Filterstring + /// </summary> + /// <param name="si">aktuellles StuffItem</param> + /// <param name="filter">String-Filter</param> + private void Recursive_MarkByFilter(StuffItem si, string filter) + { + TreeView currenttree = si.IsOnForeignDisk ? otherDisksTree : myDisksTree; + + foreach (StuffItem csi in si.ChildItems) + { + // wenn der Filter zutrifft, dann markieren + if (Regex.IsMatch(csi.Name, filter, RegexOptions.IgnoreCase)) + { + currenttree.FindSingleNode(csi.Path).Checked = true; + } + // wenn Ordner, dann weiter rekursiv durch + if (!csi.IsFile) + { + Recursive_MarkByFilter(csi, filter); + } + } + } + + /// <summary> + /// Rekursion zum Markieren fürs Saugen + /// </summary> + private void Recursive_MarkMissingFiles(StuffItem si) + { + TreeView currenttree = si.IsOnForeignDisk ? otherDisksTree : myDisksTree; + + // alle TreeNodes finden + foreach ( StuffItem csi in si.ChildItems ) + { + TreeNode node = currenttree.FindSingleNode( csi.Path ); + node.Checked = csi.IsNeeded; + if ( csi.IsNeeded ) + { + node.Expand(); + } + + if ( !csi.IsFile ) + { + Recursive_MarkMissingFiles( csi ); + } + } + } + + /// <summary> + /// Rekursiv alle untergeordneten Nodes de-/markieren + /// </summary> + private void Recursive_UpdateMark( StuffItem si, Boolean setMark ) + { + TreeView currenttree = si.IsOnForeignDisk ? otherDisksTree : myDisksTree; + + // alle TreeNodes finden + TreeNode node = currenttree.FindSingleNode( si.Path ); + node.Checked = setMark; + if ( setMark ) + { + node.Expand(); + } + + foreach ( StuffItem csi in si.ChildItems ) + { + Recursive_UpdateMark( csi, setMark ); + } + } + + /// <summary> + /// Die nachfolgenden Duplikate markieren, d.h. das erste bleibt erhalten + /// Das kann nur klappen wenn auf RootNode begonnen wird und vorher alle Markierungen + /// zurückgesetzt werden! + /// </summary> + /// <param name="si"></param> + private void Recursive_MarkDoubleEntries(StuffItem si) + { + // nur bei den eigenen Platten + if (!si.IsOnForeignDisk) + { + // nur bei Dateien + if (si.IsFile) + { + if (!si.Checked && si.HasClones) + { + foreach ( StuffItem csi in Program.MainWindow.m_MyDisks.GetItemClones( si ) ) + { + TreeNode node = myDisksTree.FindSingleNode( csi.Path ); + + node.Checked = true; + node.Expand(); + + } + } + } + else + { + foreach (StuffItem csi in si.ChildItems) + { + Recursive_MarkDoubleEntries(csi); + } + } + } + } + + #endregion + + #region Suchen + + /// <summary> + /// Suche + /// </summary> + private bool ContextSearchRecursive(StuffItem si, string filter) + { + foreach (StuffItem se2 in si.ChildItems) + { + if (Regex.IsMatch(se2.Path, filter, RegexOptions.IgnoreCase) && !itemsAlreadyFound.Contains(se2.Path)) + { + // Item zur Liste "bereits gefunden" hinzufügen + itemsAlreadyFound.Add(se2.Path); + + // gesuchtes Item gefunden, dann + TreeNode fn = FindNode(lastUsedView.Nodes[0].Nodes, se2.Path); + if (fn == null) + { + return false; + } + else + { + lastUsedView.SelectedNode = fn; + return true; + } + } + else + { + // keine Datei, dann die childs untersuchen + if (!se2.IsFile) + if (ContextSearchRecursive(se2, filter)) + return true; + } + } + + return false; + } + private TreeNode FindNode(TreeNodeCollection tncoll, String strText) + { + TreeNode tnFound = null; + foreach (TreeNode tnCurr in tncoll) + { + if (String.Equals(tnCurr.Name, strText, StringComparison.CurrentCultureIgnoreCase)) + { + return tnCurr; + } + if (tnCurr.Nodes.Count > 0) + tnFound = FindNode(tnCurr.Nodes, strText); + if (tnFound != null) + { + return tnFound; + } + } + return null; + } + + /// <summary> + /// Im Suchfeld wurde eine Taste betätigt + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void searchField_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + // wenn es um eine neue Suche handelt, dann die bereits gefunden Liste zurücksetzen + if (!String.Equals(lastSearchString, searchField.Text, StringComparison.CurrentCultureIgnoreCase)) + { + itemsAlreadyFound.Clear(); + + lastSearchString = searchField.Text; + } + + String filter = searchField.Text; + + // wenn kein Suchtext angegeben wurde, dann wird auch nichts gesucht + if (!String.IsNullOrEmpty(filter)) + { + + // RegExp-Sonderzeichen per backslash quoten + string[] quote = new string[] { "\\", ".", "(", ")", "[", "]" }; + foreach (string q in quote) + filter = filter.Replace(q, "\\" + q); + + // Dos Wildcards durch RegExp ersetzen + filter = filter.Replace("*", ".*").Replace("?", "."); + + StuffItem si = (StuffItem)lastUsedView.Nodes[0].Tag; + + // Suche beim aktuellen Item starten + if (!ContextSearchRecursive(si, filter)) + { + Status("Keine (weiteren) Treffer."); + // Bereits gefunden Liste zurücksetzen + itemsAlreadyFound.Clear(); + } + + // damit das ganze auch sichtbar wird, den TreeView fokusieren + lastUsedView.Focus(); + } + else + { + searchField.Focus(); + } + } + } + + /// <summary> + /// Suchen-Button im Menü + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void suchenToolStripMenuItem_Click(object sender, EventArgs e) + { + // gleiche Funktion wie Enter im Suchfeld + searchField_KeyUp(sender, new KeyEventArgs(Keys.Return)); + } + + #endregion + + /// <summary> + /// Neuen Ordner anlegen + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void ContextNewFolder(object sender, EventArgs e) + { + // Ohne Startitem gehts nicht + StuffItem si = GetStuffItem(sender); + if (si == null) + { + return; + } + + // Dialog aufbauen / abfragen + using (NewFolderDialog folderDlg = new NewFolderDialog()) + { + folderDlg.Text = "Neuen Ordner anlegen unterhalb \"" + si.Path + "\":"; + if (folderDlg.ShowDialog() == DialogResult.OK) + { + string folder = folderDlg.NewFolderName; + // Sonderzeichen durch _ ersetzen + foreach ( char q in Path.GetInvalidPathChars() ) + { + folder = folder.Replace( q, '_' ); + } + // Losfiltern ab Item + Directory.CreateDirectory(Path.Combine(si.Path, folder)); + + si.AddOrGetChildItemByPath( Path.Combine( si.Path, folder ) ); + + UpdateTreeRecursive( myDisksTree.Nodes[si.Path], si, false); + } + } + } + + #region Speichern und laden einer Fileliste als Ersatz für dem MyDisk-Filesystem Scan + + /// <summary> + /// Verzeichnisse exportieren (werden durch realen Scan aufgebaut) + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void verzeichnisFürMeinePlattenExportierenToolStripMenuItem_Click(object sender, EventArgs e) + { + using (SaveFileDialog fd = new SaveFileDialog()) + { + fd.Filter = "LanTool-Verzeichnis-Export (*.files)|*.files|Textdateien (*.txt)|*.txt"; + fd.DefaultExt = "*.files"; + fd.FileName = "MeinePlatten.files"; + fd.InitialDirectory = MainForm.basePath; + fd.CheckFileExists = false; + fd.CheckPathExists = true; + fd.AutoUpgradeEnabled = true; + if (fd.ShowDialog(this).Equals(DialogResult.OK)) + { + Log(String.Format("Offline-Datei {0} wurde gespeichert.", fd.FileName)); + m_MyDisks.SaveOfflineCacheToFile(fd.FileName); + } + } + } + + /// <summary> + /// Einlesen einer Cache-Datei für den Offline-Betrieb + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void verzeichnisFürMeinePlattenImportierenToolStripMenuItem_Click(object sender, EventArgs e) + { + using (OpenFileDialog fd = new OpenFileDialog()) + { + fd.Filter = "LanTool-Verzeichnis-Export (*.files)|*.files|Textdateien (*.txt)|*.txt"; + fd.DefaultExt = "*.files"; + fd.FileName = "MeinePlatten.files"; + fd.InitialDirectory = MainForm.basePath; + fd.CheckFileExists = true; + fd.CheckPathExists = true; + fd.Multiselect = false; + fd.AutoUpgradeEnabled = true; + if (fd.ShowDialog(this) == DialogResult.OK) + { + m_MyDisks.LoadOfflineCacheFromFile(fd.FileName); + m_MyDisks.IsOnline = false; + + Log(String.Format("Offline-Datei {0} wurde eingelesen.", fd.FileName)); + + UpdateTrees(); + } + } + } + + private void offlineCacheLöschenToolStripMenuItem_Click(object sender, EventArgs e) + { + m_MyDisks.ResetOfflineCaches(); + m_MyDisks.IsOnline = true; + + UpdateTrees(); + } + + #endregion + + /// <summary> + /// Speichern welcher TreeView zuletzt aufgerufen wurde + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void DisksTree_Enter(object sender, EventArgs e) + { + lastUsedView = (TreeView)sender; + } + + /// <summary> + /// Ausführen einer Datei durch Doppelklick + /// </summary> + private void tree_MouseDoubleClick(object sender, MouseEventArgs e) + { + try + { + // nur bei Linksklick reagieren + if (e.Button.Equals(MouseButtons.Left)) + { + Point clickPoint = new Point(e.X, e.Y); + + // Objekt unter der Maus holen + TreeNode clickNode = ((TreeView)sender).GetNodeAt(clickPoint); + // ins leere geklickt -> nichts tun + if ( clickNode == null || clickNode.Tag == null ) + { + return; + } + + StuffItem tn = (StuffItem)clickNode.Tag; + // kein StuffItem dran oder keine Datei + if ( tn == null || !tn.IsFile ) + { + return; + } + + // Datei ausführen + Status("Starte Datei: " + tn.Path); + Process.Start(tn.Path); + } + } + catch (Exception e2) + { + LogError("Fehler beim Ausführen: " + e2.Message); + } + } + + /// <summary> + /// Hotkeys behandeln + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void MainForm_KeyUp(object sender, KeyEventArgs e) + { + // ins Suchfeld springen bei Strg+F + if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control) + { + searchField.Focus(); + } + // gleiche Funktion wie Enter im Suchfeld + else if (e.KeyCode == Keys.F3) + { + searchField_KeyUp(sender, new KeyEventArgs(Keys.Return)); + } + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + // Caches auf die Platte schreiben + m_Cache.Dispose(); + } + + /// <summary> + /// Nach Auswahl eines Elementes den Pfad zum Element in der Textbox anzeigen + /// </summary> + private void myDisksTree_AfterSelect(object sender, TreeViewEventArgs e) + { + StuffItem selectedStuffItem = (StuffItem)myDisksTree.SelectedNode.Tag; + if (selectedStuffItem.IsFile) + { + myDisksPath.Text = Path.GetDirectoryName(selectedStuffItem.Path); + } + else + { + myDisksPath.Text = selectedStuffItem.Path; + } + } + + /// <summary> + /// Nach Auswahl eines Elementes den Pfad zum Element in der Textbox anzeigen + /// </summary> + private void otherDisksTree_AfterSelect(object sender, TreeViewEventArgs e) + { + StuffItem selectedStuffItem = (StuffItem)otherDisksTree.SelectedNode.Tag; + if (selectedStuffItem.IsFile) + { + otherDisksPath.Text = Path.GetDirectoryName(selectedStuffItem.Path); + } + else + { + otherDisksPath.Text = selectedStuffItem.Path; + } + } + + #region Pfad-Felder über den TreeViews + + private void DisksPath_OpenPath(object sender, MouseEventArgs e) + { + String path = ((TextBox)sender).Text; + + // Links -> Pfad im Explorer öffnen + if (e.Button == MouseButtons.Left) + { + try + { + // Nach oben suchen bis ein Text entsteht, der als Verzeichnis existiert + while ( !Directory.Exists( path ) && path.Length > 0 ) + { + path = path.Substring( 0, path.LastIndexOf( @"\" ) ); + } + + // im Explorer öffnen + if ( !Directory.Exists( path ) ) + { + return; + } + + Status( "Öffne Verzeichnis: " + path ); + Process.Start( path ); + } + catch { } + } + // Rechtsklick -> in die Zwischenablage + if (e.Button == MouseButtons.Right) + { + Clipboard.SetDataObject(path, true); + } + } + + private void DisksPath_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + DisksPath_OpenPath(sender, new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0)); + } + + #endregion + + #region Info-Menü + + private void lanToolForumToolStripMenuItem_Click(object sender, EventArgs e) + { + Process.Start("http://www.rw-net.de/bbl/index.php?page=Board&boardID=21"); + } + + private void lanToolTippsTricksToolStripMenuItem_Click(object sender, EventArgs e) + { + Process.Start("http://www.rw-net.de/LanTool_Tipps.txt"); + } + + private void lanToolChangeLogToolStripMenuItem_Click(object sender, EventArgs e) + { + Process.Start("http://www.rw-net.de/LanTool_ChangeLog.txt"); + } + + private void überToolStripMenuItem_Click(object sender, EventArgs e) + { + new AboutBox().ShowDialog(); + } + + private void fTPMitDemLanToolNetDriveToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + if (File.Exists("NetDrive-Setup.exe")) + Process.Start("NetDrive-Setup.exe"); + else + Process.Start("http://www.netdrive.net"); + } + catch + { } + } + + #endregion + + /// <summary> + /// Aktualisierung der beiden TreeViews starten + /// </summary> + private void StartUpdate() + { + // Auto Scan anwerfen + if (m_Config.IsAutoScanMyDisks) + { + m_MyDisks.UpdateChildsBackground(); + } + if (m_Config.IsAutoScanOtherDisks) + { + Program.MainWindow.m_OtherDisks.UpdateChildsBackground(); + } + + Program.MainWindow.UpdateTrees(); + } + } +} +\ No newline at end of file diff --git a/LanTool/MainForm.resx b/LanTool/MainForm.resx @@ -0,0 +1,343 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <metadata name="MainMenuToolStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>17, 17</value> + </metadata> + <metadata name="fileSystemImageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>293, 17</value> + </metadata> + <data name="fileSystemImageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64"> + <value> + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABa + EQAAAk1TRnQBSQFMAgEBFAEAAQwBAQEMAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + AwABQAMAAWADAAEBAQABCAYAARgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA + AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 + AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA + AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm + AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM + AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA + ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz + AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ + AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM + AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA + AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA + AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ + AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/ + AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA + AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm + ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ + Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz + AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA + AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM + AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM + ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM + Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA + AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM + AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ + AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz + AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm + AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw + AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD//8A/wD/AP8AmgABawFU + AvoBVAFrOAABxwFOBvoBTgHHNgABTgH6AVQBigIAAYoBVAH6AU4ZAAM4GQABawH6AVQBCgQAAQoBVAH6 + AWsWAAc4FwABTgH6AYoGAAGKAfoBThYABzgVAAJUAvoCVAH6BQAC+gUACvoGAAk4FQABVAL6AVQB+gYA + AvoFAAr6BgAJOBYAAU4C+gYAAYoB+gFOFQAJOBcAAfoBAAGhBAABCgFUAfoBaxYABzgbAAGKAgABigFU + AfoBThcABzgYAAHHAQAG+gFOAccZAAM4HAABawFUAvoBVAFr/wBOAAFUBAABVDoAAlQCAAJUCQAC+g4A + AfohAARUCgAC+g4AAvohAAJUCwAC+g4AA/ofAARUCgAC+g4ABPodAAJUAgACVAUACvoKAAT6BwABVCAA + CvoKAAP6CAACVAIAAlQfAAL6DgAC+goABFQgAAL6DgAB+gwAAlQhAAL6GgAEVCAAAvoZAAJUAgACVP8A + A/kDAAL5OQAD+QEAA/kGAAH5BwAC+QMAA90B+QfdAvkGAAX5DwAF+QYAAvkGAAP5AgABCQHPAagC+Qao + A/kBCQQAB/kJAAX5AQAD+QcAA/kEAAP5AgAB3QNLA/kCSwIqA/kBhgHPAwAJ+QcABfkBAAX5BwAD+QIA + A/kDAAFMAXoBTAGgAXoD+QJ6A/kBoAEqAagDAAn5BgAF+QEAAvkCAAP5BgAD+QEAA/kEAAFMAXoBTAGg + AXoD+QF6A/kBdAGgASoBqAIAC/8FAAT5AQAC+QEAAvkBAAL5BwAF+QUAAUwBegFSA6AF+QGgAXQBoAEq + AagCAAv/BAAF/wEAAfkBAAP/AgAB+QcABPkGAAFSAXoBUgOgBPkCoAF6AaABKgGoAgAL/wQABf8CAAT/ + CQAE+QcAAVIBegF0AqAE+QOgAXoBoAEqAagDAAn5BQAL/wgABvkGAAFSAXoBUgH/BvkC/wGaAf8BSwHP + AwAJ+QYACfkIAAT5AQAD+QUAAVIBoAGaBPkBUgP5AUwDSwHdBAAH+QcACfkHAAP5BAAC+QUAAVIBoAP5 + AqAC/wL5Af8BSwHPAd0GAAX5CQAH+QgAAvkFAAP5BAABdAH/AvkCoAH/AkwD+QFLAd0WAAX5EQAC+QUA + AXQE/wFSAQkCAAL5LgAD+QUAAXQDUgHdAwAD+RMAEP8wABD/MAAF/wEACv8FAAH6KgAE/wMACf8EAAP6 + KQAE/wMACf8EAAP6DwAD+gsAAfoLAAP/BQAI/wMABfoMAAf6CAAC+gsAA/8FAAj/AwAF+gwAB/oHAAr6 + BAAC/wMAAf8DAAf/AgAD+gEAA/oKAAn6BQAL+gQAAv8CAAL/AwAH/wIAAvoCAAP6CgAJ+gUAC/oEAAL/ + AQAE/wMABv8CAAH6BAAD+gkACfoGAAr6BAAH/wMABv8HAAP6CgAH+ggAAvoLAAj/AwAF/wgAA/oJAAf6 + CQAB+gsACP8DAAX/CAAD+gsAA/oXAAn/AwAE/wkAA/okAAn/AwAE/wkAA/okAAr/AwAD/woAA/ojAAL0 + Bv8B+Qf/MAAH9AP5BvQhAAGnDd0BpwH0AfMB8QK8B/kCvAHxAfMgAAGnAQkBzwuoAc8BCQHzAQcB7AFt + AfkCbQP5AW0C+QFtAewBByAAAd0ISwUqAYYBzwHxAlIBTAQqAvkEKgETAewGAAP/DQAD+QcAAUwBegFM + AaAIegF0AaABKgGoAVIBegFSAaAEegL5AnoBUgGgASoBbQQAB/8JAAf5BQABTAF6AUwBoAh6AXQBoAEq + AagBUgF6AVIBoAR6AvkCegFSAaABKgFtBAAH/wkAB/kFAAFMAXoBUgmgAXQBoAEqAagBUgF6AVIBoAf5 + AaABWAGgASoBbQMACf8HAAn5BAABUgF6AVIJoAF6AaABKgGoAVIBegFSAaAC+QKgA/kBoAF6AaABKgFt + AwAJ/wcACfkEAAFSAXoBdAmgAXoBoAEqAagBUgF6AVIBoAL5A6AC+QGgAXoBoAEqAW0DAAn/BwAJ+QQA + AVIBegFSCf8BmgH/AUsBzwFSAXoBUgL/AvkD/wH5Af8BmgH/ASoB7AQAB/8JAAf5BQABUgGgAZoGUgNM + A0sB3QFSAaABmgJSAvkIUgHxBAAH/wkAB/kFAAFSBqAF/wFLAc8B3QEAAVIEoAL5Bf8BKgHsAfAB9AYA + A/8NAAP5BwABdAH/BKAB/wNMA0sB3QIAAVIB/wOgAvkFUgFMAfEB8wH0IQABdAT/AVIBCQgAAfQBUgT/ + AfkBBwHzB/QiAAF0A1IB3QkAAvQEUgHxAfMI9CAAAUIBTQE+BwABPgMAASgDAAFAAwABYAMAAQEBAAEB + BgABAxYAA/+BAAr/AfgBHwT/AcABAwHgAQcE/wHfAfsBwAEDAv8B/AF/Ad8B+wHAAQEC/wHwAR8B3wH7 + AYMBwQL/AeABDwHfAfsBAQHBAcABAwHgAQ8B0AELAQAB4QHAAQMBwAEHAdABCwEBAeEBwAEDAcABBwHf + AfsBgwHBAcABAwHAAQcB3wH7AcMBgQL/AeABDwHfAfsB6AEDAv8B4AEPAd8B+wHgAQMC/wHwAR8BwAED + AfABBwL/AfwBfwL/AfgBHxb/Af4BAQH+AQEC/wH9Af8B/gH9Af4BeQH8AT8B/AH/Af4B/QH+ATEB/AE/ + AfwBfwH+Af0B/gGFAfwBPwH8AT8B/gH9Af4BzQH8AT8B/AEfAf4B/QH+AYUBwAEDAfwBDwGAAf0BgAEx + AcABAwH8AQ8BngEBAb4BAQHAAQMB/AEfAYwBfwG/AX8BwAEDAfwBPwGhAXcBvwF3AfwBPwH8AX8BswFj + Ab8BYwH8AT8B/AH/AaEBQQG/AUEB/AE/Af0B/wGMAXcBvwF3AfwBPwL/AYABRwGAAUcM/wH8ATgG/wH8 + ARAE/wH4AT8B/gEAAfsB+QHAAQEB8AEfAfABAQHzAfEBgAEAAeABDwHgAQMB8QHjAgABwAEHAcABAQH4 + AccCAAHAAQcBgAEAAfgBjwIAAYABAwGAAQAB/AEfAgABgAEDAgAB/AE/AgABgAEDAQABBAH4AX8CAAHA + AQcBAAEHAfABPwIAAcABBwGAAQ8B4QEfAgAB4AEPAYABDwHHAZ8BAAEBAfABHwHAAR8BzwGPAQABAwH4 + AT8B4AE/Af8BzwGAAc8C/wHwAX8B/wHHAcEBxwL/AgAG/wIABv8CAAH7A/8B+wH/AgAB8QH/AfwBfwHz + Af8CAAHxAf8B8AEfAeMB/wIAAeAB/wHgAQ8BwAEHAgAB4AH/AeABDwGAAQcCAAHEAX8BwAEHAQABBwIA + AcwBfwHAAQcBAAEHAgAB3gE/AcABBwGAAQcCAAH+AT8B4AEPAcABBwIAAf8BHwHgAQ8B4wH/AgAB/wEf + AfABHwHzAf8CAAH/AY8B/AF/AfsB/wIAAf8BjwT/AgAB/wHHBP8CAAb/AgAE/wGAAwAE/wQAAfwBfwH8 + AX8EAAHwAR8B8AEfBAAB4AEPAeABDwQAAeABDwHgAQ8EAAHAAQcBwAEHBAABwAEHAcABBwQAAcABBwHA + AQcEAAHgAQ8B4AEPBAAB4AEPAeABDwEAAQECAAHwAR8B8AEfAQABAwIAAfwBfwH8AX8BgAH/AgAE/wHB + Af8CAAT/Cw== +</value> + </data> + <metadata name="stsStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <value>177, 17</value> + </metadata> + <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> + <value>50</value> + </metadata> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + AAABAAMAMDAAAAEACACoDgAANgAAACAgAAABAAgAqAgAAN4OAAAQEAAAAQAIAGgFAACGFwAAKAAAADAA + AABgAAAAAQAIAAAAAACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AADAwMAAwNzAAPDKpgDU8P8AseL/AI7U/wBrxv8ASLj/ACWq/wAAqv8AAJLcAAB6uQAAYpYAAEpzAAAy + UADU4/8Ascf/AI6r/wBrj/8ASHP/ACVX/wAAVf8AAEncAAA9uQAAMZYAACVzAAAZUADU1P8AsbH/AI6O + /wBra/8ASEj/ACUl/wAAAP4AAADcAAAAuQAAAJYAAABzAAAAUADj1P8Ax7H/AKuO/wCPa/8Ac0j/AFcl + /wBVAP8ASQDcAD0AuQAxAJYAJQBzABkAUADw1P8A4rH/ANSO/wDGa/8AuEj/AKol/wCqAP8AkgDcAHoA + uQBiAJYASgBzADIAUAD/1P8A/7H/AP+O/wD/a/8A/0j/AP8l/wD+AP4A3ADcALkAuQCWAJYAcwBzAFAA + UAD/1PAA/7HiAP+O1AD/a8YA/0i4AP8lqgD/AKoA3ACSALkAegCWAGIAcwBKAFAAMgD/1OMA/7HHAP+O + qwD/a48A/0hzAP8lVwD/AFUA3ABJALkAPQCWADEAcwAlAFAAGQD/1NQA/7GxAP+OjgD/a2sA/0hIAP8l + JQD+AAAA3AAAALkAAACWAAAAcwAAAFAAAAD/49QA/8exAP+rjgD/j2sA/3NIAP9XJQD/VQAA3EkAALk9 + AACWMQAAcyUAAFAZAAD/8NQA/+KxAP/UjgD/xmsA/7hIAP+qJQD/qgAA3JIAALl6AACWYgAAc0oAAFAy + AAD//9QA//+xAP//jgD//2sA//9IAP//JQD+/gAA3NwAALm5AACWlgAAc3MAAFBQAADw/9QA4v+xANT/ + jgDG/2sAuP9IAKr/JQCq/wAAktwAAHq5AABilgAASnMAADJQAADj/9QAx/+xAKv/jgCP/2sAc/9IAFf/ + JQBV/wAASdwAAD25AAAxlgAAJXMAABlQAADU/9QAsf+xAI7/jgBr/2sASP9IACX/JQAA/gAAANwAAAC5 + AAAAlgAAAHMAAABQAADU/+MAsf/HAI7/qwBr/48ASP9zACX/VwAA/1UAANxJAAC5PQAAljEAAHMlAABQ + GQDU//AAsf/iAI7/1ABr/8YASP+4ACX/qgAA/6oAANySAAC5egAAlmIAAHNKAABQMgDU//8Asf//AI7/ + /wBr//8ASP//ACX//wAA/v4AANzcAAC5uQAAlpYAAHNzAABQUADy8vIA5ubmANra2gDOzs4AwsLCALa2 + tgCqqqoAnp6eAJKSkgCGhoYAenp6AG5ubgBiYmIAVlZWAEpKSgA+Pj4AMjIyACYmJgAaGhoADg4OAPD7 + /wCkoKAAgICAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADp6enp+O4AAAAA + AAAAAAAAAADu+Onp6ekAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrIAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAACy + srKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAACysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAsgAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAA + ALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////AAD///////8AAP// + /////wAA////////AAD///////8AAP/wD/AP/wAA///gB///AAD//+AP//8AAP//4A///wAA///wD/// + AAD///AP//8AAP//wAf//wAA///AA///AAD//8AB//8AAP//wAH//wAA///AAP//AAD//8AA//8AAP// + gAD//wAA//+AAP//AAD//4AA//8AAP//gAB//wAA//+AAD//AAD//4AAP/8AAP//gAA//wAA//+ACP// + AAD//wAY//8AAP//EBj//wAA//8QP///AAD//jg///8AAP/+PD///wAA//w8P///AAD//jw///8AAP// + /D///wAA///8P///AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA//////// + AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmANTw/wCx4v8AjtT/AGvG + /wBIuP8AJar/AACq/wAAktwAAHq5AABilgAASnMAADJQANTj/wCxx/8Ajqv/AGuP/wBIc/8AJVf/AABV + /wAASdwAAD25AAAxlgAAJXMAABlQANTU/wCxsf8Ajo7/AGtr/wBISP8AJSX/AAAA/gAAANwAAAC5AAAA + lgAAAHMAAABQAOPU/wDHsf8Aq47/AI9r/wBzSP8AVyX/AFUA/wBJANwAPQC5ADEAlgAlAHMAGQBQAPDU + /wDisf8A1I7/AMZr/wC4SP8AqiX/AKoA/wCSANwAegC5AGIAlgBKAHMAMgBQAP/U/wD/sf8A/47/AP9r + /wD/SP8A/yX/AP4A/gDcANwAuQC5AJYAlgBzAHMAUABQAP/U8AD/seIA/47UAP9rxgD/SLgA/yWqAP8A + qgDcAJIAuQB6AJYAYgBzAEoAUAAyAP/U4wD/sccA/46rAP9rjwD/SHMA/yVXAP8AVQDcAEkAuQA9AJYA + MQBzACUAUAAZAP/U1AD/sbEA/46OAP9rawD/SEgA/yUlAP4AAADcAAAAuQAAAJYAAABzAAAAUAAAAP/j + 1AD/x7EA/6uOAP+PawD/c0gA/1clAP9VAADcSQAAuT0AAJYxAABzJQAAUBkAAP/w1AD/4rEA/9SOAP/G + awD/uEgA/6olAP+qAADckgAAuXoAAJZiAABzSgAAUDIAAP//1AD//7EA//+OAP//awD//0gA//8lAP7+ + AADc3AAAubkAAJaWAABzcwAAUFAAAPD/1ADi/7EA1P+OAMb/awC4/0gAqv8lAKr/AACS3AAAerkAAGKW + AABKcwAAMlAAAOP/1ADH/7EAq/+OAI//awBz/0gAV/8lAFX/AABJ3AAAPbkAADGWAAAlcwAAGVAAANT/ + 1ACx/7EAjv+OAGv/awBI/0gAJf8lAAD+AAAA3AAAALkAAACWAAAAcwAAAFAAANT/4wCx/8cAjv+rAGv/ + jwBI/3MAJf9XAAD/VQAA3EkAALk9AACWMQAAcyUAAFAZANT/8ACx/+IAjv/UAGv/xgBI/7gAJf+qAAD/ + qgAA3JIAALl6AACWYgAAc0oAAFAyANT//wCx//8Ajv//AGv//wBI//8AJf//AAD+/gAA3NwAALm5AACW + lgAAc3MAAFBQAPLy8gDm5uYA2traAM7OzgDCwsIAtra2AKqqqgCenp4AkpKSAIaGhgB6enoAbm5uAGJi + YgBWVlYASkpKAD4+PgAyMjIAJiYmABoaGgAODg4A8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A + /wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6enp6fjuAAAAAAAAAAAAAAAA7vjp6enpAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAALKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrIAAAAA + AAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKy + sgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKy + srKysgAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + ALKysrKysrKyAAAAsgAAAAAAAAAAAAAAAAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAA + AAAAALIAALKysrKyAAAAALIAAAAAAAAAAAAAAAAAAAAAAACyAAAAsrKysgAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAsrIAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALIAAAAAAACysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///////////AP8A//4Af//+AP///gD///8A////AP///AB///wAP//8AB///A + Af//wAD//8AA//+AAP//gAD//4AA//+AAH//gAA//4AAP/+AAD//gAj//wAY//8QGP//ED///jg///48 + P//8PD///jw////8P////D///////ygAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYA1PD/ALHi/wCO1P8Aa8b/AEi4 + /wAlqv8AAKr/AACS3AAAerkAAGKWAABKcwAAMlAA1OP/ALHH/wCOq/8Aa4//AEhz/wAlV/8AAFX/AABJ + 3AAAPbkAADGWAAAlcwAAGVAA1NT/ALGx/wCOjv8Aa2v/AEhI/wAlJf8AAAD+AAAA3AAAALkAAACWAAAA + cwAAAFAA49T/AMex/wCrjv8Aj2v/AHNI/wBXJf8AVQD/AEkA3AA9ALkAMQCWACUAcwAZAFAA8NT/AOKx + /wDUjv8Axmv/ALhI/wCqJf8AqgD/AJIA3AB6ALkAYgCWAEoAcwAyAFAA/9T/AP+x/wD/jv8A/2v/AP9I + /wD/Jf8A/gD+ANwA3AC5ALkAlgCWAHMAcwBQAFAA/9TwAP+x4gD/jtQA/2vGAP9IuAD/JaoA/wCqANwA + kgC5AHoAlgBiAHMASgBQADIA/9TjAP+xxwD/jqsA/2uPAP9IcwD/JVcA/wBVANwASQC5AD0AlgAxAHMA + JQBQABkA/9TUAP+xsQD/jo4A/2trAP9ISAD/JSUA/gAAANwAAAC5AAAAlgAAAHMAAABQAAAA/+PUAP/H + sQD/q44A/49rAP9zSAD/VyUA/1UAANxJAAC5PQAAljEAAHMlAABQGQAA//DUAP/isQD/1I4A/8ZrAP+4 + SAD/qiUA/6oAANySAAC5egAAlmIAAHNKAABQMgAA///UAP//sQD//44A//9rAP//SAD//yUA/v4AANzc + AAC5uQAAlpYAAHNzAABQUAAA8P/UAOL/sQDU/44Axv9rALj/SACq/yUAqv8AAJLcAAB6uQAAYpYAAEpz + AAAyUAAA4//UAMf/sQCr/44Aj/9rAHP/SABX/yUAVf8AAEncAAA9uQAAMZYAACVzAAAZUAAA1P/UALH/ + sQCO/44Aa/9rAEj/SAAl/yUAAP4AAADcAAAAuQAAAJYAAABzAAAAUAAA1P/jALH/xwCO/6sAa/+PAEj/ + cwAl/1cAAP9VAADcSQAAuT0AAJYxAABzJQAAUBkA1P/wALH/4gCO/9QAa//GAEj/uAAl/6oAAP+qAADc + kgAAuXoAAJZiAABzSgAAUDIA1P//ALH//wCO//8Aa///AEj//wAl//8AAP7+AADc3AAAubkAAJaWAABz + cwAAUFAA8vLyAObm5gDa2toAzs7OAMLCwgC2trYAqqqqAJ6engCSkpIAhoaGAHp6egBubm4AYmJiAFZW + VgBKSkoAPj4+ADIyMgAmJiYAGhoaAA4ODgDw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAA6enuAAAAAAAA+OnpAAAAAAAAAACysrIAAAAAAAAAAAAAAAAA + srKyAAAAAAAAAAAAAAAAALKysgAAAAAAAAAAAAAAAACysrKyAAAAAAAAAAAAAAAAsrKysrIAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAsrKysgAAAAAA + AAAAAAAAAACysrIAAAAAAAAAAAAAALIAALIAAAAAAAAAAAAAAAAAAACyAAAAAAAAAAAAAAAAAAAAsgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADDwwAA+D8AAPg/AAD4PwAA+B8AAPgPAADwDwAA8A8AAPAH + AADwBwAA4E8AAOR/AADkfwAA5H8AAP5/AAA= +</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/NewFolderDialog.cs b/LanTool/NewFolderDialog.cs @@ -0,0 +1,28 @@ +using System.Windows.Forms; +using System.IO; + +namespace LanTool +{ + /// <summary> + /// Dialog zum Anlegen eines neuen Ordners auf den eigenen Platten + /// </summary> + public partial class NewFolderDialog : Form + { + /// <summary> + /// NewFolderDialog erstellen + /// </summary> + public NewFolderDialog () + { + InitializeComponent(); + } + + /// <summary> + /// Name des neuen Ordners + /// </summary> + public string NewFolderName + { + get { return newFolderTextBox.Text; } + set { newFolderTextBox.Text = value; } + } + } +} +\ No newline at end of file diff --git a/LanTool/NewFolderDialog.designer.cs b/LanTool/NewFolderDialog.designer.cs @@ -0,0 +1,111 @@ +namespace LanTool +{ + partial class NewFolderDialog + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NewFolderDialog)); + this.cancelButton = new System.Windows.Forms.Button(); + this.executeButton = new System.Windows.Forms.Button(); + this.newFolderTextBox = new System.Windows.Forms.TextBox(); + this.newFolderLabel = new System.Windows.Forms.Label(); + this.dokLabel = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // cancelButton + // + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(280, 79); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(75, 23); + this.cancelButton.TabIndex = 2; + this.cancelButton.Text = "Abbruch"; + this.cancelButton.UseVisualStyleBackColor = true; + // + // executeButton + // + this.executeButton.DialogResult = System.Windows.Forms.DialogResult.OK; + this.executeButton.Location = new System.Drawing.Point(199, 79); + this.executeButton.Name = "executeButton"; + this.executeButton.Size = new System.Drawing.Size(75, 23); + this.executeButton.TabIndex = 1; + this.executeButton.Text = "Erstellen"; + this.executeButton.UseVisualStyleBackColor = true; + // + // newFolderTextBox + // + this.newFolderTextBox.Location = new System.Drawing.Point(73, 12); + this.newFolderTextBox.Name = "newFolderTextBox"; + this.newFolderTextBox.Size = new System.Drawing.Size(281, 20); + this.newFolderTextBox.TabIndex = 0; + // + // newFolderLabel + // + this.newFolderLabel.AutoSize = true; + this.newFolderLabel.Location = new System.Drawing.Point(12, 12); + this.newFolderLabel.Name = "newFolderLabel"; + this.newFolderLabel.Size = new System.Drawing.Size(39, 13); + this.newFolderLabel.TabIndex = 3; + this.newFolderLabel.Text = "Ordner"; + // + // dokLabel + // + this.dokLabel.AutoSize = true; + this.dokLabel.Location = new System.Drawing.Point(70, 44); + this.dokLabel.Name = "dokLabel"; + this.dokLabel.Size = new System.Drawing.Size(171, 13); + this.dokLabel.TabIndex = 4; + this.dokLabel.Text = "Namen für neuen Ordner eingeben"; + // + // NewFolderDialog + // + this.AcceptButton = this.executeButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(365, 116); + this.Controls.Add(this.dokLabel); + this.Controls.Add(this.newFolderLabel); + this.Controls.Add(this.newFolderTextBox); + this.Controls.Add(this.executeButton); + this.Controls.Add(this.cancelButton); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "NewFolderDialog"; + this.Text = "Namen für neuen Ordner eingeben"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Button executeButton; + private System.Windows.Forms.TextBox newFolderTextBox; + private System.Windows.Forms.Label newFolderLabel; + private System.Windows.Forms.Label dokLabel; + } +} +\ No newline at end of file diff --git a/LanTool/NewFolderDialog.resx b/LanTool/NewFolderDialog.resx @@ -0,0 +1,249 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> + <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value> + AAABAAMAMDAAAAEACACoDgAANgAAACAgAAABAAgAqAgAAN4OAAAQEAAAAQAIAGgFAACGFwAAKAAAADAA + AABgAAAAAQAIAAAAAACACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICA + AADAwMAAwNzAAPDKpgDU8P8AseL/AI7U/wBrxv8ASLj/ACWq/wAAqv8AAJLcAAB6uQAAYpYAAEpzAAAy + UADU4/8Ascf/AI6r/wBrj/8ASHP/ACVX/wAAVf8AAEncAAA9uQAAMZYAACVzAAAZUADU1P8AsbH/AI6O + /wBra/8ASEj/ACUl/wAAAP4AAADcAAAAuQAAAJYAAABzAAAAUADj1P8Ax7H/AKuO/wCPa/8Ac0j/AFcl + /wBVAP8ASQDcAD0AuQAxAJYAJQBzABkAUADw1P8A4rH/ANSO/wDGa/8AuEj/AKol/wCqAP8AkgDcAHoA + uQBiAJYASgBzADIAUAD/1P8A/7H/AP+O/wD/a/8A/0j/AP8l/wD+AP4A3ADcALkAuQCWAJYAcwBzAFAA + UAD/1PAA/7HiAP+O1AD/a8YA/0i4AP8lqgD/AKoA3ACSALkAegCWAGIAcwBKAFAAMgD/1OMA/7HHAP+O + qwD/a48A/0hzAP8lVwD/AFUA3ABJALkAPQCWADEAcwAlAFAAGQD/1NQA/7GxAP+OjgD/a2sA/0hIAP8l + JQD+AAAA3AAAALkAAACWAAAAcwAAAFAAAAD/49QA/8exAP+rjgD/j2sA/3NIAP9XJQD/VQAA3EkAALk9 + AACWMQAAcyUAAFAZAAD/8NQA/+KxAP/UjgD/xmsA/7hIAP+qJQD/qgAA3JIAALl6AACWYgAAc0oAAFAy + AAD//9QA//+xAP//jgD//2sA//9IAP//JQD+/gAA3NwAALm5AACWlgAAc3MAAFBQAADw/9QA4v+xANT/ + jgDG/2sAuP9IAKr/JQCq/wAAktwAAHq5AABilgAASnMAADJQAADj/9QAx/+xAKv/jgCP/2sAc/9IAFf/ + JQBV/wAASdwAAD25AAAxlgAAJXMAABlQAADU/9QAsf+xAI7/jgBr/2sASP9IACX/JQAA/gAAANwAAAC5 + AAAAlgAAAHMAAABQAADU/+MAsf/HAI7/qwBr/48ASP9zACX/VwAA/1UAANxJAAC5PQAAljEAAHMlAABQ + GQDU//AAsf/iAI7/1ABr/8YASP+4ACX/qgAA/6oAANySAAC5egAAlmIAAHNKAABQMgDU//8Asf//AI7/ + /wBr//8ASP//ACX//wAA/v4AANzcAAC5uQAAlpYAAHNzAABQUADy8vIA5ubmANra2gDOzs4AwsLCALa2 + tgCqqqoAnp6eAJKSkgCGhoYAenp6AG5ubgBiYmIAVlZWAEpKSgA+Pj4AMjIyACYmJgAaGhoADg4OAPD7 + /wCkoKAAgICAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADp6enp+O4AAAAA + AAAAAAAAAADu+Onp6ekAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAsrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrKysgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrIAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAACy + srKysgAAAACyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAACysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAALIAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAsgAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAA + ALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKyAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////AAD///////8AAP// + /////wAA////////AAD///////8AAP/wD/AP/wAA///gB///AAD//+AP//8AAP//4A///wAA///wD/// + AAD///AP//8AAP//wAf//wAA///AA///AAD//8AB//8AAP//wAH//wAA///AAP//AAD//8AA//8AAP// + gAD//wAA//+AAP//AAD//4AA//8AAP//gAB//wAA//+AAD//AAD//4AAP/8AAP//gAA//wAA//+ACP// + AAD//wAY//8AAP//EBj//wAA//8QP///AAD//jg///8AAP/+PD///wAA//w8P///AAD//jw///8AAP// + /D///wAA///8P///AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA//////// + AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmANTw/wCx4v8AjtT/AGvG + /wBIuP8AJar/AACq/wAAktwAAHq5AABilgAASnMAADJQANTj/wCxx/8Ajqv/AGuP/wBIc/8AJVf/AABV + /wAASdwAAD25AAAxlgAAJXMAABlQANTU/wCxsf8Ajo7/AGtr/wBISP8AJSX/AAAA/gAAANwAAAC5AAAA + lgAAAHMAAABQAOPU/wDHsf8Aq47/AI9r/wBzSP8AVyX/AFUA/wBJANwAPQC5ADEAlgAlAHMAGQBQAPDU + /wDisf8A1I7/AMZr/wC4SP8AqiX/AKoA/wCSANwAegC5AGIAlgBKAHMAMgBQAP/U/wD/sf8A/47/AP9r + /wD/SP8A/yX/AP4A/gDcANwAuQC5AJYAlgBzAHMAUABQAP/U8AD/seIA/47UAP9rxgD/SLgA/yWqAP8A + qgDcAJIAuQB6AJYAYgBzAEoAUAAyAP/U4wD/sccA/46rAP9rjwD/SHMA/yVXAP8AVQDcAEkAuQA9AJYA + MQBzACUAUAAZAP/U1AD/sbEA/46OAP9rawD/SEgA/yUlAP4AAADcAAAAuQAAAJYAAABzAAAAUAAAAP/j + 1AD/x7EA/6uOAP+PawD/c0gA/1clAP9VAADcSQAAuT0AAJYxAABzJQAAUBkAAP/w1AD/4rEA/9SOAP/G + awD/uEgA/6olAP+qAADckgAAuXoAAJZiAABzSgAAUDIAAP//1AD//7EA//+OAP//awD//0gA//8lAP7+ + AADc3AAAubkAAJaWAABzcwAAUFAAAPD/1ADi/7EA1P+OAMb/awC4/0gAqv8lAKr/AACS3AAAerkAAGKW + AABKcwAAMlAAAOP/1ADH/7EAq/+OAI//awBz/0gAV/8lAFX/AABJ3AAAPbkAADGWAAAlcwAAGVAAANT/ + 1ACx/7EAjv+OAGv/awBI/0gAJf8lAAD+AAAA3AAAALkAAACWAAAAcwAAAFAAANT/4wCx/8cAjv+rAGv/ + jwBI/3MAJf9XAAD/VQAA3EkAALk9AACWMQAAcyUAAFAZANT/8ACx/+IAjv/UAGv/xgBI/7gAJf+qAAD/ + qgAA3JIAALl6AACWYgAAc0oAAFAyANT//wCx//8Ajv//AGv//wBI//8AJf//AAD+/gAA3NwAALm5AACW + lgAAc3MAAFBQAPLy8gDm5uYA2traAM7OzgDCwsIAtra2AKqqqgCenp4AkpKSAIaGhgB6enoAbm5uAGJi + YgBWVlYASkpKAD4+PgAyMjIAJiYmABoaGgAODg4A8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A + /wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA6enp6fjuAAAAAAAAAAAAAAAA7vjp6enpAAAAAAAAAAAAAAAAAAAAAACy + srKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKyAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAALKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAsrKysrKysrKysrIAAAAA + AAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKy + sgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrIAAAAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKy + srKysgAAAAAAAAAAAAAAAAAAAAAAAAAAALKysrKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAAAAsrKy + srKysrKysrKysgAAAAAAAAAAAAAAAAAAAAAAAACysrKysrKysrKysrKyAAAAAAAAAAAAAAAAAAAAAAAA + ALKysrKysrKyAAAAsgAAAAAAAAAAAAAAAAAAAAAAAACyAACysrKysgAAAACyAAAAAAAAAAAAAAAAAAAA + AAAAALIAALKysrKyAAAAALIAAAAAAAAAAAAAAAAAAAAAAACyAAAAsrKysgAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAALIAAAAAsrKyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAsrIAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAALIAAAAAAACysgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsgAAAAAAALKyAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAsrIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACysgAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD///////////AP8A//4Af//+AP///gD///8A////AP///AB///wAP//8AB///A + Af//wAD//8AA//+AAP//gAD//4AA//+AAH//gAA//4AAP/+AAD//gAj//wAY//8QGP//ED///jg///48 + P//8PD///jw////8P////D///////ygAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYA1PD/ALHi/wCO1P8Aa8b/AEi4 + /wAlqv8AAKr/AACS3AAAerkAAGKWAABKcwAAMlAA1OP/ALHH/wCOq/8Aa4//AEhz/wAlV/8AAFX/AABJ + 3AAAPbkAADGWAAAlcwAAGVAA1NT/ALGx/wCOjv8Aa2v/AEhI/wAlJf8AAAD+AAAA3AAAALkAAACWAAAA + cwAAAFAA49T/AMex/wCrjv8Aj2v/AHNI/wBXJf8AVQD/AEkA3AA9ALkAMQCWACUAcwAZAFAA8NT/AOKx + /wDUjv8Axmv/ALhI/wCqJf8AqgD/AJIA3AB6ALkAYgCWAEoAcwAyAFAA/9T/AP+x/wD/jv8A/2v/AP9I + /wD/Jf8A/gD+ANwA3AC5ALkAlgCWAHMAcwBQAFAA/9TwAP+x4gD/jtQA/2vGAP9IuAD/JaoA/wCqANwA + kgC5AHoAlgBiAHMASgBQADIA/9TjAP+xxwD/jqsA/2uPAP9IcwD/JVcA/wBVANwASQC5AD0AlgAxAHMA + JQBQABkA/9TUAP+xsQD/jo4A/2trAP9ISAD/JSUA/gAAANwAAAC5AAAAlgAAAHMAAABQAAAA/+PUAP/H + sQD/q44A/49rAP9zSAD/VyUA/1UAANxJAAC5PQAAljEAAHMlAABQGQAA//DUAP/isQD/1I4A/8ZrAP+4 + SAD/qiUA/6oAANySAAC5egAAlmIAAHNKAABQMgAA///UAP//sQD//44A//9rAP//SAD//yUA/v4AANzc + AAC5uQAAlpYAAHNzAABQUAAA8P/UAOL/sQDU/44Axv9rALj/SACq/yUAqv8AAJLcAAB6uQAAYpYAAEpz + AAAyUAAA4//UAMf/sQCr/44Aj/9rAHP/SABX/yUAVf8AAEncAAA9uQAAMZYAACVzAAAZUAAA1P/UALH/ + sQCO/44Aa/9rAEj/SAAl/yUAAP4AAADcAAAAuQAAAJYAAABzAAAAUAAA1P/jALH/xwCO/6sAa/+PAEj/ + cwAl/1cAAP9VAADcSQAAuT0AAJYxAABzJQAAUBkA1P/wALH/4gCO/9QAa//GAEj/uAAl/6oAAP+qAADc + kgAAuXoAAJZiAABzSgAAUDIA1P//ALH//wCO//8Aa///AEj//wAl//8AAP7+AADc3AAAubkAAJaWAABz + cwAAUFAA8vLyAObm5gDa2toAzs7OAMLCwgC2trYAqqqqAJ6engCSkpIAhoaGAHp6egBubm4AYmJiAFZW + VgBKSkoAPj4+ADIyMgAmJiYAGhoaAA4ODgDw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAAAAAAAAAA6enuAAAAAAAA+OnpAAAAAAAAAACysrIAAAAAAAAAAAAAAAAA + srKyAAAAAAAAAAAAAAAAALKysgAAAAAAAAAAAAAAAACysrKyAAAAAAAAAAAAAAAAsrKysrIAAAAAAAAA + AAAAsrKysrKyAAAAAAAAAAAAALKysrKysgAAAAAAAAAAAACysrKysrKyAAAAAAAAAAAAsrKysgAAAAAA + AAAAAAAAAACysrIAAAAAAAAAAAAAALIAALIAAAAAAAAAAAAAAAAAAACyAAAAAAAAAAAAAAAAAAAAsgAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADDwwAA+D8AAPg/AAD4PwAA+B8AAPgPAADwDwAA8A8AAPAH + AADwBwAA4E8AAOR/AADkfwAA5H8AAP5/AAA= +</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/Program.cs b/LanTool/Program.cs @@ -0,0 +1,97 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Windows.Forms; +using LanTool.Classes; + +[assembly: CLSCompliant(true)] +namespace LanTool +{ + static class Program + { + public static MainForm MainWindow; + + /// <summary> + /// Länger andauernde Funktion im Hintergrund starten (damit Oberfläche bedienbar bleibt) + /// </summary> + /// <param name="obj">Owner</param> + /// <param name="procname">Name der Funktion die aufzurufen ist</param> + /// <param name="para">Parameter des Aufrufs</param> + public static void RunBackgroundTask( object obj, string procname, object para ) + { + try + { + WaitCallback wc = ( WaitCallback )Delegate.CreateDelegate( typeof( WaitCallback ), obj, procname ); + if ( para == null ) + { + ThreadPool.QueueUserWorkItem( wc ); + } + else + { + ThreadPool.QueueUserWorkItem( wc, para ); + } + } + catch ( Exception ex ) + { + Console.WriteLine( ex.ToString() ); + } + } + + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault( false ); + + Boolean createdNew; + Mutex mut = new Mutex( true, "LanTool_" + Application.StartupPath.Replace( @"\", "_" ), out createdNew ); + try + { + if ( createdNew ) + { + MainWindow = new MainForm(); + Application.Run( MainWindow ); + + // Release the Mutex. + mut.ReleaseMutex(); + } + else + { + // Alle Processe die "LanTool" heißen suchen + Process[] ltprocs = Process.GetProcessesByName( "LanTool" ); + + // Prozesse in den Vordergrund holen + foreach ( Process ltproc in ltprocs ) + { + // TODO: Holen des Fensters klappt nicht im normalen Aufruf + if ( ltproc.MainModule.FileName.Equals( Application.ExecutablePath, + StringComparison.OrdinalIgnoreCase ) && + ltproc.Id != Process.GetCurrentProcess().Id ) + { + NativeMethods.SetForegroundWindow( ( int )ltproc.MainWindowHandle ); + break; + } + } + } + } + catch ( Exception ex ) + { + MessageBox.Show( ex.ToString() ); + } + finally + { + // Mutex schließen + if ( mut != null ) + { + if ( createdNew ) + { + mut.Close(); + } + } + } + } + } +} +\ No newline at end of file diff --git a/LanTool/Properties/AssemblyInfo.cs b/LanTool/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Resources; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LanTool")] +[assembly: AssemblyDescription("Das LanTool ist ein äußerst nützliches Werkzeug, um die eigene Datensammlung im Blick zu behalten und auf LanBaddies schnell und einfach zu erweitern.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("St. CapLAN")] +[assembly: AssemblyProduct("LanTool")] +[assembly: AssemblyCopyright("Copyright © stlan.de.vu / Buddha && apollo")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("05948a00-7dc0-4d69-bbbc-fb81f54624cf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion( "1.6.0.0" )] +[assembly: AssemblyFileVersion( "1.6.0.0" )] + +[assembly: NeutralResourcesLanguageAttribute("de-DE")] diff --git a/LanTool/Properties/Resources.Designer.cs b/LanTool/Properties/Resources.Designer.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace LanTool.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LanTool.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap DeleteHS { + get { + object obj = ResourceManager.GetObject("DeleteHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap EditTableHS { + get { + object obj = ResourceManager.GetObject("EditTableHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap FindHS { + get { + object obj = ResourceManager.GetObject("FindHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap HTMLPage { + get { + object obj = ResourceManager.GetObject("HTMLPage", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap OpenFile { + get { + object obj = ResourceManager.GetObject("OpenFile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap openfolderHS { + get { + object obj = ResourceManager.GetObject("openfolderHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// <summary> + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// </summary> + internal static System.Drawing.Bitmap saveHS { + get { + object obj = ResourceManager.GetObject("saveHS", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/LanTool/Properties/Resources.resx b/LanTool/Properties/Resources.resx @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> + <data name="DeleteHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\DeleteHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="HTMLPage" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\HTMLPage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="EditTableHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\EditTableHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="FindHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\FindHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="OpenFile" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\OpenFile.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <data name="saveHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\saveHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> + <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> + <data name="openfolderHS" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\openfolderHS.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> +</root> +\ No newline at end of file diff --git a/LanTool/Properties/app.manifest b/LanTool/Properties/app.manifest @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <assemblyIdentity version="1.0.0.0" name="MyApplication.app" /> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> + <security> + <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> + <!-- UAC Manifest Options + If you want to change the Windows User Account Control level replace the + requestedExecutionLevel node with one of the following. + + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> + <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> + + Specifying requestedExecutionLevel node will disable file and registry virtualization. + If you want to utilize File and Registry Virtualization for backward + compatibility then delete the requestedExecutionLevel node. + --> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </requestedPrivileges> + <applicationRequestMinimum> + <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" /> + <defaultAssemblyRequest permissionSetReference="Custom" /> + </applicationRequestMinimum> + </security> + </trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.--> + <!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node--> + <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>--> + </application> + </compatibility> + <!-- Enable themes for Windows common controls and dialogs (Windows XP and later) --> + <!-- <dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.Windows.Common-Controls" + version="6.0.0.0" + processorArchitecture="*" + publicKeyToken="6595b64144ccf1df" + language="*" + /> + </dependentAssembly> + </dependency>--> +</asmv1:assembly> +\ No newline at end of file diff --git a/LanTool/Resources/DeleteHS.png b/LanTool/Resources/DeleteHS.png Binary files differ. diff --git a/LanTool/Resources/EditTableHS.png b/LanTool/Resources/EditTableHS.png Binary files differ. diff --git a/LanTool/Resources/FindHS.png b/LanTool/Resources/FindHS.png Binary files differ. diff --git a/LanTool/Resources/HTMLPage.png b/LanTool/Resources/HTMLPage.png Binary files differ. diff --git a/LanTool/Resources/OpenFile.png b/LanTool/Resources/OpenFile.png Binary files differ. diff --git a/LanTool/Resources/openfolderHS.png b/LanTool/Resources/openfolderHS.png Binary files differ. diff --git a/LanTool/Resources/saveHS.png b/LanTool/Resources/saveHS.png Binary files differ. diff --git a/LanTool/app.config b/LanTool/app.config @@ -0,0 +1,3 @@ +<?xml version="1.0"?> +<configuration> +<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>