This repository has been archived on 2025-01-01. You can view files and clone it, but cannot push or open issues or pull requests.
ShiftOS_TheReturn/ShiftOS.Frontend/Apps/FileSkimmer.cs
2017-08-05 17:01:15 -04:00

434 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShiftOS.Engine;
using ShiftOS.Frontend.GraphicsSubsystem;
using ShiftOS.Frontend.GUI;
using static ShiftOS.Objects.ShiftFS.Utils;
namespace ShiftOS.Frontend.Apps
{
[WinOpen("fileskimmer")]
[Launcher("File Skimmer", false, null, "System")]
[DefaultTitle("File Skimmer")]
public class FileSkimmer : GUI.Control, IShiftOSWindow
{
private string _currentdirectory = "0:";
private const string SD_SYSTEM = "__system";
private GUI.ListView _fList = null;
private GUI.TextControl _currentdirtext = null;
private GUI.Button _openFile = null;
private GUI.TextControl _fileFilter = null;
private GUI.TextControl _filePrompt = null;
private GUI.TextInput _fileBox = null;
public bool IsDialog = false;
public Action<string> DialogCallback = null;
public string[] FileFilters = new string[] { "" };
public FileOpenerStyle DialogMode = FileOpenerStyle.Open;
public int SelectedFilter = 0;
public FileSkimmer()
{
_fileBox = new GUI.TextInput();
_filePrompt = new TextControl();
_fileFilter = new TextControl();
_openFile = new Button();
AddControl(_openFile);
AddControl(_fileBox);
AddControl(_filePrompt);
AddControl(_fileFilter);
_openFile.AutoSize = true;
_fileFilter.AutoSize = true;
_filePrompt.AutoSize = true;
Width = 720;
Height = 480;
_fList = new GUI.ListView();
//TODO: keyboard support in listviews
/*
_fList.KeyEvent += (e) =>
{
if(e.Key == Microsoft.Xna.Framework.Input.Keys.Enter)
{
Navigate(_fList.SelectedItem.ToString());
}
};*/
_fList.DoubleClick += () =>
{
try
{
Navigate(_fList.SelectedItem.Tag);
}
catch { }
};
AddControl(_fList);
_currentdirtext = new GUI.TextControl();
_currentdirtext.AutoSize = true;
AddControl(_currentdirtext);
ResetList();
}
public void OnLoad()
{
if (Hacking.CurrentHackable != null)
{
if (Hacking.CurrentHackable.VectorsUnlocked.Contains(Objects.SystemType.FileServer))
{
if (Mounts.Count > 2)
{
Mounts.RemoveAt(2);
}
var dir = new Objects.ShiftFS.Directory();
dir.Name = $"{Hacking.CurrentHackable.Data.SystemName} (ftp)";
Mounts.Add(dir);
foreach (var loot in Hacking.CurrentHackable.ServerFTPLoot)
{
if(!FileExists("2:/" + loot.LootName))
{
var bytes = Hacking.GetLootBytes(loot.PointTo);
WriteAllBytes($"2:/{loot.LootName}", bytes);
}
}
}
}
Width = 720;
Height = 480;
_fList = new GUI.ListView();
//TODO: keyboard support in listviews
/*
_fList.KeyEvent += (e) =>
{
if(e.Key == Microsoft.Xna.Framework.Input.Keys.Enter)
{
Navigate(_fList.SelectedItem.ToString());
}
};*/
_fList.Click += () =>
{
if(_fList.SelectedItem != null)
{
if(_fList.SelectedItem.Tag != "__up")
{
if(FileExists(_fList.SelectedItem.Tag))
{
_fileBox.Text = _fList.SelectedItem.Text;
}
}
}
};
_fList.DoubleClick += () =>
{
try
{
Navigate(_fList.SelectedItem.Tag);
}
catch { }
};
_fileBox.KeyEvent += (key) =>
{
if (key.Key == Microsoft.Xna.Framework.Input.Keys.Enter)
{
HandleFileSelect();
}
};
_openFile.Click += () =>
{
HandleFileSelect();
};
AddControl(_fList);
_currentdirtext = new GUI.TextControl();
_currentdirtext.AutoSize = true;
AddControl(_currentdirtext);
ResetList();
}
public void HandleFileSelect(bool quiet = false)
{
string fname = _fileBox.Text;
string filter = FileFilters[SelectedFilter];
if (filter != "Directory")
if (!fname.EndsWith(filter))
fname += filter;
string path = _currentdirectory + "/" + fname;
bool exists = false;
if (filter == "Directory")
exists = DirectoryExists(path);
else
exists = FileExists(path);
if (exists)
{
if (DialogMode == FileOpenerStyle.Open || quiet)
{
DialogCallback?.Invoke(path);
AppearanceManager.Close(this);
}
else
{
Engine.Infobox.PromptYesNo("Overwrite file?", "The file you chose already exists on disk. Would you like to overwrite it?", (answer) =>
{
if (answer)
{
DialogCallback?.Invoke(path);
AppearanceManager.Close(this);
}
});
}
}
else
{
if (DialogMode == FileOpenerStyle.Open)
{
if (quiet == false)
Engine.Infobox.Show("File not found.", "The requested file path could not be found on disk.");
}
else
{
DialogCallback?.Invoke(path);
AppearanceManager.Close(this);
}
}
}
public void Navigate(string path)
{
if(path == "__up")
{
if (_currentdirectory == SD_SYSTEM)
throw new NaughtyDeveloperException("Someone tried to make it so you can go \"up one directory\" in the mounts list.");
if (_currentdirectory.EndsWith(":"))
{
_currentdirectory = SD_SYSTEM;
ResetList();
return;
}
else
{
int slashlast = _currentdirectory.LastIndexOf("/");
int len = _currentdirectory.Length - slashlast;
_currentdirectory = _currentdirectory.Remove(slashlast, len);
ResetList();
return;
}
}
if (DirectoryExists(path))
{
_currentdirectory = path;
ResetList();
}
else if (FileExists(path))
{
if (IsDialog)
{
bool quiet = DialogMode == FileOpenerStyle.Open;
this.HandleFileSelect(quiet);
}
else
{
if (!FileSkimmerBackend.OpenFile(path))
{
Engine.Infobox.Show("File Skimmer can't open this file!", "File Skimmer couldn't find a program that can open a file of this type. Please install a program that can handle this file and try again.");
}
}
}
}
public Texture2D ToTexture2D(System.Drawing.Image img)
{
if (img == null)
return null;
using(var bmp = new System.Drawing.Bitmap(img))
{
var lck = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var arr = new byte[Math.Abs(lck.Stride) * lck.Height];
Marshal.Copy(lck.Scan0, arr, 0, arr.Length);
for(int i = 0; i < arr.Length; i += 4)
{
byte r = arr[i];
byte b = arr[i + 2];
arr[i] = b;
arr[i + 2] = r;
}
var tex2 = new Texture2D(UIManager.GraphicsDevice, bmp.Width, bmp.Height);
tex2.SetData<byte>(arr);
bmp.UnlockBits(lck);
return tex2;
}
}
public void OnSkinLoad()
{
foreach(var name in Enum.GetNames(typeof(FileType)))
{
FileType ftype = (FileType)Enum.Parse(typeof(FileType), name);
var img = ToTexture2D(GetImage(ftype));
_fList.SetImage(name, img);
}
_currentdirtext.Font = SkinEngine.LoadedSkin.Header3Font;
}
public System.Drawing.Image GetImage(FileType type)
{
switch (type)
{
case FileType.UpOne:
return Properties.Resources.fileicon5;
case FileType.Mount:
case FileType.Directory:
return Properties.Resources.fileicon0;
case FileType.Executable:
case FileType.Lua:
case FileType.Python:
return Properties.Resources.fileiconsaa;
case FileType.Image:
return Properties.Resources.fileicon3;
case FileType.Skin:
return Properties.Resources.fileicon10;
case FileType.TextFile:
return Properties.Resources.fileicon2;
case FileType.CommandFormat:
return Properties.Resources.fileiconcf;
default:
return Properties.Resources.fileicon1;
}
}
public bool OnUnload()
{
return true;
}
public void OnUpgrade()
{
}
public void ResetList()
{
if (_currentdirectory == SD_SYSTEM)
_currentdirtext.Text = "My storage drives";
else
_currentdirtext.Text = _currentdirectory;
_fList.ClearItems();
if (_currentdirectory != SD_SYSTEM)
_fList.AddItem(new GUI.ListViewItem
{
Text = "Up one...",
Tag = "__up",
ImageKey = FileType.UpOne.ToString()
});
if(_currentdirectory == SD_SYSTEM)
{
foreach(var mount in Mounts)
{
string mountpath = $"{Mounts.IndexOf(mount)}:";
string name = $"{mount.Name} ({mountpath})";
_fList.AddItem(new ListViewItem
{
Text = name,
Tag = mountpath,
ImageKey = FileType.Mount.ToString()
});
}
}
else
{
foreach(var dir in GetDirectories(_currentdirectory))
{
var dinf = GetDirectoryInfo(dir);
_fList.AddItem(new ListViewItem
{
Text = dinf.Name,
Tag = dir,
ImageKey = FileType.Directory.ToString()
});
}
foreach (var dir in GetFiles(_currentdirectory))
{
var dinf = GetFileInfo(dir);
if (dinf.Name.EndsWith(FileFilters[SelectedFilter]))
{
var ext = FileSkimmerBackend.GetFileType(dir);
_fList.AddItem(new ListViewItem
{
Text = dinf.Name,
Tag = dir,
ImageKey = ext.ToString()
});
}
}
}
InvalidateTopLevel();
}
private const int _fileselectboxheight = 50;
protected override void OnLayout(GameTime gameTime)
{
int listbottom = Height - _currentdirtext.Height;
if (IsDialog)
listbottom -= _fileselectboxheight;
_currentdirtext.Layout(gameTime);
_fList.X = 0;
_fList.Y = 0;
_fList.Width = Width;
_fList.Height = listbottom;
_currentdirtext.X = (Width - _currentdirtext.Width) / 2;
_currentdirtext.Y = _fList.Height;
if (IsDialog)
{
int _fileselectstart = Height - _fileselectboxheight;
_openFile.Text = DialogMode.ToString();
_openFile.Visible = true;
_openFile.X = (Width - _openFile.Width) - 10;
_openFile.Y = _fileselectstart + ((_fileselectboxheight - _openFile.Height) / 2);
_filePrompt.AutoSize = true;
_filePrompt.Text = $"{DialogMode} file: ";
_filePrompt.Font = SkinEngine.LoadedSkin.MainFont;
_filePrompt.Layout(gameTime);
_filePrompt.X = 10;
_filePrompt.Y = _fileselectstart + ((_fileselectboxheight - _filePrompt.Height) / 2);
_filePrompt.Visible = true;
_fileFilter.AutoSize = true;
_fileFilter.Visible = true;
_fileFilter.Text = FileFilters[SelectedFilter];
_fileFilter.Font = SkinEngine.LoadedSkin.MainFont;
_fileFilter.Layout(gameTime);
_fileFilter.X = _openFile.X - _fileFilter.Width - 10;
_fileFilter.Y = _fileselectstart + ((_fileselectboxheight - _fileFilter.Height) / 2);
_fileBox.X = _filePrompt.X + _filePrompt.Width + 10;
_fileBox.Width = _fileFilter.X - _fileBox.X;
_fileBox.Height = 24;
_fileBox.Y = _fileselectstart + ((_fileselectboxheight - _fileBox.Height) / 2);
_fileBox.Visible = true;
}
}
}
}