using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utils;
using System.Windows.Input;
using WpfApplication1.Model;
using MVVM;
using System.Collections.ObjectModel;
using System.Collections;
using System.IO;
namespace WpfApplication1.ViewModel
{
// All commands here, except
// Note: Not very "DRY". Use MVVM framework to bind to functions by convention
// Note: Some System.IO used here, could be moved to model
// Note: Using cosale operator "??" saves some characters, but formatting not standard/ a little awkward
public partial class MainVm
{
private int GetIndexFolderPlanes(string path)
{
int indexInPlanes = -1;
for (int i = 0; i <= FolderPlanes.Count - 1; i++)
{
if (FolderPlanes[i].FullPathName == path) { indexInPlanes = i; }
}
return indexInPlanes;
}
// For now SelectedPath common to all trees
// to do? set OnClickCommand as attribute to NavTreeView and TabbedNavTrees
RelayCommand selectedPathFromTreeCommand;
public ICommand SelectedPathFromTreeCommand
{
get
{
return selectedPathFromTreeCommand ??
(selectedPathFromTreeCommand =
new RelayCommand(x => SelectedPath = (x as string) ));
}
}
RelayCommand folderPlaneItemDoubleClickCommand;
public ICommand FolderPlaneItemDoubleClickCommand
{
get
{
return folderPlaneItemDoubleClickCommand ??
(folderPlaneItemDoubleClickCommand =
new RelayCommand(x => OnFolderDownClick(x), x => true));
}
}
// In case of doubleclick on FolderItem we choose/want to change current selected folder
// We do not know the source of the Set/change event in SelectedPath
// For now we use a boolean for this, however I am not sure if this completely (thread???) safe
private bool UseCurrentPlane = false;
public void OnFolderDownClick(object p)
{
if (p == null) return;
string path = (p as FolderPlaneItem).FullPathName;
bool isDrive = FolderPlaneUtils.IsDrive(path);
bool isFolder = FolderPlaneUtils.IsFolder(path);
if (isDrive || isFolder)
{
UseCurrentPlane = true;
try
{
SelectedPath = path;
}
finally { UseCurrentPlane = false; }
}
else
{
// Execute
try
{
// Console.WriteLine("Execute: "+ path);
System.Diagnostics.Process.Start(path);
}
catch
{ }
}
}
RelayCommand closeTabCommand;
public ICommand CloseTabCommand
{
get { return closeTabCommand ?? (closeTabCommand = new RelayCommand(CloseTab, x => FolderPlanes.Count > 0)); }
}
//public int teller = 0;
public void CloseTab(object p)
{
//teller++;
//Console.WriteLine("*********** OnCloseCommand called ************" + teller.ToString());
if (SelectedFolderPlane != null)
{
int i = GetIndexFolderPlanes(SelectedFolderPlane.FullPathName);
if (i != -1)
{
FolderPlanes.RemoveAt(i);
if (FolderPlanes.Count != 0)
{
i = i - 1;
if (i < 0) i = i + 1;
SelectedPath = FolderPlanes[i].FullPathName;
}
else
{
SelectedFolderPlane = null;
SelectedPath = "";
}
}
}
}
RelayCommand folderUpCommand;
public ICommand FolderUpCommand
{
get { return folderUpCommand ?? (folderUpCommand = new RelayCommand(FolderUp, x => FolderPlanes.Count > 0)); }
}
public void FolderUp(object p)
{
if (SelectedFolderPlane != null)
{
string path = FolderPlaneUtils.FolderUp(SelectedFolderPlane.FullPathName);
UseCurrentPlane = true;
try
{
SelectedPath = path;
}
finally { UseCurrentPlane = false; }
}
}
// Note: we now use drag and drop for ordering Folders and SavedTabs
//RelayCommand tabToLeftCommand;
//public ICommand TabToLeftCommand
//{
// get { return tabToLeftCommand ?? (tabToLeftCommand = new RelayCommand(TabToLeft)); }
//}
//public void TabToLeft(object p)
//{
// int index = GetIndexFolderPlanes(selectedPath);
// if (index > 0)
// {
// FolderPlanes.Move(index, index - 1);
// }
//}
//RelayCommand tabToRightCommand;
//public ICommand TabToRightCommand
//{
// get { return tabToRightCommand ?? (tabToRightCommand = new RelayCommand(TabToRight)); }
//}
//public void TabToRight(object p)
//{
// int index = GetIndexFolderPlanes(selectedPath);
// if ((index != -1) && (index < FolderPlanes.Count - 1))
// {
// FolderPlanes.Move(index, index + 1);
// }
//}
RelayCommand toggleOpenPopup1Command;
public ICommand ToggleOpenPopup1Command
{
get { return toggleOpenPopup1Command ?? (toggleOpenPopup1Command = new RelayCommand(x => Popup1IsOpen = !Popup1IsOpen)); }
}
RelayCommand toggleOpenPopup2Command;
public ICommand ToggleOpenPopup2Command
{
get { return toggleOpenPopup2Command ?? (toggleOpenPopup2Command = new RelayCommand(x => Popup2IsOpen = !Popup2IsOpen)); }
}
RelayCommand toggleOpenPopup3Command;
public ICommand ToggleOpenPopup3Command
{
get
{
return toggleOpenPopup3Command ??
(toggleOpenPopup3Command = new RelayCommand
(x => Popup3IsOpen = (!Popup3IsOpen && (SelectedFolderItems.Count == 1)),
x => SelectedFolderItem != ""));
}
}
RelayCommand addSavedTabsCommand;
public ICommand AddSavedTabsCommand
{
get { return addSavedTabsCommand ?? (addSavedTabsCommand = new RelayCommand(AddSavedTabs)); }
}
public void AddSavedTabs(object p)
{
string name = (p as String);
var saveTheseTabs = new SavedFolderTabsItem() { };
saveTheseTabs.FriendlyName = name;
saveTheseTabs.TabFullPathName = new System.Collections.ObjectModel.Collection<string>() { };
for (int i = 0; i <= FolderPlanes.Count - 1; i++)
{
saveTheseTabs.TabFullPathName.Add(FolderPlanes[i].FullPathName);
}
SavedFolderTabs.Add(saveTheseTabs);
// to do: .Add does not set and save ???
SavedFolderTabsUtils.Save(savedFolderTabs);
Popup2IsOpen = !Popup2IsOpen;
}
RelayCommand deleteSavedTabsCommand;
public ICommand DeleteSavedTabsCommand
{
get { return deleteSavedTabsCommand ?? (deleteSavedTabsCommand = new RelayCommand(DeleteSavedTabs)); }
}
public void DeleteSavedTabs(object p)
{
int index = (int)p;
if (index != -1) { SavedFolderTabs.RemoveAt(index); }
SavedFolderTabsUtils.Save(savedFolderTabs);
Popup1IsOpen = !Popup1IsOpen;
}
RelayCommand closeAllFolderTabsCommand;
public ICommand CloseAllFolderTabsCommand
{
get
{
return closeAllFolderTabsCommand ??
(
closeAllFolderTabsCommand = new RelayCommand(x =>
{
SelectedPath = "";
SelectedFolderPlane = null;
FolderPlanes.Clear();
SelectedIndexSavedFolderTabs = -1;
})
);
}
}
RelayCommand selectedItemsChangedCommand;
public ICommand SelectedItemsChangedCommand
{
get { return selectedItemsChangedCommand ?? (selectedItemsChangedCommand = new RelayCommand(SelectedItemsChanged, x => true)); }
}
public void SelectedItemsChanged(object p)
{
SelectedFolderItems.Clear();
IList selectedRecords = p as IList;
foreach (FolderPlaneItem item in selectedRecords)
{
SelectedFolderItems.Add(item.FullPathName);
}
if (SelectedFolderItems.Count == 1) { SelectedFolderItem = Path.GetFileName(SelectedFolderItems[0]); } else { SelectedFolderItem = ""; }
}
RelayCommand snapShotSelectedCommand;
public ICommand SnapShotSelectedCommand
{
get
{
return snapShotSelectedCommand ??
(snapShotSelectedCommand = new RelayCommand(SnapShotSelected, x => SelectedFolderItems.Count != 0));
}
}
public void SnapShotSelected(object p)
{
SnappedSelectedItems.Clear();
foreach (string item in SelectedFolderItems)
{
SnappedSelectedItems.Add(item);
}
}
RelayCommand copySnapShotCommand;
public ICommand CopySnapShotCommand
{
get
{
return copySnapShotCommand ??
(copySnapShotCommand = new RelayCommand(CopySnapShot, x => SnappedSelectedItems.Count != 0));
}
}
public void CopySnapShot(object p) { CopyMoveSnapShot(p); }
RelayCommand moveSnapShotCommand;
public ICommand MoveSnapShotCommand
{
get
{
return moveSnapShotCommand ??
(moveSnapShotCommand = new RelayCommand(MoveSnapShot, x => SnappedSelectedItems.Count != 0));
}
}
public void MoveSnapShot(object p) { CopyMoveSnapShot(p, false); }
RelayCommand copySnapShotAddDateCommand;
public ICommand CopySnapShotAddDateCommand
{
get
{
return copySnapShotAddDateCommand ??
(copySnapShotAddDateCommand = new RelayCommand(CopySnapShotAddDate, x => SnappedSelectedItems.Count == 1));
}
}
public void CopySnapShotAddDate(object p) { CopyMoveSnapShot("Date"); }
// http://stackoverflow.com/questions/627504/what-is-the-best-way-to-recursively-copy-contents-in-c
// Note filemanagement not ready. No feedback. UI hangs on large files, must in other process (Backgroundworker?)
// to do: to model
public void CopyDirAndChildren(DirectoryInfo source, DirectoryInfo target)
{
// Saw once error during heavy copying, not reproducable, new folder/copy to .exe folder
if ((target.Parent == null) || (target.Parent.FullName == "")) return;
// Deny action if target is a (indirect) child of target, recursive loops
// Test target startswith sourcefullname
// can be longer folder/file name, so extra test on common parent
if ((target.FullName.StartsWith(source.FullName)) && (target.Parent.FullName != source.Parent.FullName)) return;
try
{
//check if the target directory exists
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
//copy all the files into the new directory
foreach (FileInfo fi in source.GetFiles())
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
//copy all the sub directories using recursion
foreach (DirectoryInfo diSourceDir in source.GetDirectories())
{
DirectoryInfo nextTargetDir = target.CreateSubdirectory(diSourceDir.Name);
CopyDirAndChildren(diSourceDir, nextTargetDir);
}
//success here
}
catch //(IOException ie)
{
//handle it here
}
}
public void CopyMoveSnapShot(object p, bool CopyNotMove = true)
{
// Ctrl+d pressed and 1 item in snapshot
// to do: make a extra command for it, work with SelectedFolderItems (items=1)
string extra = "";
if ((p as string) == "Date")
{
if (SnappedSelectedItems.Count != 1) return;
DateTime time = DateTime.Now;
string format = " yyyy-M-d HH.mm -)";
extra = time.ToString(format);
}
// Saw once error during heavy copying, not reproducable, new folder/copy to .exe folder
if ((SelectedFolderPlane == null) || (SelectedFolderPlane.FullPathName == "") || (SelectedPath == "") ) return;
// Copy SelectedFolderItems to SelectedFolderPlane.FullName
string targetPath = SelectedFolderPlane.FullPathName;
if (!System.IO.Directory.Exists(targetPath)) return;
string sourcePath = "";
string fileName = "";
foreach (string fullPathName in SnappedSelectedItems)
{
sourcePath = Path.GetDirectoryName(fullPathName);
fileName = Path.GetFileName(fullPathName);
if (System.IO.Directory.Exists(fullPathName))
{
// construct targetItem, if exists try -copy ()
string targetItem = Path.Combine(targetPath, fileName + extra);
int i = 0;
string targetItemCopy = targetItem + " - copy(";
while (System.IO.Directory.Exists(targetItem) && (i < 100))
{
targetItem = targetItemCopy + i.ToString() + ")";
i++;
}
if (CopyNotMove)
{
CopyDirAndChildren(new DirectoryInfo(fullPathName), new DirectoryInfo(targetItem));
}
else
{
Directory.Move(fullPathName, targetItem);
}
}
else if (System.IO.File.Exists(fullPathName))
{
// construct targetItem, if exists try -copy ()
string targetItem = Path.Combine(targetPath, fileName);
int i = 0;
string targetItemCopy = Path.Combine(targetPath, Path.GetFileNameWithoutExtension(fileName)) + " - copy(";
string targetExt = Path.GetExtension(fileName);
while (System.IO.File.Exists(targetItem) && (i < 100))
{
targetItem = targetItemCopy + i.ToString() + ")" + targetExt;
i++;
}
// error can happen
File.Copy(fullPathName, targetItem, true);
if (!CopyNotMove) File.Delete(fullPathName);
}
}
if (!CopyNotMove) SnappedSelectedItems.Clear();
RefreshFolderPlanesAndSelectedNavTree(null);
}
RelayCommand newFolderCommand;
public ICommand NewFolderCommand
{
// test CanExecute not correct hack, to do?
get { return newFolderCommand ?? (newFolderCommand = new RelayCommand(NewFolder, x => selectedFolderPlane.FullPathName != null)); }
}
public void NewFolder(object p)
{
// Saw once error during heavy copying, not yet reproducable, new folder/copy to .exe folder
if ((SelectedFolderPlane == null) || (SelectedFolderPlane.FullPathName=="") || (SelectedPath=="")) return;
string targetPath = SelectedFolderPlane.FullPathName;
if (!System.IO.Directory.Exists(targetPath)) return;
string newPath = System.IO.Path.Combine(targetPath, "NewFolder");
int i = 0;
while ((System.IO.Directory.Exists(newPath)) && (i < 100))
{
i++;
newPath = System.IO.Path.Combine(targetPath, "NewFolder(" + i.ToString() + ")");
}
System.IO.Directory.CreateDirectory(newPath);
RefreshFolderPlanesAndSelectedNavTree(null);
}
RelayCommand renameCommand;
public ICommand RenameCommand
{
get { return renameCommand ?? (renameCommand = new RelayCommand(x => Rename(x))); }
}
public void Rename(object p)
{
// Rename single selected folder or file
if (SelectedFolderItems.Count != 1)
{
Popup3IsOpen = false;
return;
}
string newname = Path.Combine(selectedFolderPlane.FullPathName, (p as String));
string oldname = (SelectedFolderItems[0]);
if (File.Exists(oldname) && !File.Exists(newname))
{
File.Copy(oldname, newname);
File.Delete(oldname);
}
if (Directory.Exists(oldname) && !Directory.Exists(newname))
{
Directory.Move(oldname, newname);
}
RefreshFolderPlanesAndSelectedNavTree(null);
Popup3IsOpen = false;
}
// Deletion from SelectedFolderItems. Alternative choice: use snapshot and delete SnappedSelectedItems //
RelayCommand deleteSelectedCommand;
public ICommand DeleteSelectedCommand
{
get
{
return deleteSelectedCommand ??
(deleteSelectedCommand = new RelayCommand(x => DeleteSelected(x), x => SelectedFolderItems.Count != 0));
}
}
public void DeleteSelected(object p)
{
if (selectedFolderItems == null) return;
if (selectedFolderItems.Count == 0) return;
string str;
// to do: test if folder can be deleted, send notification if not
for (int i = 0; i <= SelectedFolderItems.Count - 1; i++)
{
str = SelectedFolderItems[i];
try
{
if (System.IO.Directory.Exists(str))
{
Directory.Delete(str, true);
}
else if (System.IO.File.Exists(str))
{
File.Delete(str);
}
}
catch
{
// if no permissions we fail and continue
Console.WriteLine(" Failed to delete: " + str);
}
}
// to do: refresh all FolderPlanes
RefreshFolderPlanesAndSelectedNavTree(null);
}
RelayCommand refreshFolderPlanesCommand;
public ICommand RefreshFolderPlanesCommand
{
get { return refreshFolderPlanesCommand ?? (refreshFolderPlanesCommand = new RelayCommand(RefreshFolderPlanesAndSelectedNavTree)); }
}
public void RefreshFolderPlanesAndSelectedNavTree(object p)
{
SelectedFolderPlane.RefreshFolderPlane();
// In RefreshFolderPlane Directory.Exists(FullPathName) is checked. If false FullPathName set to ""
// When a SelectedFolderPlane is removed, another existing SelectedFolderPlane is chosen
for (int i = FolderPlanes.Count - 1; i >= 0; i--)
{
folderPlanes[i].RefreshFolderPlane();
if (folderPlanes[i].FullPathName == "")
{
var item = folderPlanes[i];
folderPlanes.Remove(item);
}
}
// Commented Code for testing, you can see here what folders are expanded when pressing RefreshButton
// List<string> SnapShot = TreeUtils.TakeSnapshot(TabbedNavTrees.SelectedNavTree.RootNode);
TabbedNavTrees.SelectedNavTree.RebuildTree();
// When no selectedFolderPlane is selected FullPathName is null
SelectedPath= SelectedFolderPlane.FullPathName ?? "";
}
}
}