diff --git a/FLParser b/FLParser
new file mode 160000
index 0000000..124b685
--- /dev/null
+++ b/FLParser
@@ -0,0 +1 @@
+Subproject commit 124b685950f0262a256d09bab3d226569a91bdbe
diff --git a/FLRecordingCleaner.sln b/FLRecordingCleaner.sln
new file mode 100644
index 0000000..b7bc92c
--- /dev/null
+++ b/FLRecordingCleaner.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27428.2015
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monad.FLParser", "FLParser\Monad.FLParser.csproj", "{CE83037E-41AA-4C72-BE2E-1DF90583AD17}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FLRecordingCleaner", "FLRecordingCleaner\FLRecordingCleaner.csproj", "{20C0846E-6CAA-4443-B6E5-6F1511EAA557}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CE83037E-41AA-4C72-BE2E-1DF90583AD17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE83037E-41AA-4C72-BE2E-1DF90583AD17}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE83037E-41AA-4C72-BE2E-1DF90583AD17}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE83037E-41AA-4C72-BE2E-1DF90583AD17}.Release|Any CPU.Build.0 = Release|Any CPU
+ {20C0846E-6CAA-4443-B6E5-6F1511EAA557}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20C0846E-6CAA-4443-B6E5-6F1511EAA557}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20C0846E-6CAA-4443-B6E5-6F1511EAA557}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20C0846E-6CAA-4443-B6E5-6F1511EAA557}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4B4023F4-71FD-4EC1-8620-1B3844B45B90}
+ EndGlobalSection
+EndGlobal
diff --git a/FLRecordingCleaner/.gitignore b/FLRecordingCleaner/.gitignore
new file mode 100644
index 0000000..22fd88a
--- /dev/null
+++ b/FLRecordingCleaner/.gitignore
@@ -0,0 +1,295 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+**/Properties/launchSettings.json
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Typescript v1 declaration files
+typings/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
diff --git a/FLRecordingCleaner/App.config b/FLRecordingCleaner/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/FLRecordingCleaner/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FLRecordingCleaner/FLRecordingCleaner.csproj b/FLRecordingCleaner/FLRecordingCleaner.csproj
new file mode 100644
index 0000000..997c769
--- /dev/null
+++ b/FLRecordingCleaner/FLRecordingCleaner.csproj
@@ -0,0 +1,91 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {20C0846E-6CAA-4443-B6E5-6F1511EAA557}
+ WinExe
+ FLRecordingCleaner
+ FLRecordingCleaner
+ v4.6.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+ {ce83037e-41aa-4c72-be2e-1df90583ad17}
+ Monad.FLParser
+
+
+
+
\ No newline at end of file
diff --git a/FLRecordingCleaner/Form1.Designer.cs b/FLRecordingCleaner/Form1.Designer.cs
new file mode 100644
index 0000000..613422e
--- /dev/null
+++ b/FLRecordingCleaner/Form1.Designer.cs
@@ -0,0 +1,299 @@
+namespace FLRecordingCleaner
+{
+ partial class Form1
+ {
+ ///
+ /// Обязательная переменная конструктора.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Освободить все используемые ресурсы.
+ ///
+ /// истинно, если управляемый ресурс должен быть удален; иначе ложно.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Код, автоматически созданный конструктором форм Windows
+
+ ///
+ /// Требуемый метод для поддержки конструктора — не изменяйте
+ /// содержимое этого метода с помощью редактора кода.
+ ///
+ private void InitializeComponent()
+ {
+ this.label1 = new System.Windows.Forms.Label();
+ this.projectsPathBox = new System.Windows.Forms.TextBox();
+ this.browseBtn = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.unusedRecSizeLabel = new System.Windows.Forms.Label();
+ this.unusedRecLabel = new System.Windows.Forms.Label();
+ this.totalRecSizeLabel = new System.Windows.Forms.Label();
+ this.totalRecLabel = new System.Windows.Forms.Label();
+ this.totalProjectsLabel = new System.Windows.Forms.Label();
+ this.label6 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.label4 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.gatherInfoBtn = new System.Windows.Forms.Button();
+ this.folderPick = new System.Windows.Forms.OpenFileDialog();
+ this.folderPickDlg = new System.Windows.Forms.FolderBrowserDialog();
+ this.bgWorker = new System.ComponentModel.BackgroundWorker();
+ this.doCleanupBtn = new System.Windows.Forms.Button();
+ this.ignoreErrorsCheck = new System.Windows.Forms.CheckBox();
+ this.delWorker = new System.ComponentModel.BackgroundWorker();
+ this.progressBar = new System.Windows.Forms.ProgressBar();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(9, 22);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(268, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Select folder where your FL Studio projects are located ";
+ //
+ // projectsPathBox
+ //
+ this.projectsPathBox.Location = new System.Drawing.Point(12, 38);
+ this.projectsPathBox.Name = "projectsPathBox";
+ this.projectsPathBox.Size = new System.Drawing.Size(435, 20);
+ this.projectsPathBox.TabIndex = 1;
+ //
+ // browseBtn
+ //
+ this.browseBtn.Location = new System.Drawing.Point(453, 36);
+ this.browseBtn.Name = "browseBtn";
+ this.browseBtn.Size = new System.Drawing.Size(75, 23);
+ this.browseBtn.TabIndex = 2;
+ this.browseBtn.Text = "Browse";
+ this.browseBtn.UseVisualStyleBackColor = true;
+ this.browseBtn.Click += new System.EventHandler(this.browseBtn_Click);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.unusedRecSizeLabel);
+ this.groupBox1.Controls.Add(this.unusedRecLabel);
+ this.groupBox1.Controls.Add(this.totalRecSizeLabel);
+ this.groupBox1.Controls.Add(this.totalRecLabel);
+ this.groupBox1.Controls.Add(this.totalProjectsLabel);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.label4);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Location = new System.Drawing.Point(12, 65);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(516, 153);
+ this.groupBox1.TabIndex = 4;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Folder information";
+ //
+ // unusedRecSizeLabel
+ //
+ this.unusedRecSizeLabel.AutoSize = true;
+ this.unusedRecSizeLabel.Location = new System.Drawing.Point(167, 121);
+ this.unusedRecSizeLabel.Name = "unusedRecSizeLabel";
+ this.unusedRecSizeLabel.Size = new System.Drawing.Size(10, 13);
+ this.unusedRecSizeLabel.TabIndex = 9;
+ this.unusedRecSizeLabel.Text = "-";
+ //
+ // unusedRecLabel
+ //
+ this.unusedRecLabel.AutoSize = true;
+ this.unusedRecLabel.Location = new System.Drawing.Point(167, 99);
+ this.unusedRecLabel.Name = "unusedRecLabel";
+ this.unusedRecLabel.Size = new System.Drawing.Size(10, 13);
+ this.unusedRecLabel.TabIndex = 8;
+ this.unusedRecLabel.Text = "-";
+ //
+ // totalRecSizeLabel
+ //
+ this.totalRecSizeLabel.AutoSize = true;
+ this.totalRecSizeLabel.Location = new System.Drawing.Point(167, 77);
+ this.totalRecSizeLabel.Name = "totalRecSizeLabel";
+ this.totalRecSizeLabel.Size = new System.Drawing.Size(10, 13);
+ this.totalRecSizeLabel.TabIndex = 7;
+ this.totalRecSizeLabel.Text = "-";
+ //
+ // totalRecLabel
+ //
+ this.totalRecLabel.AutoSize = true;
+ this.totalRecLabel.Location = new System.Drawing.Point(167, 53);
+ this.totalRecLabel.Name = "totalRecLabel";
+ this.totalRecLabel.Size = new System.Drawing.Size(10, 13);
+ this.totalRecLabel.TabIndex = 6;
+ this.totalRecLabel.Text = "-";
+ //
+ // totalProjectsLabel
+ //
+ this.totalProjectsLabel.AutoSize = true;
+ this.totalProjectsLabel.Location = new System.Drawing.Point(167, 29);
+ this.totalProjectsLabel.Name = "totalProjectsLabel";
+ this.totalProjectsLabel.Size = new System.Drawing.Size(10, 13);
+ this.totalProjectsLabel.TabIndex = 5;
+ this.totalProjectsLabel.Text = "-";
+ //
+ // label6
+ //
+ this.label6.AutoSize = true;
+ this.label6.Location = new System.Drawing.Point(6, 121);
+ this.label6.Name = "label6";
+ this.label6.Size = new System.Drawing.Size(120, 13);
+ this.label6.TabIndex = 4;
+ this.label6.Text = "Unused recordings size:";
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Location = new System.Drawing.Point(6, 99);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(99, 13);
+ this.label5.TabIndex = 3;
+ this.label5.Text = "Unused recordings:";
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(6, 77);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(107, 13);
+ this.label4.TabIndex = 2;
+ this.label4.Text = "Total recordings size:";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(6, 53);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(86, 13);
+ this.label3.TabIndex = 1;
+ this.label3.Text = "Total recordings:";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(6, 29);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(74, 13);
+ this.label2.TabIndex = 0;
+ this.label2.Text = "Total projects:";
+ //
+ // gatherInfoBtn
+ //
+ this.gatherInfoBtn.Location = new System.Drawing.Point(12, 224);
+ this.gatherInfoBtn.Name = "gatherInfoBtn";
+ this.gatherInfoBtn.Size = new System.Drawing.Size(135, 23);
+ this.gatherInfoBtn.TabIndex = 5;
+ this.gatherInfoBtn.Text = "Gather Information";
+ this.gatherInfoBtn.UseVisualStyleBackColor = true;
+ this.gatherInfoBtn.Click += new System.EventHandler(this.gatherInfoBtn_Click);
+ //
+ // folderPick
+ //
+ this.folderPick.CheckFileExists = false;
+ this.folderPick.CheckPathExists = false;
+ //
+ // bgWorker
+ //
+ this.bgWorker.WorkerReportsProgress = true;
+ this.bgWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.bgWorker_DoWork);
+ this.bgWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.bgWorker_ProgressChanged);
+ this.bgWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.bgWorker_OnComplete);
+ //
+ // doCleanupBtn
+ //
+ this.doCleanupBtn.Location = new System.Drawing.Point(420, 224);
+ this.doCleanupBtn.Name = "doCleanupBtn";
+ this.doCleanupBtn.Size = new System.Drawing.Size(108, 23);
+ this.doCleanupBtn.TabIndex = 6;
+ this.doCleanupBtn.Text = "Perform cleanup";
+ this.doCleanupBtn.UseVisualStyleBackColor = true;
+ this.doCleanupBtn.Click += new System.EventHandler(this.doCleanupBtn_Click);
+ //
+ // ignoreErrorsCheck
+ //
+ this.ignoreErrorsCheck.AutoSize = true;
+ this.ignoreErrorsCheck.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+ this.ignoreErrorsCheck.Location = new System.Drawing.Point(329, 228);
+ this.ignoreErrorsCheck.Name = "ignoreErrorsCheck";
+ this.ignoreErrorsCheck.Size = new System.Drawing.Size(85, 17);
+ this.ignoreErrorsCheck.TabIndex = 7;
+ this.ignoreErrorsCheck.Text = "Ignore errors";
+ this.ignoreErrorsCheck.UseVisualStyleBackColor = true;
+ //
+ // delWorker
+ //
+ this.delWorker.WorkerReportsProgress = true;
+ this.delWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.delWorker_DoWork);
+ this.delWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.delWorker_ProgressChanged);
+ //
+ // progressBar
+ //
+ this.progressBar.Location = new System.Drawing.Point(12, 259);
+ this.progressBar.Name = "progressBar";
+ this.progressBar.Size = new System.Drawing.Size(516, 23);
+ this.progressBar.TabIndex = 8;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(540, 294);
+ this.Controls.Add(this.progressBar);
+ this.Controls.Add(this.ignoreErrorsCheck);
+ this.Controls.Add(this.doCleanupBtn);
+ this.Controls.Add(this.gatherInfoBtn);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.browseBtn);
+ this.Controls.Add(this.projectsPathBox);
+ this.Controls.Add(this.label1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Form1";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "FL Studio Unused Recording Cleaner Utility 1.0";
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox projectsPathBox;
+ private System.Windows.Forms.Button browseBtn;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button gatherInfoBtn;
+ private System.Windows.Forms.OpenFileDialog folderPick;
+ private System.Windows.Forms.FolderBrowserDialog folderPickDlg;
+ private System.ComponentModel.BackgroundWorker bgWorker;
+ private System.Windows.Forms.Label unusedRecSizeLabel;
+ private System.Windows.Forms.Label unusedRecLabel;
+ private System.Windows.Forms.Label totalRecSizeLabel;
+ private System.Windows.Forms.Label totalRecLabel;
+ private System.Windows.Forms.Label totalProjectsLabel;
+ private System.Windows.Forms.Button doCleanupBtn;
+ private System.Windows.Forms.CheckBox ignoreErrorsCheck;
+ private System.ComponentModel.BackgroundWorker delWorker;
+ private System.Windows.Forms.ProgressBar progressBar;
+ }
+}
+
diff --git a/FLRecordingCleaner/Form1.cs b/FLRecordingCleaner/Form1.cs
new file mode 100644
index 0000000..02b5e00
--- /dev/null
+++ b/FLRecordingCleaner/Form1.cs
@@ -0,0 +1,303 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Windows.Forms;
+using System.Linq;
+using Microsoft.VisualBasic;
+using System.Collections.Generic;
+
+namespace FLRecordingCleaner
+{
+ public partial class Form1 : Form
+ {
+ GatheringResult GatheringResult = null;
+ ProjectInfo[] ProjectFolderGroups = null;
+
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void browseBtn_Click(object sender, EventArgs e)
+ {
+ if (folderPickDlg.ShowDialog() == DialogResult.OK)
+ {
+ projectsPathBox.Text = folderPickDlg.SelectedPath;
+ }
+ }
+
+ private void gatherInfoBtn_Click(object sender, EventArgs e)
+ {
+ if (!Directory.Exists(projectsPathBox.Text))
+ {
+ MessageBox.Show(this, "Folder you have choosen does not exists", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning );
+ return;
+ }
+
+ totalProjectsLabel.Text = "Please wait...";
+ totalRecLabel.Text = "-";
+ totalRecSizeLabel.Text = "-";
+ unusedRecLabel.Text = "-";
+ unusedRecSizeLabel.Text = "-";
+
+ GatheringResult = null;
+ ProjectFolderGroups = null;
+
+ progressBar.Value = 0;
+
+ bgWorker.RunWorkerAsync(projectsPathBox.Text);
+ }
+
+ private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
+ {
+ string folderPath = (string)e.Argument;
+
+ var result = new GatheringResult();
+
+ // first we search for FLP files
+ foreach (var file in Directory.EnumerateFiles(folderPath, "*.flp", SearchOption.AllDirectories))
+ {
+ result.ProjectList.Add(new ProjectInfo {
+ FileName = file,
+ });
+ }
+
+ // second we're parsing the FLP file for project folder path
+ //foreach (var project in result.ProjectList)
+ for(int i = 0; i < result.ProjectList.Count; i++)
+ {
+ var project = result.ProjectList[i];
+
+ var parser = new Monad.FLParser.ProjectParser(false);
+
+ try
+ {
+ using (var stream = File.OpenRead(project.FileName))
+ {
+ using (var reader = new BinaryReader(stream))
+ {
+ parser.Parse(reader);
+ }
+ }
+
+ // add only non-empty project paths
+ if (!string.IsNullOrWhiteSpace(parser.project.ProjectPath))
+ project.ProjectPath = parser.project.ProjectPath;
+ }
+ catch (Exception ex)
+ {
+ // it has read error, so it may have invalid tracks
+ project.HasLoadErrors = true;
+
+ // if there is project path were parsed, it's correct
+ if (!string.IsNullOrWhiteSpace(parser.project.ProjectPath))
+ project.ProjectPath = parser.project.ProjectPath;
+ }
+
+ // skip project where is no project path set
+ if (string.IsNullOrWhiteSpace(project.ProjectPath))
+ continue;
+
+ // try to fix project data path, if hard drives were mysteriously changed
+ if (!Directory.Exists(project.ProjectPath))
+ {
+ var projectLocation = Helpers.NormalizePath(Path.GetDirectoryName(project.FileName));
+ var projectDataLocation = Helpers.NormalizePath(project.ProjectPath);
+
+ // remove drive letter
+ if (string.Compare(projectDataLocation.Substring(1), projectLocation.Substring(1), StringComparison.InvariantCultureIgnoreCase) == 0)
+ {
+ project.ProjectPath = projectLocation;
+ }
+ else
+ {
+ // ask user if he want to use the project location as project data folder
+ var pathErrMsg = string.Format("Project folder '{0}' was not found for project {1}\n\nTry to use path {2} for it?",
+ project.ProjectPath, project.FileName, projectLocation);
+
+ var dlgResult = (DialogResult)this.Invoke((Func)(() => MessageBox.Show(this, pathErrMsg, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question)));
+
+ if (dlgResult == DialogResult.Yes)
+ project.ProjectPath = projectLocation;
+ else
+ project.PathError = true;
+ }
+ }
+
+ project.ProjectPath = Helpers.NormalizePath(project.ProjectPath);
+
+ // second we try search for WAV files in project folder
+ try {
+ foreach (string file in Directory.EnumerateFiles(project.ProjectPath, "*.wav", SearchOption.AllDirectories))
+ {
+ var fileInfo = new System.IO.FileInfo(file);
+
+ project.FolderWAVList.Add(new FileInfo {
+ FileName = file,
+ FileSize = fileInfo.Length,
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ project.PathError = true;
+ }
+
+ foreach (var chan in parser.project.Channels)
+ {
+ var chanData = chan.Data as Monad.FLParser.GeneratorData;
+
+ if (chanData != null && !string.IsNullOrWhiteSpace(chanData.SampleFileName))
+ {
+ var wavFilename = chanData.SampleFileName;
+
+ try
+ {
+ // try to fix file path, if hard drives were mysteriously changed
+ if (!File.Exists(wavFilename))
+ {
+ var wavLocation = Helpers.NormalizePath(Path.GetDirectoryName(chanData.SampleFileName));
+
+ if (string.Compare(wavLocation.Substring(1), project.ProjectPath.Substring(1), StringComparison.InvariantCultureIgnoreCase) == 0)
+ {
+ wavFilename = Path.Combine(project.ProjectPath, Path.GetFileName(wavFilename));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ project.FileError = true;
+ }
+
+ project.UsedWAVList.Add(wavFilename);
+ }
+ }
+
+ bgWorker.ReportProgress(Convert.ToInt32((float)i / (float)result.ProjectList.Count * 100.0f));
+ }
+
+ bgWorker.ReportProgress(100);
+
+ // store the result
+ e.Result = result;
+ }
+
+ private void bgWorker_OnComplete(object sender, RunWorkerCompletedEventArgs e)
+ {
+ GatheringResult = (GatheringResult)e.Result;
+
+ // for counting records size
+ var folderProjectGroups = GatheringResult.ProjectList.GroupBy(x => x.ProjectPath);
+
+ // store project groups
+ ProjectFolderGroups = folderProjectGroups.Select(x => new ProjectInfo {
+ FolderWAVList = x.First().FolderWAVList,
+ ProjectPath = x.First().ProjectPath,
+ HasLoadErrors = x.Any(p => p.HasLoadErrors),
+ FileError = x.Any(p => p.FileError),
+ PathError = x.Any(p => p.PathError),
+ ProjectFiles = x.Select(p => p.FileName).ToArray(),
+ UsedWAVList = x.SelectMany(p => p.UsedWAVList.Select(f => f)).ToList(),
+ }).Where(x => !string.IsNullOrWhiteSpace(x.ProjectPath)).ToArray();
+
+ // now complete the unused files list to proceed
+ foreach (var projectGroup in ProjectFolderGroups)
+ {
+ projectGroup.UnusedWAVList =
+ projectGroup.FolderWAVList.Where(folderFile =>
+ !projectGroup.UsedWAVList.Any(usedFile =>
+ string.Compare(Path.GetFileName(folderFile.FileName), Path.GetFileName(usedFile), StringComparison.InvariantCultureIgnoreCase) == 0
+ )
+ ).ToArray();
+ }
+
+ var totalRecordings = GatheringResult.ProjectList.Sum(x => x.FolderWAVList.Count);
+ var totalRecordingsSize = ProjectFolderGroups.Sum(x => x.FolderWAVList.Sum(r => r.FileSize));
+ var totalUnusedRecordings = ProjectFolderGroups.Sum(x => x.UnusedWAVList.Count());
+ var totalUnusedRecordingsSize = ProjectFolderGroups.Sum(x => x.UnusedWAVList.Sum(r => r.FileSize));
+
+ totalProjectsLabel.Text = string.Format("{0}", GatheringResult.ProjectList.Count);
+ totalRecLabel.Text = string.Format("{0}", totalRecordings);
+ totalRecSizeLabel.Text = string.Format("{0}", Helpers.BytesToString(totalRecordingsSize));
+ unusedRecLabel.Text = string.Format("{0}", totalUnusedRecordings);
+ unusedRecSizeLabel.Text = string.Format("{0}", Helpers.BytesToString(totalUnusedRecordingsSize));
+ }
+
+ private void doCleanupBtn_Click(object sender, EventArgs e)
+ {
+ progressBar.Value = 0;
+
+ delWorker.RunWorkerAsync();
+ }
+
+ private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
+ {
+ progressBar.Value = e.ProgressPercentage;
+ }
+
+ private void delWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
+ {
+ progressBar.Value = e.ProgressPercentage;
+ }
+
+ private void delWorker_DoWork(object sender, DoWorkEventArgs e)
+ {
+ if (ProjectFolderGroups == null)
+ {
+ MessageBox.Show(this, "You have to gather information before performing cleanup", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+
+ // this is made for progress bar
+ var delFilesList = new List();
+
+ foreach (var projectGroup in ProjectFolderGroups)
+ {
+ if (!ignoreErrorsCheck.Checked)
+ {
+ if (projectGroup.PathError)
+ {
+ var pathErrMsg = string.Format("Project folder '{0}' was not found in next projects:\n{1}", projectGroup.ProjectPath, string.Join("\n", projectGroup.ProjectFiles));
+
+ this.Invoke((Func)(() => MessageBox.Show(this, pathErrMsg, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)));
+ }
+
+ if (projectGroup.HasLoadErrors || projectGroup.FileError)
+ {
+ var errorDesc = (projectGroup.HasLoadErrors ? "FLP Problem" : "") + (projectGroup.FileError ? "Missing file" : "");
+
+ var message = string.Format("Projects in '{0}' had errors while gathering ({1}).\n\nDo you want to skip them?", projectGroup.ProjectPath, errorDesc);
+
+
+ var dialogResult = (DialogResult)this.Invoke((Func)(() => MessageBox.Show(this, message, "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)));
+
+ if (dialogResult == DialogResult.Yes)
+ continue;
+
+ if (dialogResult == DialogResult.Cancel)
+ {
+ this.Invoke((Func)(() => MessageBox.Show(this, "Operation cancelled", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information)));
+ break;
+ }
+ }
+ }
+
+ delFilesList.AddRange(projectGroup.UnusedWAVList);
+ }
+
+ for (int i = 0; i < delFilesList.Count; i++)
+ {
+ var wavInfo = delFilesList[i];
+
+ // send files to recycle bin first
+ Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(wavInfo.FileName, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin);
+
+ delWorker.ReportProgress(Convert.ToInt32((float)i / (float)delFilesList.Count * 100.0f));
+ }
+
+ delWorker.ReportProgress(100);
+
+ this.Invoke((Func)(() => MessageBox.Show(this, "Job completed. You still can find your files in recycle bin.", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information)));
+ }
+ }
+}
diff --git a/FLRecordingCleaner/Form1.resx b/FLRecordingCleaner/Form1.resx
new file mode 100644
index 0000000..1c811b5
--- /dev/null
+++ b/FLRecordingCleaner/Form1.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 122, 17
+
+
+ 246, 17
+
+
+ 352, 17
+
+
\ No newline at end of file
diff --git a/FLRecordingCleaner/GatheringResult.cs b/FLRecordingCleaner/GatheringResult.cs
new file mode 100644
index 0000000..d2f5226
--- /dev/null
+++ b/FLRecordingCleaner/GatheringResult.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FLRecordingCleaner
+{
+ public class FileInfo
+ {
+ public string FileName { get; set; }
+ public long FileSize { get; set; }
+
+ // for debugging purposes
+ public override string ToString()
+ {
+ return FileName;
+ }
+ }
+
+ public class ProjectInfo
+ {
+ public ProjectInfo()
+ {
+ FolderWAVList = new List();
+ UsedWAVList = new List();
+
+ HasLoadErrors = false;
+ PathError = false;
+ FileError = false;
+ }
+
+ public string FileName { get; set; }
+ public string ProjectPath { get; set; }
+ public bool HasLoadErrors { get; set; }
+
+ public bool PathError { get; set; }
+ public bool FileError { get; set; }
+
+ public List FolderWAVList { get; set; }
+ public List UsedWAVList { get; set; }
+
+ public IEnumerable ProjectFiles { get; set; }
+ public IEnumerable UnusedWAVList { get; set; }
+
+ // for debugging purposes
+ public override string ToString()
+ {
+ return string.IsNullOrEmpty(FileName) ? ProjectPath : FileName;
+ }
+ }
+
+ public class GatheringResult
+ {
+ public GatheringResult()
+ {
+ ProjectList = new List();
+ }
+
+ public List ProjectList { get; set; }
+ }
+}
diff --git a/FLRecordingCleaner/Helpers.cs b/FLRecordingCleaner/Helpers.cs
new file mode 100644
index 0000000..bfb1a7e
--- /dev/null
+++ b/FLRecordingCleaner/Helpers.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FLRecordingCleaner
+{
+ class Helpers
+ {
+ public static string NormalizePath(string path)
+ {
+ return Path.GetFullPath(new Uri(path).LocalPath)
+ .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ }
+
+ public static String BytesToString(long byteCount)
+ {
+ string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
+ if (byteCount == 0)
+ return "0 " + suf[0];
+ long bytes = Math.Abs(byteCount);
+ int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
+ double num = Math.Round(bytes / Math.Pow(1024, place), 1);
+ return string.Format("{0} {1}", (Math.Sign(byteCount) * num),suf[place]);
+ }
+ }
+}
diff --git a/FLRecordingCleaner/Program.cs b/FLRecordingCleaner/Program.cs
new file mode 100644
index 0000000..a834f9f
--- /dev/null
+++ b/FLRecordingCleaner/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace FLRecordingCleaner
+{
+ static class Program
+ {
+ ///
+ /// Главная точка входа для приложения.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/FLRecordingCleaner/Properties/AssemblyInfo.cs b/FLRecordingCleaner/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..06fd856
--- /dev/null
+++ b/FLRecordingCleaner/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Общие сведения об этой сборке предоставляются следующим набором
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("FLRecordingCleaner")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FLRecordingCleaner")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("20c0846e-6caa-4443-b6e5-6f1511eaa557")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер сборки
+// Редакция
+//
+// Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/FLRecordingCleaner/Properties/Resources.Designer.cs b/FLRecordingCleaner/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..e91a5af
--- /dev/null
+++ b/FLRecordingCleaner/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// Этот код создан программным средством.
+// Версия среды выполнения: 4.0.30319.42000
+//
+// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
+// код создан повторно.
+//
+//------------------------------------------------------------------------------
+
+namespace FLRecordingCleaner.Properties
+{
+
+
+ ///
+ /// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
+ ///
+ // Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
+ // класс с помощью таких средств, как ResGen или Visual Studio.
+ // Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
+ // с параметром /str или заново постройте свой VS-проект.
+ [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()
+ {
+ }
+
+ ///
+ /// Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FLRecordingCleaner.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Переопределяет свойство CurrentUICulture текущего потока для всех
+ /// подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/FLRecordingCleaner/Properties/Resources.resx b/FLRecordingCleaner/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/FLRecordingCleaner/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/FLRecordingCleaner/Properties/Settings.Designer.cs b/FLRecordingCleaner/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..72a5f1c
--- /dev/null
+++ b/FLRecordingCleaner/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+
+namespace FLRecordingCleaner.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/FLRecordingCleaner/Properties/Settings.settings b/FLRecordingCleaner/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/FLRecordingCleaner/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..27f81a1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+FL Studio recording cleanup utility for people who has tons of UNUSED recordings eating disk storage.
+
+Using modified Monad.FLParser library, you can find it at https://github.com/SoapyMan/FLParser
+
+---
+
+Intuitively collects your project data by their folders, finds unused sample files and deletes them to recycle bin. Nothing other fancy!
\ No newline at end of file