#region Disclaimer / License
// Copyright (C) 2010, Jackie Ng
// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Aga.Controls.Tree;
using OSGeo.MapGuide.MaestroAPI.Services;
using OSGeo.MapGuide.MaestroAPI;
using OSGeo.MapGuide.ObjectModels.Common;
using System.Security.AccessControl;
using OSGeo.MapGuide.MaestroAPI.Resource;
using Maestro.Editors.Common;
namespace Maestro.Editors.Generic
{
///
/// A generic dialog for selecting folders or resource documents
///
public partial class ResourcePicker : Form
{
private ResourceTypes[] _resTypes;
private ResourcePicker()
{
InitializeComponent();
_resTypes = new ResourceTypes[]
{
ResourceTypes.ApplicationDefinition,
ResourceTypes.DrawingSource,
ResourceTypes.FeatureSource,
ResourceTypes.Folder,
ResourceTypes.LayerDefinition,
ResourceTypes.LoadProcedure,
ResourceTypes.MapDefinition,
ResourceTypes.PrintLayout,
ResourceTypes.SymbolDefinition,
ResourceTypes.SymbolLibrary,
ResourceTypes.WebLayout,
ResourceTypes.WatermarkDefinition
};
cmbResourceFilter.DataSource = _resTypes;
RepositoryIcons.PopulateImageList(resImageList);
RepositoryIcons.PopulateImageList(folderImageList);
}
private IResourceService _resSvc;
private bool _resourceMode = false;
///
/// Constructs a new instance. Use this overload to select any resource type. If only
/// folder selection is desired, set to true before
/// showing the dialog
///
/// The res SVC.
/// The mode.
public ResourcePicker(IResourceService resSvc, ResourcePickerMode mode)
: this()
{
_resSvc = resSvc;
repoView.Init(resSvc, true, false);
repoView.ItemSelected += OnFolderSelected;
this.UseFilter = true;
this.Mode = mode;
SetStartingPoint(LastSelectedFolder.FolderId);
}
void OnFolderSelected(object sender, EventArgs e)
{
UpdateDocumentList();
}
///
/// Sets the starting point.
///
/// The folder id.
/// If the specified folder does not exist, it will fallback to Library://
public void SetStartingPoint(string folderId)
{
if (string.IsNullOrEmpty(folderId))
return;
if (!ResourceIdentifier.IsFolderResource(folderId))
throw new ArgumentException(string.Format(Strings.NotAFolder, folderId));
// Library:// will *always* exist, so fallback to this if given folder doesn't check out
if (!_resSvc.ResourceExists(folderId))
folderId = StringConstants.RootIdentifier;
this.ActiveControl = repoView;
repoView.NavigateTo(folderId);
this.SelectedFolder = folderId;
//HACK: Navigating to the specified folder takes away the focus to the
//name field
this.ActiveControl = txtName;
}
///
/// Gets the selected folder.
///
public string SelectedFolder { get; private set; }
private ResourcePickerMode _mode = ResourcePickerMode.OpenResource;
///
/// Gets or sets the mode.
///
/// The mode.
public ResourcePickerMode Mode
{
get { return _mode; }
private set
{
_mode = value;
switch (_mode)
{
case ResourcePickerMode.OpenFolder:
{
this.Text = Strings.SelectFolder;
this.SelectFoldersOnly = true;
}
break;
case ResourcePickerMode.SaveResource:
{
this.Text = Strings.SaveResource;
}
break;
}
}
}
///
/// Constructs a new instance. Use this overload to select only resources of a specific type.
/// You cannot select folders in this mode. Attempting to set to
/// true will throw an
///
/// The res SVC.
/// The res filter.
/// The mode.
public ResourcePicker(IResourceService resSvc, ResourceTypes resFilter, ResourcePickerMode mode)
: this(resSvc, mode)
{
if (mode == ResourcePickerMode.OpenFolder)
throw new InvalidOperationException(string.Format(Strings.ModeNotAllowed, mode));
this.Filter = resFilter;
this.UseFilter = true;
_resourceMode = true;
cmbResourceFilter.Enabled = false;
}
///
/// Gets or sets the resource filter. If a filter value is specified, browsing
/// is locked to that particular resource type, otherwise all resource type can be
/// selected
///
public ResourceTypes Filter
{
get { return (ResourceTypes)cmbResourceFilter.SelectedItem; }
set
{
if (Array.IndexOf(_resTypes, value) < 0)
throw new InvalidOperationException("Cannot use specified resource type as filter: " + value); //LOCALIZE
cmbResourceFilter.SelectedItem = value;
}
}
///
/// Gets or sets whether to use a resource filter. If set to false, when selecting a folder
/// all resource types are returned, otherwise only children of the specified type are returned
///
internal bool UseFilter
{
get { return cmbResourceFilter.Visible; }
set
{
if (value && this.SelectFoldersOnly)
throw new InvalidOperationException("Cannot specify a filter when SelectFoldersOnly is true"); //LOCALIZE
cmbResourceFilter.Visible = value; lblFilter.Visible = value;
}
}
///
/// Gets or sets whether to select folders only. If true, the document view is disabled and
/// is set to false
///
private bool SelectFoldersOnly
{
get { return splitContainer1.Panel2Collapsed; }
set
{
if (_resourceMode && value)
throw new InvalidOperationException("Cannot specify to select folders when dialog is initialized with a resource filter"); //LOCALIZE
if (value)
this.UseFilter = false;
splitContainer1.Panel2Collapsed = value;
resIdComponentPanel.Visible = !value;
if (value)
txtResourceId.Text = string.Empty;
}
}
///
/// Gets the resource id of the selected item
///
public string ResourceID
{
get { return txtResourceId.Text; }
}
private void UpdateResourceId()
{
btnOK.Enabled = false;
this.SelectedFolder = txtFolder.Text;
if (this.SelectFoldersOnly)
{
txtResourceId.Text = txtFolder.Text;
if (!string.IsNullOrEmpty(txtFolder.Text) && ResourceIdentifier.IsFolderResource(txtResourceId.Text))
{
btnOK.Enabled = true;
}
}
else
{
txtResourceId.Text = txtFolder.Text + txtName.Text + "." + cmbResourceFilter.SelectedItem.ToString();
if (!ResourceIdentifier.IsFolderResource(txtResourceId.Text) && !string.IsNullOrEmpty(txtName.Text))
{
btnOK.Enabled = true;
}
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
private void btnOK_Click(object sender, EventArgs e)
{
if (_mode == ResourcePickerMode.OpenResource)
{
if (!_resSvc.ResourceExists(txtResourceId.Text))
{
MessageBox.Show(Strings.ResourceDoesntExist);
return;
}
}
else if (_mode == ResourcePickerMode.SaveResource)
{
if (ResourceIdentifier.IsFolderResource(txtResourceId.Text))
{
MessageBox.Show(Strings.InvalidResourceIdFolder);
return;
}
else
{
if (!ResourceIdentifier.Validate(txtResourceId.Text))
{
MessageBox.Show(Strings.InvalidResourceId);
return;
}
else
{
if (ResourceIdentifier.GetResourceType(txtResourceId.Text) != (ResourceTypes)cmbResourceFilter.SelectedItem)
{
MessageBox.Show(Strings.InvalidResourceIdNotSpecifiedType);
return;
}
}
if (_resSvc.ResourceExists(txtResourceId.Text))
{
if (MessageBox.Show(Strings.OverwriteResource, Strings.SaveResource, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
return;
}
}
}
if (ResourceIdentifier.IsFolderResource(txtResourceId.Text))
LastSelectedFolder.FolderId = txtResourceId.Text;
else
LastSelectedFolder.FolderId = (txtResourceId.Text != StringConstants.RootIdentifier) ? ResourceIdentifier.GetParentFolder(txtResourceId.Text) : StringConstants.RootIdentifier;
this.DialogResult = DialogResult.OK;
}
private void UpdateDocumentList()
{
IRepositoryItem folder = repoView.SelectedItem;
if (folder != null)
{
txtFolder.Text = folder.ResourceId;
if (!this.SelectFoldersOnly)
{
ResourceList list = null;
if (!this.UseFilter)
list = _resSvc.GetRepositoryResources(folder.ResourceId, 1);
else
list = _resSvc.GetRepositoryResources(folder.ResourceId, this.Filter.ToString(), 1);
PopulateDocumentList(list);
}
}
}
private void PopulateDocumentList(ResourceList list)
{
lstResources.Clear();
SortedList items = new SortedList();
foreach (var item in list.Items)
{
var doc = item as ResourceListResourceDocument;
if (doc != null)
{
string sortKey = doc.Name + "." + doc.ResourceType;
items.Add(sortKey, doc);
}
}
foreach (var doc in items.Values)
{
var li = new ListViewItem(doc.Name);
li.Tag = doc;
try
{
var rt = ResourceIdentifier.GetResourceType(doc.ResourceId);
li.ImageIndex = RepositoryIcons.GetImageIndexForResourceType(rt);
}
catch
{
li.ImageIndex = RepositoryIcons.RES_UNKNOWN;
}
lstResources.Items.Add(li);
}
}
private void lstResources_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstResources.SelectedItems.Count == 1)
{
var item = lstResources.SelectedItems[0];
var doc = item.Tag as ResourceListResourceDocument;
if (doc != null)
{
txtName.Text = ResourceIdentifier.GetName(doc.ResourceId);
}
}
}
private void txtName_TextChanged(object sender, EventArgs e)
{
UpdateResourceId();
}
private void txtFolder_TextChanged(object sender, EventArgs e)
{
UpdateResourceId();
}
private void cmbResourceFilter_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateResourceId();
UpdateDocumentList();
}
private void lstResources_MouseDoubleClick(object sender, MouseEventArgs e)
{
var item = lstResources.GetItemAt(e.X, e.Y);
if (item != null)
{
var doc = item.Tag as ResourceListResourceDocument;
if (doc != null)
{
txtName.Text = ResourceIdentifier.GetName(doc.ResourceId);
btnOK.PerformClick();
}
}
}
}
///
/// Defines the various modes this resource picker can be in
///
public enum ResourcePickerMode
{
///
///
///
OpenResource,
///
///
///
SaveResource,
///
///
///
OpenFolder
}
}