///* // * DragSource.cs - Add drag source functionality to an ObjectListView // * // * UNFINISHED // * // * Author: Phillip Piper // * Date: 2009-03-17 5:15 PM // * // * Change log: // * v2.3 // * 2009-07-06 JPP - Make sure Link is acceptable as an drop effect by default // * (since MS didn't make it part of the 'All' value) // * v2.2 // * 2009-04-15 JPP - Separated DragSource.cs into DropSink.cs // * 2009-03-17 JPP - Initial version // * // * Copyright (C) 2009 Phillip Piper // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by // * the Free Software Foundation, either version 3 of the License, or // * (at your option) any later version. // * // * This program 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 General Public License for more details. // * // * You should have received a copy of the GNU General Public License // * along with this program. If not, see . // * // * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com. // */ //using System; //using System.Collections; //using System.Collections.Generic; //using System.Text; //using System.Windows.Forms; //using System.Drawing; //using System.Drawing.Drawing2D; //namespace BrightIdeasSoftware //{ // /// // /// An IDragSource controls how drag out from the ObjectListView will behave // /// // public interface IDragSource // { // /// // /// A drag operation is beginning. Return the data object that will be used // /// for data transfer. Return null to prevent the drag from starting. // /// // /// // /// The returned object is later passed to the GetAllowedEffect() and EndDrag() // /// methods. // /// // /// What ObjectListView is being dragged from. // /// Which mouse button is down? // /// What item was directly dragged by the user? There may be more than just this // /// item selected. // /// The data object that will be used for data transfer. This will often be a subclass // /// of DataObject, but does not need to be. // Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item); // /// // /// What operations are possible for this drag? This controls the icon shown during the drag // /// // /// The data object returned by StartDrag() // /// A combination of DragDropEffects flags // DragDropEffects GetAllowedEffects(Object dragObject); // /// // /// The drag operation is complete. Do whatever is necessary to complete the action. // /// // /// The data object returned by StartDrag() // /// The value returned from GetAllowedEffects() // void EndDrag(Object dragObject, DragDropEffects effect); // } // /// // /// A do-nothing implementation of IDragSource that can be safely subclassed. // /// // public class AbstractDragSource : IDragSource // { // #region IDragSource Members // /// // /// See IDragSource documentation // /// // /// // /// // /// // /// // public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { // return null; // } // /// // /// See IDragSource documentation // /// // /// // /// // public virtual DragDropEffects GetAllowedEffects(Object data) { // return DragDropEffects.None; // } // /// // /// See IDragSource documentation // /// // /// // /// // public virtual void EndDrag(Object dragObject, DragDropEffects effect) { // } // #endregion // } // /// // /// A reasonable implementation of IDragSource that provides normal // /// drag source functionality. It creates a data object that supports // /// inter-application dragging of text and HTML representation of // /// the dragged rows. It can optionally force a refresh of all dragged // /// rows when the drag is complete. // /// // /// Subclasses can override GetDataObject() to add new // /// data formats to the data transfer object. // public class SimpleDragSource : IDragSource // { // #region Constructors // /// // /// Construct a SimpleDragSource // /// // public SimpleDragSource() { // } // /// // /// Construct a SimpleDragSource that refreshes the dragged rows when // /// the drag is complete // /// // /// // public SimpleDragSource(bool refreshAfterDrop) { // this.RefreshAfterDrop = refreshAfterDrop; // } // #endregion // #region Public properties // /// // /// Gets or sets whether the dragged rows should be refreshed when the // /// drag operation is complete. // /// // public bool RefreshAfterDrop { // get { return refreshAfterDrop; } // set { refreshAfterDrop = value; } // } // private bool refreshAfterDrop; // #endregion // #region IDragSource Members // /// // /// Create a DataObject when the user does a left mouse drag operation. // /// See IDragSource for further information. // /// // /// // /// // /// // /// // public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { // // We only drag on left mouse // if (button != MouseButtons.Left) // return null; // return this.CreateDataObject(olv); // } // /// // /// Which operations are allowed in the operation? By default, all operations are supported. // /// // /// // /// All opertions are supported // public virtual DragDropEffects GetAllowedEffects(Object data) { // return DragDropEffects.All | DragDropEffects.Link; // why didn't MS include 'Link' in 'All'?? // } // /// // /// The drag operation is finished. Refreshe the dragged rows if so configured. // /// // /// // /// // public virtual void EndDrag(Object dragObject, DragDropEffects effect) { // OLVDataObject data = dragObject as OLVDataObject; // if (data == null) // return; // if (this.RefreshAfterDrop) // data.ListView.RefreshObjects(data.ModelObjects); // } // /// // /// Create a data object that will be used to as the data object // /// for the drag operation. // /// // /// // /// Subclasses can override this method add new formats to the data object. // /// // /// The ObjectListView that is the source of the drag // /// A data object for the drag // protected virtual object CreateDataObject(ObjectListView olv) { // OLVDataObject data = new OLVDataObject(olv); // data.CreateTextFormats(); // return data; // } // #endregion // } // /// // /// A data transfer object that knows how to transform a list of model // /// objects into a text and HTML representation. // /// // public class OLVDataObject : DataObject // { // #region Life and death // /// // /// Create a data object from the selected objects in the given ObjectListView // /// // /// The source of the data object // public OLVDataObject(ObjectListView olv) : this(olv, olv.SelectedObjects) { // } // /// // /// Create a data object which operates on the given model objects // /// in the given ObjectListView // /// // /// The source of the data object // /// The model objects to be put into the data object // public OLVDataObject(ObjectListView olv, IList modelObjects) { // this.objectListView = olv; // this.modelObjects = modelObjects; // this.includeHiddenColumns = olv.IncludeHiddenColumnsInDataTransfer; // this.includeColumnHeaders = olv.IncludeColumnHeadersInCopy; // } // #endregion // #region Properties // /// // /// Gets or sets whether hidden columns will also be included in the text // /// and HTML representation. If this is false, only visible columns will // /// be included. // /// // public bool IncludeHiddenColumns { // get { return includeHiddenColumns; } // } // private bool includeHiddenColumns; // /// // /// Gets or sets whether column headers will also be included in the text // /// and HTML representation. // /// // public bool IncludeColumnHeaders // { // get { return includeColumnHeaders; } // } // private bool includeColumnHeaders; // /// // /// Gets the ObjectListView that is being used as the source of the data // /// // public ObjectListView ListView { // get { return objectListView; } // } // private ObjectListView objectListView; // /// // /// Gets the model objects that are to be placed in the data object // /// // public IList ModelObjects { // get { return modelObjects; } // } // private IList modelObjects = new ArrayList(); // #endregion // /// // /// Put a text and HTML representation of our model objects // /// into the data object. // /// // public void CreateTextFormats() { // IList columns = this.IncludeHiddenColumns ? this.ListView.AllColumns : this.ListView.ColumnsInDisplayOrder; // // Build text and html versions of the selection // StringBuilder sbText = new StringBuilder(); // StringBuilder sbHtml = new StringBuilder(""); // // Include column headers // if (includeColumnHeaders) // { // sbHtml.Append(""); // } // foreach (object modelObject in this.ModelObjects) // { // sbHtml.Append(""); // } // sbHtml.AppendLine("
"); // foreach (OLVColumn col in columns) // { // if (col != columns[0]) // { // sbText.Append("\t"); // sbHtml.Append(""); // } // string strValue = col.Text; // sbText.Append(strValue); // sbHtml.Append(strValue); //TODO: Should encode the string value // } // sbText.AppendLine(); // sbHtml.AppendLine("
"); // foreach (OLVColumn col in columns) { // if (col != columns[0]) { // sbText.Append("\t"); // sbHtml.Append(""); // } // string strValue = col.GetStringValue(modelObject); // sbText.Append(strValue); // sbHtml.Append(strValue); //TODO: Should encode the string value // } // sbText.AppendLine(); // sbHtml.AppendLine("
"); // // Put both the text and html versions onto the clipboard. // // For some reason, SetText() with UnicodeText doesn't set the basic CF_TEXT format, // // but using SetData() does. // //this.SetText(sbText.ToString(), TextDataFormat.UnicodeText); // this.SetData(sbText.ToString()); // this.SetText(ConvertToHtmlFragment(sbHtml.ToString()), TextDataFormat.Html); // } // /// // /// Make a HTML representation of our model objects // /// // public string CreateHtml() { // IList columns = this.ListView.ColumnsInDisplayOrder; // // Build html version of the selection // StringBuilder sbHtml = new StringBuilder(""); // foreach (object modelObject in this.ModelObjects) { // sbHtml.Append(""); // } // sbHtml.AppendLine("
"); // foreach (OLVColumn col in columns) { // if (col != columns[0]) { // sbHtml.Append(""); // } // string strValue = col.GetStringValue(modelObject); // sbHtml.Append(strValue); //TODO: Should encode the string value // } // sbHtml.AppendLine("
"); // return sbHtml.ToString(); // } // /// // /// Convert the fragment of HTML into the Clipboards HTML format. // /// // /// The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx // /// // /// The HTML to put onto the clipboard. It must be valid HTML! // /// A string that can be put onto the clipboard and will be recognized as HTML // private string ConvertToHtmlFragment(string fragment) { // // Minimal implementation of HTML clipboard format // string source = "http://www.codeproject.com/KB/list/ObjectListView.aspx"; // const String MARKER_BLOCK = // "Version:1.0\r\n" + // "StartHTML:{0,8}\r\n" + // "EndHTML:{1,8}\r\n" + // "StartFragment:{2,8}\r\n" + // "EndFragment:{3,8}\r\n" + // "StartSelection:{2,8}\r\n" + // "EndSelection:{3,8}\r\n" + // "SourceURL:{4}\r\n" + // "{5}"; // int prefixLength = String.Format(MARKER_BLOCK, 0, 0, 0, 0, source, "").Length; // const String DEFAULT_HTML_BODY = // "" + // "{0}"; // string html = String.Format(DEFAULT_HTML_BODY, fragment); // int startFragment = prefixLength + html.IndexOf(fragment); // int endFragment = startFragment + fragment.Length; // return String.Format(MARKER_BLOCK, prefixLength, prefixLength + html.Length, startFragment, endFragment, source, html); // } // } //}