diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index c4c0ef70f4..6799d76b45 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -454,6 +454,13 @@ editPython.aspx + + ChangeDocType.aspx + ASPXCodeBehind + + + ChangeDocType.aspx + EditMacro.aspx ASPXCodeBehind @@ -663,6 +670,9 @@ + + ASPXCodeBehind + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 4acaa7b2a6..59fcf55aed 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -8,6 +8,7 @@ Culture and Hostnames Audit Trail Browse Node + Change Document Type Copy Create Create Package @@ -92,6 +93,26 @@ Show styles Insert table + + To change the document type for the selected content, first select from the list of valid types for this location. + Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. + The content has been re-published. + Current Property + Current type + The document type cannot be changed, as there are no alternatives valid for this location. + Document Type Changed + Map Properties + Map to Property + New Template + New Type + none + Content + Select New Document Type + The document type of the selected content has been successfully changed to [new type] and the following properties mapped: + to + Could not complete property mapping as one or more properties have more than one mapping defined. + Only alternate types valid for the current location are displayed. + About this page Alias diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 430669c5d1..256293a2ce 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -8,6 +8,7 @@ Manage hostnames Audit Trail Browse Node + Change Document Type Copy Create Create Package @@ -79,6 +80,23 @@ Show styles Insert table + + To change the document type for the selected content, first select from the list of valid types for this location. + Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. + Current Property + Current type + The document type cannot be changed, as there are no alternatives valid for this location. + Map Properties + Map to Property + New Template + New Type + none + Content + Select New Document Type + The document type of the selected content has been successfully changed and the properties mapped. + Could not complete property mapping as one or more properties have more than one mapping defined. + Only alternate types valid for the current location are displayed. + About this page Alias diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx new file mode 100644 index 0000000000..c6fb07ed19 --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx @@ -0,0 +1,118 @@ +<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master"Codebehind="ChangeDocType.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Dialogs.ChangeDocType" %> +<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> +<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> + + + + + + + + + + +

+ <%= umbraco.ui.Text("changeDocType", "changeDocTypeInstruction") %> +

+ + + + + + + + + + + + +
<%=umbraco.ui.Text("changeDocType", "validDocTypesNote") %> +
+ + + + + + +
+

<%=umbraco.ui.Text("changeDocType", "docTypeCannotBeChanged") %>

+
+
+
+ + + +

+ <%= umbraco.ui.Text("changeDocType", "changeDocTypeInstruction2") %> +

+ + + + + + + + + + + + + + + + + + +
<%= umbraco.ui.Text("changeDocType", "currentProperty") %><%= umbraco.ui.Text("changeDocType", "mapToProperty") %>
+ <%# DataBinder.Eval(Container, "DataItem.Name") %> + + + +
+ +
+
+ + +

<%=umbraco.ui.Text("changeDocType", "docTypeChanged") %>

+
+ +
+ + +
+
+ +
+
+ + +
+

+ + + <%= umbraco.ui.Text("or") %> + + <%=umbraco.ui.Text("general", "cancel", this.getUser())%> +

+
+ +
+ \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.cs b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.cs new file mode 100644 index 0000000000..39c0efc74d --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.cs @@ -0,0 +1,333 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.UI; +using System.Web.UI.WebControls; +using umbraco.BasePages; +using Umbraco.Core; +using Umbraco.Core.Models; + +namespace Umbraco.Web.UI.Umbraco.Dialogs +{ + public partial class ChangeDocType : UmbracoEnsuredPage + { + class PropertyMapping + { + public string FromName { get; set; } + public string ToName { get; set; } + public string ToAlias { get; set; } + public object Value { get; set; } + } + + private IContent _content; + + protected void Page_Load(object sender, EventArgs e) + { + var contentNodeId = int.Parse(Request.QueryString["id"]); + _content = ApplicationContext.Current.Services.ContentService.GetById(contentNodeId); + + LocalizeTexts(); + + if (!Page.IsPostBack) + { + DisplayContentDetails(); + if (PopulateListOfValidAlternateDocumentTypes()) + { + PopulateListOfTemplates(); + PopulatePropertyMappingWithSources(); + PopulatePropertyMappingWithDestinations(); + } + else + { + DisplayNotAvailable(); + } + } + } + + private void LocalizeTexts() + { + ChangeDocTypePane.Text = global::umbraco.ui.Text("changeDocType", "selectNewDocType"); + ContentNamePropertyPanel.Text = global::umbraco.ui.Text("changeDocType", "selectedContent"); + CurrentTypePropertyPanel.Text = global::umbraco.ui.Text("changeDocType", "currentType"); + NewTypePropertyPanel.Text = global::umbraco.ui.Text("changeDocType", "newType"); + NewTemplatePropertyPanel.Text = global::umbraco.ui.Text("changeDocType", "newTemplate"); + ChangeDocTypePropertyMappingPane.Text = global::umbraco.ui.Text("changeDocType", "mapProperties"); + ValidateAndSave.Text = global::umbraco.ui.Text("buttons", "save"); + } + + private void DisplayContentDetails() + { + ContentNameLabel.Text = _content.Name; + CurrentTypeLabel.Text = _content.ContentType.Name; + } + + private bool PopulateListOfValidAlternateDocumentTypes() + { + // Get all content types + var documentTypes = ApplicationContext.Current.Services.ContentTypeService.GetAllContentTypes(); + + // Save a flag if the allowed at root option has been set for any document types (if not, then all are allowed there) + var haveTypesAllowedAtRootBeenDefined = documentTypes.Any(x => x.AllowedAsRoot); + + // Remove current one + documentTypes = documentTypes.Where(x => x.Id != _content.ContentType.Id); + + // Remove any not valid for current location + if (_content.ParentId == -1 && haveTypesAllowedAtRootBeenDefined) + { + // Root content, and at least one type has been defined as allowed at root, so only include those that have + // been selected as allowed + documentTypes = documentTypes.Where(x => x.AllowedAsRoot); + } + else + { + // Below root, so only include those allowed as sub-nodes for the parent + var parentNode = ApplicationContext.Current.Services.ContentService.GetById(_content.ParentId); + documentTypes = documentTypes.Where(x => parentNode.ContentType.AllowedContentTypes + .Select(y => y.Id.Value) + .Contains(x.Id)); + } + + // If we have at least one, bind to list and return true + if (documentTypes.Any()) + { + NewDocumentTypeList.DataSource = documentTypes.OrderBy(x => x.Name); + NewDocumentTypeList.DataValueField = "Id"; + NewDocumentTypeList.DataTextField = "Name"; + NewDocumentTypeList.DataBind(); + return true; + } + + return false; + } + + private void PopulateListOfTemplates() + { + // Get selected new document type + var contentType = GetSelectedDocumentType(); + + // Populate template list + NewTemplateList.DataSource = contentType.AllowedTemplates; + NewTemplateList.DataValueField = "Id"; + NewTemplateList.DataTextField = "Name"; + NewTemplateList.DataBind(); + NewTemplateList.Items.Add(new ListItem("<" + global::umbraco.ui.Text("changeDocType", "none") + ">", "0")); + + // Set default template + if (contentType.DefaultTemplate != null) + { + var itemToSelect = NewTemplateList.Items.FindByValue(contentType.DefaultTemplate.Id.ToString()); + if (itemToSelect != null) + { + itemToSelect.Selected = true; + } + } + } + + private void PopulatePropertyMappingWithSources() + { + PropertyMappingRepeater.DataSource = GetPropertiesOfContentType(_content.ContentType); + PropertyMappingRepeater.DataBind(); + } + + private void PopulatePropertyMappingWithDestinations() + { + // Get selected new document type + var contentType = GetSelectedDocumentType(); + + // Get properties of new document type (including any from parent types) + var properties = GetPropertiesOfContentType(contentType); + + // Loop through list of source properties and populate destination options with all those of same property type + foreach (RepeaterItem ri in PropertyMappingRepeater.Items) + { + if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem) + { + // Get data type from hidden field + var dataTypeId = Guid.Parse(((HiddenField)ri.FindControl("DataTypeId")).Value); + + // Bind destination list with properties that match data type + var ddl = (DropDownList)ri.FindControl("DestinationProperty"); + ddl.DataSource = properties.Where(x => x.DataTypeId == dataTypeId); + ddl.DataValueField = "Alias"; + ddl.DataTextField = "Name"; + ddl.DataBind(); + ddl.Items.Add(new ListItem("<" + global::umbraco.ui.Text("changeDocType", "none") + ">", string.Empty)); + + // Set default selection to be one with matching alias + var alias = ((HiddenField)ri.FindControl("Alias")).Value; + var item = ddl.Items.FindByValue(alias); + if (item != null) + { + item.Selected = true; + } + } + } + } + + private IContentType GetSelectedDocumentType() + { + return ApplicationContext.Current.Services.ContentTypeService.GetContentType(int.Parse(NewDocumentTypeList.SelectedItem.Value)); + } + + private IEnumerable GetPropertiesOfContentType(IContentType contentType) + { + var properties = contentType.PropertyTypes.ToList(); + while (contentType.ParentId > -1) + { + contentType = ApplicationContext.Current.Services.ContentTypeService.GetContentType(contentType.ParentId); + properties.AddRange(contentType.PropertyTypes); + } + + return properties.OrderBy(x => x.Name); + } + + private void DisplayNotAvailable() + { + NewTypePropertyPanel.Visible = false; + NewTemplatePropertyPanel.Visible = false; + SavePlaceholder.Visible = false; + NotAvailablePlaceholder.Visible = true; + ChangeDocTypePropertyMappingPane.Visible = false; + } + + protected void NewDocumentTypeList_SelectedIndexChanged(object sender, EventArgs e) + { + PopulateListOfTemplates(); + PopulatePropertyMappingWithDestinations(); + } + + protected void ValidateAndSave_Click(object sender, EventArgs e) + { + if (IsPropertyMappingValid()) + { + // For all properties to be mapped, save the values to a temporary list + var propertyMappings = SavePropertyMappings(); + + // Get flag for if content already published + var wasPublished = _content.Published; + + // Change the document type passing flag to clear the properties + var newContentType = GetSelectedDocumentType(); + _content.ChangeContentType(newContentType, true); + + // Set the template if one has been selected + if (NewTemplateList.SelectedItem != null) + { + var templateId = int.Parse(NewTemplateList.SelectedItem.Value); + if (templateId > 0) + { + _content.Template = ApplicationContext.Current.Services.FileService.GetTemplate(templateId); + } + } + + // Set the property values + var propertiesMappedMessageBuilder = new StringBuilder("
    "); + foreach (var propertyMapping in propertyMappings) + { + propertiesMappedMessageBuilder.AppendFormat("
  • {0} {1} {2}
  • ", + propertyMapping.FromName, global::umbraco.ui.Text("changeDocType", "to"), propertyMapping.ToName); + _content.SetValue(propertyMapping.ToAlias, propertyMapping.Value); + } + propertiesMappedMessageBuilder.Append("
"); + + // Save + var user = global::umbraco.BusinessLogic.User.GetCurrent(); + ApplicationContext.Current.Services.ContentService.Save(_content, user.Id); + + // Publish if the content was already published + if (wasPublished) + { + ApplicationContext.Current.Services.ContentService.Publish(_content, user.Id); + } + + // Sync the tree + ClientTools.SyncTree(_content.Path, true); + + // Reload the page if the content was already being viewed + ClientTools.ReloadContentFrameUrlIfPathLoaded("/editContent.aspx?id=" + _content.Id); + + // Display success message + SuccessMessage.Text = global::umbraco.ui.Text("changeDocType", "successMessage").Replace("[new type]", "" + newContentType.Name + ""); + PropertiesMappedMessage.Text = propertiesMappedMessageBuilder.ToString(); + if (wasPublished) + { + ContentPublishedMessage.Text = global::umbraco.ui.Text("changeDocType", "contentRepublished"); + ContentPublishedMessage.Visible = true; + } + else + { + ContentPublishedMessage.Visible = false; + } + SuccessPlaceholder.Visible = true; + SaveAndCancelPlaceholder.Visible = false; + ValidationPlaceholder.Visible = false; + ChangeDocTypePane.Visible = false; + ChangeDocTypePropertyMappingPane.Visible = false; + } + else + { + ValidationPlaceholder.Visible = true; + } + } + + private bool IsPropertyMappingValid() + { + // Check whether any properties have been mapped to more than once + var mappedPropertyAliases = new List(); + foreach (RepeaterItem ri in PropertyMappingRepeater.Items) + { + if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem) + { + var ddl = (DropDownList)ri.FindControl("DestinationProperty"); + var mappedPropertyAlias = ddl.SelectedItem.Value; + if (!string.IsNullOrEmpty(mappedPropertyAlias)) + { + if (mappedPropertyAliases.Contains(mappedPropertyAlias)) + { + ValidationError.Text = global::umbraco.ui.Text("changeDocType", "validationErrorPropertyWithMoreThanOneMapping"); + return false; + } + + mappedPropertyAliases.Add(mappedPropertyAlias); + } + } + } + + return true; + } + + private IList SavePropertyMappings() + { + // Create list of mapped property values for assignment after the document type is changed + var mappedPropertyValues = new List(); + foreach (RepeaterItem ri in PropertyMappingRepeater.Items) + { + if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem) + { + // Get property alias to map to + var ddl = (DropDownList)ri.FindControl("DestinationProperty"); + var mappedAlias = ddl.SelectedItem.Value; + if (!string.IsNullOrEmpty(mappedAlias)) + { + // If mapping property, get current property value from alias + var sourceAlias = ((HiddenField)ri.FindControl("Alias")).Value; + var sourcePropertyValue = _content.GetValue(sourceAlias); + + // Add to list + mappedPropertyValues.Add(new PropertyMapping + { + FromName = ((HiddenField)ri.FindControl("Name")).Value, + ToName = ddl.SelectedItem.Text, + ToAlias = mappedAlias, + Value = sourcePropertyValue + }); + } + } + } + + return mappedPropertyValues; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.designer.cs new file mode 100644 index 0000000000..c49801294e --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx.designer.cs @@ -0,0 +1,213 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Web.UI.Umbraco.Dialogs { + + + public partial class ChangeDocType { + + /// + /// ChangeDocTypePane control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.Pane ChangeDocTypePane; + + /// + /// ContentNamePropertyPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.PropertyPanel ContentNamePropertyPanel; + + /// + /// ContentNameLabel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label ContentNameLabel; + + /// + /// CurrentTypePropertyPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.PropertyPanel CurrentTypePropertyPanel; + + /// + /// CurrentTypeLabel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label CurrentTypeLabel; + + /// + /// NewTypePropertyPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.PropertyPanel NewTypePropertyPanel; + + /// + /// NewDocumentTypeList control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList NewDocumentTypeList; + + /// + /// NewDocumentTypeValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator NewDocumentTypeValidator; + + /// + /// NewTemplatePropertyPanel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.PropertyPanel NewTemplatePropertyPanel; + + /// + /// NewTemplateList control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList NewTemplateList; + + /// + /// NotAvailablePlaceholder control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder NotAvailablePlaceholder; + + /// + /// ChangeDocTypePropertyMappingPane control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.Pane ChangeDocTypePropertyMappingPane; + + /// + /// PropertyMappingRepeater control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Repeater PropertyMappingRepeater; + + /// + /// SuccessPlaceholder control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder SuccessPlaceholder; + + /// + /// SuccessMessage control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal SuccessMessage; + + /// + /// PropertiesMappedMessage control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal PropertiesMappedMessage; + + /// + /// ContentPublishedMessage control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal ContentPublishedMessage; + + /// + /// ValidationPlaceholder control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder ValidationPlaceholder; + + /// + /// ValidationError control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Literal ValidationError; + + /// + /// SaveAndCancelPlaceholder control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder SaveAndCancelPlaceholder; + + /// + /// SavePlaceholder control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.PlaceHolder SavePlaceholder; + + /// + /// ValidateAndSave control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button ValidateAndSave; + } +} diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js index 0e9b508784..3ff3e7beec 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js +++ b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js @@ -181,6 +181,15 @@ Umbraco.Application.Actions = function () { }, + actionChangeDocType: function () { + /// + + if (UmbClientMgr.mainTree().getActionNode().nodeId != '0' && UmbClientMgr.mainTree().getActionNode().nodeType != '') { + UmbClientMgr.openModalWindow("dialogs/changeDocType.aspx?id=" + UmbClientMgr.mainTree().getActionNode().nodeId + '&app=' + this._currApp + '&rnd=' + this._utils.generateRandom(), uiKeys['actions_changeDocType'], true, 600, 600); + } + + }, + actionRights: function () { /// diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoClientManager.js b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoClientManager.js index e3bc82b260..feeb02bf4f 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoClientManager.js +++ b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoClientManager.js @@ -141,6 +141,20 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); },200); } }, + reloadContentFrameUrlIfPathLoaded: function (url) { + var contentFrame; + if (typeof this.mainWindow().right != "undefined") { + contentFrame = this.mainWindow().right; + } + else { + contentFrame = this.mainWindow(); + } + + var currentPath = contentFrame.location.pathname + (contentFrame.location.search ? contentFrame.location.search : ""); + if (currentPath == url) { + contentFrame.location.reload(); + } + }, openModalWindow: function(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback) { //need to create the modal on the top window if the top window has a client manager, if not, create it on the current window diff --git a/src/Umbraco.Web.UI/umbraco_client/Tree/menuIcons.css b/src/Umbraco.Web.UI/umbraco_client/Tree/menuIcons.css index 680c4a0296..9cbe7c96d5 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Tree/menuIcons.css +++ b/src/Umbraco.Web.UI/umbraco_client/Tree/menuIcons.css @@ -105,8 +105,11 @@ { background-position: -7px -207px; } - .sprLiveEdit { background-position: -7px -706px; -} \ No newline at end of file +} +.sprChangeDocType +{ + background-position: -12px -741px; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Tree/sprites.png b/src/Umbraco.Web.UI/umbraco_client/Tree/sprites.png index 8a3ed9b934..820942c963 100644 Binary files a/src/Umbraco.Web.UI/umbraco_client/Tree/sprites.png and b/src/Umbraco.Web.UI/umbraco_client/Tree/sprites.png differ diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c8ab6c7f95..8c8271800b 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1957,7 +1957,9 @@ ASPXCodeBehind
- + + ASPXCodeBehind + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs index abd79a204a..dfbb7cd8e8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs @@ -124,6 +124,8 @@ namespace umbraco actions.Add(ActionSort.Instance); actions.Add(ActionRollback.Instance); actions.Add(ContextMenuSeperator.Instance); + actions.Add(ActionChangeDocType.Instance); + actions.Add(ContextMenuSeperator.Instance); actions.Add(ActionPublish.Instance); actions.Add(ActionToPublish.Instance); actions.Add(ActionAssignDomain.Instance); diff --git a/src/umbraco.businesslogic/BasePages/ClientTools.cs b/src/umbraco.businesslogic/BasePages/ClientTools.cs index 2dffb45024..3050448430 100644 --- a/src/umbraco.businesslogic/BasePages/ClientTools.cs +++ b/src/umbraco.businesslogic/BasePages/ClientTools.cs @@ -48,6 +48,9 @@ namespace umbraco.BasePages public static string ChangeContentFrameUrl(string url) { return string.Format(ClientMgrScript + ".contentFrame('{0}');", url); } + public static string ReloadContentFrameUrlIfPathLoaded(string url) { + return string.Format(ClientMgrScript + ".reloadContentFrameUrlIfPathLoaded('{0}');", url); + } public static string ChildNodeCreated = GetMainTree + ".childNodeCreated();"; public static string SyncTree { get { return GetMainTree + ".syncTree('{0}', {1});"; } } public static string ClearTreeCache { get { return GetMainTree + ".clearTreeCache();"; } } @@ -147,8 +150,7 @@ namespace umbraco.BasePages //don't load if there is no url if (string.IsNullOrEmpty(url)) return this; - if (url.StartsWith("/") && !url.StartsWith(IOHelper.ResolveUrl(SystemDirectories.Umbraco))) - url = IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/" + url; + url = EnsureUmbracoUrl(url); if (url.Trim().StartsWith("~")) url = IOHelper.ResolveUrl(url); @@ -158,6 +160,30 @@ namespace umbraco.BasePages return this; } + /// + /// Reloads the content in the content frame if the specified URL is currently loaded + /// + /// + public ClientTools ReloadContentFrameUrlIfPathLoaded(string url) + { + if (string.IsNullOrEmpty(url)) return this; + + url = EnsureUmbracoUrl(url); + + RegisterClientScript(Scripts.ReloadContentFrameUrlIfPathLoaded(url)); + + return this; + } + + private string EnsureUmbracoUrl(string url) + { + if (url.StartsWith("/") && !url.StartsWith(IOHelper.ResolveUrl(SystemDirectories.Umbraco))) + { + url = IOHelper.ResolveUrl(SystemDirectories.Umbraco) + url; + } + return url; + } + /// /// Shows the dashboard for the given application /// diff --git a/src/umbraco.cms/Actions/ActionChangeDocType.cs b/src/umbraco.cms/Actions/ActionChangeDocType.cs new file mode 100644 index 0000000000..dee4d53607 --- /dev/null +++ b/src/umbraco.cms/Actions/ActionChangeDocType.cs @@ -0,0 +1,94 @@ +using System; +using umbraco.interfaces; +using umbraco.BasePages; + +namespace umbraco.BusinessLogic.Actions +{ + /// + /// This action is invoked when the document type of a piece of content is changed + /// + public class ActionChangeDocType : IAction + { + //create singleton +#pragma warning disable 612,618 + private static readonly ActionChangeDocType m_instance = new ActionChangeDocType(); +#pragma warning restore 612,618 + + /// + /// A public constructor exists ONLY for backwards compatibility in regards to 3rd party add-ons. + /// All Umbraco assemblies should use the singleton instantiation (this.Instance) + /// When this applicatio is refactored, this constuctor should be made private. + /// + [Obsolete("Use the singleton instantiation instead of a constructor")] + public ActionChangeDocType() { } + + public static ActionChangeDocType Instance + { + get { return m_instance; } + } + + #region IAction Members + + public char Letter + { + get + { + + return '7'; + } + } + + public string JsFunctionName + { + get + { + return string.Format("{0}.actionChangeDocType()", ClientTools.Scripts.GetAppActions); + } + } + + public string JsSource + { + get + { + + return null; + } + } + + public string Alias + { + get + { + + return "changeDocType"; + } + } + + public string Icon + { + get + { + + return ".sprChangeDocType"; + } + } + + public bool ShowInNotifier + { + get + { + + return true; + } + } + public bool CanBePermissionAssigned + { + get + { + + return true; + } + } + #endregion + } +} diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj index cfa764afab..22b89f894f 100644 --- a/src/umbraco.cms/umbraco.cms.csproj +++ b/src/umbraco.cms/umbraco.cms.csproj @@ -175,6 +175,7 @@ +