コード例 #1
0
ファイル: Clipboard.cs プロジェクト: bzquan/GherkinEditor
        /// <summary>
        /// Copy data from Clipboard and put on grid.
        ///
        /// Currently ReoGrid supports the following types of source from the clipboard.
        ///  - Data from another ReoGrid instance
        ///  - Plain/Unicode Text from any Windows Applications
        ///  - Tabbed Plain/Unicode Data from Excel or similar applications
        ///
        /// When data copied from another ReoGrid instance, and the destination range
        /// is bigger than the source, ReoGrid will try to repeat putting data to fill
        /// the destination range entirely.
        ///
        /// Todo: Copy border and cell style from Excel.
        /// </summary>
        public bool Paste()
        {
            if (IsEditing)
            {
                this.controlAdapter.EditControlPaste();
            }
            else
            {
                // Paste method will always perform action to do paste

                // do nothing if in readonly mode
                if (this.HasSettings(WorksheetSettings.Edit_Readonly)
                    // or selection is empty
                    || this.selectionRange.IsEmpty)
                {
                    return(false);
                }

                try
                {
                    this.controlAdapter.ChangeCursor(CursorStyle.Busy);

                    PartialGrid partialGrid   = null;
                    string      clipboardText = null;

#if WINFORM || WPF
                    DataObject data = Clipboard.GetDataObject() as DataObject;
                    if (data != null)
                    {
                        partialGrid = data.GetData(ClipBoardDataFormatIdentify) as PartialGrid;

                        if (data.ContainsText())
                        {
                            clipboardText = data.GetText();
                        }
                    }
#elif ANDROID
#endif // WINFORM || WPF

                    if (partialGrid != null)
                    {
                        #region Partial Grid Pasting
                        int startRow = selectionRange.Row;
                        int startCol = selectionRange.Col;

                        int rows = partialGrid.Rows;
                        int cols = partialGrid.Columns;

                        int rowRepeat = 1;
                        int colRepeat = 1;

                        if (selectionRange.Rows % partialGrid.Rows == 0)
                        {
                            rows      = selectionRange.Rows;
                            rowRepeat = selectionRange.Rows / partialGrid.Rows;
                        }
                        if (selectionRange.Cols % partialGrid.Columns == 0)
                        {
                            cols      = selectionRange.Cols;
                            colRepeat = selectionRange.Cols / partialGrid.Columns;
                        }

                        var targetRange = new RangePosition(startRow, startCol, rows, cols);

                        if (!RaiseBeforePasteEvent(targetRange))
                        {
                            return(false);
                        }

                        if (targetRange.EndRow >= this.rows.Count ||
                            targetRange.EndCol >= this.cols.Count)
                        {
                            // TODO: paste range overflow
                            // need to notify user-code to handle this
                            return(false);
                        }

                        // check any intersected merge-range in partial grid
                        //
                        bool cancelPerformPaste = false;

                        if (partialGrid.Cells != null)
                        {
                            try
                            {
                                #region Check repeated intersected ranges
                                for (int rr = 0; rr < rowRepeat; rr++)
                                {
                                    for (int cc = 0; cc < colRepeat; cc++)
                                    {
                                        partialGrid.Cells.Iterate((row, col, cell) =>
                                        {
                                            if (cell.IsMergedCell)
                                            {
                                                for (int r = startRow; r < cell.MergeEndPos.Row - cell.InternalRow + startRow + 1; r++)
                                                {
                                                    for (int c = startCol; c < cell.MergeEndPos.Col - cell.InternalCol + startCol + 1; c++)
                                                    {
                                                        int tr = r + rr * partialGrid.Rows;
                                                        int tc = c + cc * partialGrid.Columns;

                                                        var existedCell = cells[tr, tc];

                                                        if (existedCell != null)
                                                        {
                                                            if (
                                                                // cell is a part of merged cell
                                                                (existedCell.Rowspan == 0 && existedCell.Colspan == 0)
                                                                // cell is merged cell
                                                                || existedCell.IsMergedCell)
                                                            {
                                                                throw new RangeIntersectionException(selectionRange);
                                                            }
                                                            // cell is readonly
                                                            else if (existedCell.IsReadOnly)
                                                            {
                                                                throw new CellDataReadonlyException(cell.InternalPos);
                                                            }
                                                        }
                                                    }
                                                }
                                            }

                                            return(Math.Min(cell.Colspan, (short)1));
                                        });
                                    }
                                }
                                #endregion                                 // Check repeated intersected ranges
                            }
                            catch (Exception ex)
                            {
                                cancelPerformPaste = true;

                                // raise event to notify user-code there is error happened during paste operation
                                if (OnPasteError != null)
                                {
                                    OnPasteError(this, new RangeOperationErrorEventArgs(selectionRange, ex));
                                }
                            }
                        }

                        if (!cancelPerformPaste)
                        {
                            DoAction(new SetPartialGridAction(new RangePosition(
                                                                  startRow, startCol, rows, cols), partialGrid));
                        }

                        #endregion                         // Partial Grid Pasting
                    }
                    else if (!string.IsNullOrEmpty(clipboardText))
                    {
                        #region Plain Text Pasting
                        var arrayData = RGUtility.ParseTabbedString(clipboardText);

                        int rows = Math.Max(selectionRange.Rows, arrayData.GetLength(0));
                        int cols = Math.Max(selectionRange.Cols, arrayData.GetLength(1));

                        // by bzquan expand rows of worksheet
                        if (this.RowCount < rows)
                        {
                            this.RowCount = rows + 1;
                        }

                        var targetRange = new RangePosition(selectionRange.Row, selectionRange.Col, rows, cols);
                        if (!RaiseBeforePasteEvent(targetRange))
                        {
                            return(false);
                        }

                        if (this.controlAdapter != null)
                        {
                            var actionSupportedControl = this.controlAdapter.ControlInstance as IActionControl;

                            if (actionSupportedControl != null)
                            {
                                actionSupportedControl.DoAction(this, new SetRangeDataAction(targetRange, arrayData));
                            }
                        }
                        #endregion                         // Plain Text Pasting
                    }
                }
                catch (Exception ex)
                {
                    // raise event to notify user-code there is error happened during paste operation
                    //if (OnPasteError != null)
                    //{
                    //	OnPasteError(this, new RangeOperationErrorEventArgs(selectionRange, ex));
                    //}
                    this.NotifyExceptionHappen(ex);
                }
                finally
                {
                    this.controlAdapter.ChangeCursor(CursorStyle.Selection);

                    RequestInvalidate();
                }

                if (AfterPaste != null)
                {
                    AfterPaste(this, new RangeEventArgs(this.selectionRange));
                }
            }

            return(true);
        }
コード例 #2
0
ファイル: Clipboard.cs プロジェクト: datadiode/ReoGrid
        /// <summary>
        /// Copy data from Clipboard and put on grid.
        ///
        /// Currently ReoGrid supports the following types of source from the clipboard.
        ///  - Data from another ReoGrid instance
        ///  - Plain/Unicode Text from any Windows Applications
        ///  - Tabbed Plain/Unicode Data from Excel or similar applications
        ///
        /// When data copied from another ReoGrid instance, and the destination range
        /// is bigger than the source, ReoGrid will try to repeat putting data to fill
        /// the destination range entirely.
        ///
        /// Todo: Copy border and cell style from Excel.
        /// </summary>
        public bool Paste()
        {
            if (IsEditing)
            {
                this.controlAdapter.EditControlPaste();
            }
            else
            {
                // Paste method will always perform action to do paste

                // do nothing if in readonly mode
                if (this.HasSettings(WorksheetSettings.Edit_Readonly)
                    // or selection is empty
                    || this.selectionRange.IsEmpty)
                {
                    return(false);
                }

                try
                {
                    this.controlAdapter.ChangeCursor(CursorStyle.Busy);

                    PartialGrid partialGrid   = null;
                    string      clipboardText = null;

#if WINFORM || WPF
                    DataObject data = Clipboard.GetDataObject() as DataObject;
                    if (data != null)
                    {
                        partialGrid = data.GetData(ClipBoardDataFormatIdentify) as PartialGrid;

                        if (data.ContainsText())
                        {
                            clipboardText = data.GetText();
                        }
                    }
#elif ANDROID
#endif // WINFORM || WPF

                    if (partialGrid != null)
                    {
                        #region Partial Grid Pasting
                        int startRow = selectionRange.Row;
                        int startCol = selectionRange.Col;

                        int rows = partialGrid.Rows;
                        int cols = partialGrid.Columns;

                        int rowRepeat = 1;
                        int colRepeat = 1;

                        if (selectionRange.Rows % partialGrid.Rows == 0)
                        {
                            rows      = selectionRange.Rows;
                            rowRepeat = selectionRange.Rows / partialGrid.Rows;
                        }
                        if (selectionRange.Cols % partialGrid.Columns == 0)
                        {
                            cols      = selectionRange.Cols;
                            colRepeat = selectionRange.Cols / partialGrid.Columns;
                        }

                        var targetRange = new RangePosition(startRow, startCol, rows, cols);

                        if (!RaiseBeforePasteEvent(targetRange))
                        {
                            return(false);
                        }

                        if (targetRange.EndRow >= this.rows.Count ||
                            targetRange.EndCol >= this.cols.Count)
                        {
                            // TODO: paste range overflow
                            // need to notify user-code to handle this
                            return(false);
                        }

                        // check whether the range to be pasted contains readonly cell
                        if (this.CheckRangeReadonly(targetRange))
                        {
                            this.NotifyExceptionHappen(new OperationOnReadonlyCellException("specified range contains readonly cell"));
                            return(false);
                        }

                        DoAction(new SetPartialGridAction(new RangePosition(
                                                              startRow, startCol, rows, cols), partialGrid));

                        #endregion                         // Partial Grid Pasting
                    }
                    else if (!string.IsNullOrEmpty(clipboardText))
                    {
                        #region Plain Text Pasting
                        var arrayData = RGUtility.ParseTabbedString(clipboardText);

                        int rows = Math.Max(selectionRange.Rows, arrayData.GetLength(0));
                        int cols = Math.Max(selectionRange.Cols, arrayData.GetLength(1));

                        var targetRange = new RangePosition(selectionRange.Row, selectionRange.Col, rows, cols);
                        if (!RaiseBeforePasteEvent(targetRange))
                        {
                            return(false);
                        }

                        if (this.controlAdapter != null)
                        {
                            var actionSupportedControl = this.controlAdapter.ControlInstance as IActionControl;

                            if (actionSupportedControl != null)
                            {
                                actionSupportedControl.DoAction(this, new SetRangeDataAction(targetRange, arrayData));
                            }
                        }
                        #endregion                         // Plain Text Pasting
                    }
                }
                catch (Exception ex)
                {
                    // raise event to notify user-code there is error happened during paste operation
                    //if (OnPasteError != null)
                    //{
                    //	OnPasteError(this, new RangeOperationErrorEventArgs(selectionRange, ex));
                    //}
                    this.NotifyExceptionHappen(ex);
                }
                finally
                {
                    this.controlAdapter.ChangeCursor(CursorStyle.Selection);

                    RequestInvalidate();
                }

                if (AfterPaste != null)
                {
                    AfterPaste(this, new RangeEventArgs(this.selectionRange));
                }
            }

            return(true);
        }