public void Paste() { int row = grid.Rows.GetFirstRow(DataGridViewElementStates.Selected); // If there's no item selected, just paste at the end. if (row < 0 || row >= source.Count) { row = source.Count; } var data = Clipboard.GetDataObject(); var entries = WordListEntries.FromDataObject(data); if (entries != null && entries.Items.Count > 0) { Paste(entries, row); } else { string text = Clipboard.GetText().Trim(); if (text.Contains("\n")) { return; } // If the cell is being edited, Ctrl-V will be handled by the textbox itself // so this code is only visited when a paste occurs with textual data on an // entry which isn't currently being edited. WordListEntry item = RowSource(row); if (item == null || row == rowInEdit) { Paste(new WordListEntries(source, new[] { new WordListEntry(source, text, string.Empty) }), row); return; } string phrase = item.Phrase, translation = item.Translation; if (grid.CurrentCellAddress.X == 0) { phrase = text; } else { translation = text; } if (row >= 0 && row < source.Count) { // Re-create the row source so that an undo list entry gets made. source[row] = new WordListEntry(source, phrase, translation); if (!grid.IsRowVisible(row)) { grid.FirstDisplayedScrollingRowIndex = row; } } } }
// Starts a drag operation if the mouse leaves the drag box with the button held down. void grid_MouseMove(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } if (!grid.DragRectangle.IsEmpty && !grid.DragRectangle.Contains(e.Location)) { bool hitSelectedRow = grid.IsRowSelected(grid.DragRow); // The drag data has to be computed when the mouse moves out of the drag rectangle, not on MouseDown, // because we need to wait for the mouse down to possibly affect the selection (such as extending it // or contracting it, which are done at MouseDown time). var rows = new List <WordListEntry>(); if (hitSelectedRow) { // TODO: This won't include the row currently being edited, if one exists! foreach (int row in SelectedEntryIndices) { rows.Add(source[row]); } } else { // TODO: For now, let's not try to drag uncommitted rows. if (grid.DragRow < 0 || grid.DragRow > source.Count) { return; } rows.Add(source[grid.DragRow]); grid.SelectRow(grid.DragRow); } dragData = new WordListEntries(source, rows); var data = dragData.MakeDataObject(); var result = grid.DoDragDrop(data, DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll); // If we moved the items, we have to delete the original ones now. // This doesn't exactly look great in the undo list, but it's very unlikely that // we'll be able to tie together undo items related to multiple lists. if (result == DragDropEffects.Move) { var indices = new List <int>(); foreach (var entry in dragData.Items) { int i = source.IndexOf(entry); indices.Add(i); } source.RemoveAt(indices); } } }
void CopyRowsFromTo(WordListEntries entries, int dropRow) { var copies = new List <WordListEntry>(); foreach (var e in entries.Items) { copies.Add(e.Clone()); } source.Insert(dropRow, copies); }
void Paste(WordListEntries entries, int?row) { // Clone the entries if they're from a different word list. // Maybe this is a bit paranoid. for (int i = 0; i < entries.Items.Count; ++i) { if (entries.Items[i].Owner != source) { entries.Items[i] = entries.Items[i].Clone(); } } int actualRow = row ?? source.Count; source.Insert(actualRow, entries.Items); grid.SelectRowBlock(actualRow, entries.Items.Count); }
void Paste(WordListEntries entries, int? row) { // Clone the entries if they're from a different word list. // Maybe this is a bit paranoid. for (int i = 0; i < entries.Items.Count; ++i) if (entries.Items[i].Owner != source) entries.Items[i] = entries.Items[i].Clone(); int actualRow = row ?? source.Count; source.Insert(actualRow, entries.Items); grid.SelectRowBlock(actualRow, entries.Items.Count); }
// Starts a drag operation if the mouse leaves the drag box with the button held down. void grid_MouseMove(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; if (!grid.DragRectangle.IsEmpty && !grid.DragRectangle.Contains(e.Location)) { bool hitSelectedRow = grid.IsRowSelected(grid.DragRow); // The drag data has to be computed when the mouse moves out of the drag rectangle, not on MouseDown, // because we need to wait for the mouse down to possibly affect the selection (such as extending it // or contracting it, which are done at MouseDown time). var rows = new List<WordListEntry>(); if (hitSelectedRow) { // TODO: This won't include the row currently being edited, if one exists! foreach (int row in SelectedEntryIndices) rows.Add(source[row]); } else { // TODO: For now, let's not try to drag uncommitted rows. if (grid.DragRow < 0 || grid.DragRow > source.Count) return; rows.Add(source[grid.DragRow]); grid.SelectRow(grid.DragRow); } dragData = new WordListEntries(source, rows); var data = dragData.MakeDataObject(); var result = grid.DoDragDrop(data, DragDropEffects.Move | DragDropEffects.Copy | DragDropEffects.Scroll); // If we moved the items, we have to delete the original ones now. // This doesn't exactly look great in the undo list, but it's very unlikely that // we'll be able to tie together undo items related to multiple lists. if (result == DragDropEffects.Move) { var indices = new List<int>(); foreach (var entry in dragData.Items) { int i = source.IndexOf(entry); indices.Add(i); } source.RemoveAt(indices); } } }
void CopyRowsFromTo(WordListEntries entries, int dropRow) { var copies = new List<WordListEntry>(); foreach (var e in entries.Items) copies.Add(e.Clone()); source.Insert(dropRow, copies); }
// Finishes the drag operation and updates the selection. void grid_DragDrop(object sender, DragEventArgs e) { grid.RemoveDropMarker(); var clientPoint = grid.PointToClient(new Point(e.X, e.Y)); int dropRow = GetDropRow(clientPoint.X, clientPoint.Y); if (dropRow < 0) { return; } if (dropRow >= source.Count) { dropRow = source.Count; } var entries = WordListEntries.FromDataObject(e.Data); // Were the entries moved or copied? bool moved = false; if (entries != null && entries.WordList == this.source) { // Copying from the grid to itself requires a bit more care. if (e.Effect == DragDropEffects.Move) { moved = true; // Dragging rows from this grid to itself: i.e. re-ordering the rows. source.MoveRows(new List <int>(entries.Indices), dropRow); // Set the drag result to None, so that the results won't be removed *again*. e.Effect = DragDropEffects.None; } else { CopyRowsFromTo(entries, dropRow); } } else if (entries != null) { // Copying/moving from some other word list, or a non-wordlist source CopyRowsFromTo(entries, dropRow); } // TODO: This doesn't seem to work if the drop row is the last row in the grid. if (entries != null && entries.Items.Count > 0) { int firstRow = dropRow; // If we're moving, not copying, we don't know where the rows were actually put, // because the rows may have been shifted. Instead, find where they actually are. if (moved) { firstRow = source.IndexOf(entries.Items[0]); } if (firstRow > -1) { grid.SelectRowBlock(firstRow, entries.Items.Count); } } }