#region Disclaimer / License // Copyright (C) 2011, 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.Text; using OSGeo.MapGuide.MaestroAPI.Services; using Maestro.Editors.Common; using System.ComponentModel; using System.IO; using OSGeo.MapGuide.MaestroAPI.Resource; using Maestro.Editors.Generic; using OSGeo.MapGuide.MaestroAPI; using OSGeo.MapGuide.MaestroAPI.Schema; namespace Maestro.Editors { /// /// A base class for providing editor services /// public abstract class ResourceEditorServiceBase : IEditorService { /// /// The server connection /// protected IServerConnection _conn; /// /// The resource being edited /// protected IResource _editCopy; /// /// Initializes a new instance of the class. /// /// The resource ID. /// The conn. protected ResourceEditorServiceBase(string resourceID, IServerConnection conn) { this.IsNew = ResourceIdentifier.IsSessionBased(resourceID); this.ResourceID = resourceID; _conn = conn; } /// /// Raised when the edited resource has changed /// public event EventHandler DirtyStateChanged; /// /// Edits the expression. /// /// The current expr. /// The class def. /// Name of the provider. /// The feature source id. /// public string EditExpression(string currentExpr, ClassDefinition classDef, string providerName, string featureSourceId) { var ed = new ExpressionEditor(); var caps = this.FeatureService.GetProviderCapabilities(providerName); ed.Initialize(this.FeatureService, caps, classDef, featureSourceId); ed.Expression = currentExpr; if (ed.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return ed.Expression; } return null; } /// /// Initiates the editing process. The resource to be edited is copied to the session repository and /// a deserialized version is returned from this copy. Subsequent calls will return the same reference /// to this resource object. /// /// /// A deserialized version of a session-copy of the resource to be edited /// public IResource GetEditedResource() { if (_editCopy == null) { string copy = _conn.GenerateSessionResourceId(ResourceIdentifier.GetResourceType(this.ResourceID)); _conn.ResourceService.CopyResource(this.ResourceID, copy, true); _editCopy = _conn.ResourceService.GetResource(copy); _editCopy.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnResourcePropertyChanged); } return _editCopy; } /// /// Called when [resource property changed]. /// /// The sender. /// The instance containing the event data. protected void OnResourcePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { MarkDirty(); } /// /// Called when [dirty state changed]. /// protected void OnDirtyStateChanged() { var handler = this.DirtyStateChanged; if (handler != null) handler(this, EventArgs.Empty); } /// /// Indicates whether the edited resource has unsaved changes /// public bool IsDirty { get; private set; } /// /// Forces the edited resource to be marked as dirty /// public void MarkDirty() { this.IsDirty = true; OnDirtyStateChanged(); } /// /// Indicates whether the edited resource is a new resource /// public bool IsNew { get; private set; } /// /// Opens the specified URL /// /// public abstract void OpenUrl(string url); /// /// Gets the resource ID of the resource, whose session-copy is being edited /// public string ResourceID { get; private set; } /// /// Invokes a prompt to select a resource of any type /// /// public string SelectAnyResource() { var picker = new ResourcePicker(_conn.ResourceService, ResourcePickerMode.OpenResource); if (picker.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return picker.ResourceID; } return string.Empty; } /// /// Invokes a prompt to select a resource of the specified type /// /// /// public string SelectResource(OSGeo.MapGuide.MaestroAPI.ResourceTypes resType) { var picker = new ResourcePicker(_conn.ResourceService, resType, ResourcePickerMode.OpenResource); if (picker.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return picker.ResourceID; } return string.Empty; } /// /// Invokes a prompt to select a folder /// /// public string SelectFolder() { var picker = new ResourcePicker(_conn.ResourceService, ResourcePickerMode.OpenFolder); if (picker.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return picker.ResourceID; } return string.Empty; } /// /// Invokes a prompt to select a file from an unmanaged alias /// /// /// /// public abstract string SelectUnmanagedData(string startPath, System.Collections.Specialized.NameValueCollection fileTypes); /// /// Saves the edited resource. The session copy, which holds the current changes is copied back /// to the original resource ID. /// public void Save() { if (!OnBeforeSave()) { _conn.ResourceService.CopyResource(this.EditedResourceID, this.ResourceID, true); this.IsDirty = false; OnDirtyStateChanged(); OnSaved(); } } /// /// Saves the edited resource under a different resource ID. The session copy, which holds the current changes is copied back /// to the specified resource ID /// /// public void SaveAs(string resourceID) { if (ResourceIdentifier.IsSessionBased(resourceID)) throw new ArgumentException(Properties.Resources.NotSessionBasedId); //LOCALIZE if (!OnBeforeSave()) { //_conn.ResourceService.SaveResourceAs(_editCopy, resourceID); _conn.ResourceService.CopyResource(_editCopy.ResourceID, resourceID, true); this.ResourceID = resourceID; this.IsNew = false; this.IsDirty = false; OnDirtyStateChanged(); OnSaved(); } } /// /// Indicates whether an upgrade for this resource is available /// public bool IsUpgradeAvailable { get { if (_editCopy == null) return false; return _conn.Capabilities.GetMaxSupportedResourceVersion(_editCopy.ResourceType) > _editCopy.ResourceVersion; } } /// /// Gets the resource ID of the actively edited resource /// public string EditedResourceID { get { return _editCopy.ResourceID; } } /// /// Registers a custom notifier /// /// public void RegisterCustomNotifier(INotifyResourceChanged irc) { irc.ResourceChanged += (sender, e) => { this.IsDirty = true; OnDirtyStateChanged(); }; } /// /// Updates the session copy's resource content /// /// public void UpdateResourceContent(string xml) { try { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) { _conn.ResourceService.SetResourceXmlData(this.EditedResourceID, ms); } } catch (Exception ex) { XmlContentErrorDialog.CheckAndHandle(ex, xml, false); } } /// /// Called when [before save]. /// /// private bool OnBeforeSave() { var e = new CancelEventArgs(); var handler = this.BeforeSave; if (handler != null) handler(this, e); return e.Cancel; } /// /// Raised before a save operation commences /// public event System.ComponentModel.CancelEventHandler BeforeSave; /// /// Gets the associated feature service /// public IFeatureService FeatureService { get { return _conn.FeatureService; } } /// /// Gets the associated resource service /// public IResourceService ResourceService { get { return _conn.ResourceService; } } /// /// Invokes a prompt to select the coordinate system /// /// public string GetCoordinateSystem() { var dlg = new CoordinateSystemPicker(_conn.CoordinateSystemCatalog); if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return dlg.SelectedCoordSys.WKT; } return string.Empty; } /// /// Gets the associated drawing service /// public IDrawingService DrawingService { get { return (IDrawingService)_conn.GetService((int)ServiceType.Drawing); } } /// /// Forces the the event. Normally the databinding /// system should auto-flag dirty state, only call this if you don't utilise this /// databinding system. /// public void HasChanged() { this.IsDirty = true; OnDirtyStateChanged(); } /// /// Gets the session id /// public string SessionID { get { return _conn.SessionID; } } /// /// Indicates if a specified custom command is supported and can be created /// /// /// public bool SupportsCommand(OSGeo.MapGuide.MaestroAPI.Commands.CommandType cmdType) { return Array.IndexOf(_conn.Capabilities.SupportedCommands, (int)cmdType) >= 0; } /// /// Create a custom command /// /// /// public OSGeo.MapGuide.MaestroAPI.Commands.ICommand CreateCommand(OSGeo.MapGuide.MaestroAPI.Commands.CommandType cmdType) { return _conn.CreateCommand((int)cmdType); } /// /// Raises a request to refresh the Site Explorer /// public abstract void RequestRefresh(); /// /// Raises a request to refresh the Site Explorer at the specified folder id /// /// public abstract void RequestRefresh(string folderId); /// /// Called when [saved]. /// protected void OnSaved() { var handler = this.Saved; if (handler != null) handler(this, EventArgs.Empty); } /// /// Raised when the edited resource is saved /// public event EventHandler Saved; /// /// Synchronises changes in the in-memory resource back to the session repository. This is usually called /// before validation of the edited resource begins. /// public void SyncSessionCopy() { string xml = ResourceTypeRegistry.SerializeAsString(_editCopy); try { using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) { this.ResourceService.SetResourceXmlData(_editCopy.ResourceID, ms); } } catch (Exception ex) { XmlContentErrorDialog.CheckAndHandle(ex, xml, false); } } /// /// Gets the MapGuide Server version /// public Version SiteVersion { get { return _conn.SiteVersion; } } /// /// Opens the specified resource /// /// public abstract void OpenResource(string resourceId); /// /// Gets the suggested save folder for a "save as" operation /// public string SuggestedSaveFolder { get; set; } /// /// Gets the value of a custom connection property /// /// /// public object GetCustomProperty(string name) { return _conn.GetCustomProperty(name); } /// /// Gets the service of the specified type /// /// /// public IService GetService(int serviceType) { return _conn.GetService(serviceType); } /// /// Gets the supported services /// public int[] SupportedServiceTypes { get { return _conn.Capabilities.SupportedServices; } } public abstract void RunProcess(string processName, params string[] args); public void PrePreviewProcess() { SyncSessionCopy(); var handler = this.BeforePreview; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler BeforePreview; } }