Beispiel #1
0
        //******************************************************************
        /// <summary>
        /// Pastes the features from the clipboard to the ListView. (The
        /// DisplayedNode and the ListView are both updated.)
        /// </summary>
        private void PasteFeatures()
        {
            Debug.Assert(DisplayedNode != null);

            //**************************************************************
            // Prevent modification if the feature collection is read-only.

            if (ReadOnly)
            {
                return;
            }

            //**************************************************************
            // Get the string data on the clipboard, or return (without
            // reporting an error) if there is no string data on the
            // clipboard.

            IDataObject oDataObject = Clipboard.GetDataObject();
            if (oDataObject == null)
            {
                return;
            }
            if (! oDataObject.GetDataPresent(typeof(string)))
            {
                return;
            }
            string sString = (string) oDataObject.GetData(typeof(string));
            if (sString == null)
            {
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if the string data does
            // not look at all like XML.

            if (sString.IndexOf("<") < 0)
            {
                return;
            }
            if (sString.IndexOf("/") < 0)
            {
                return;
            }
            if (sString.IndexOf(">") < 0)
            {
                return;
            }

            //**************************************************************
            // Use a RuleReader to read the first SyntaxNode represented by
            // the string data (that is, the root node of the find pattern
            // in the first rule).

            SyntaxNode oNode = null;
            try
            {
                TextReader oTextReader = new StringReader(sString);
                RuleReader oRuleReader = new RuleReader(oTextReader);
                if (oRuleReader.Read())
                {
                    oNode = oRuleReader.FindPatternRoot;
                }
                oRuleReader.Close();
            }
            catch (Exception oException)
            {
                string sCaption = "Paste";
                string sMessage = "Cannot paste because "
                    + "the clipboard data is not compatible."
                    + Environment.NewLine + Environment.NewLine
                    + "(" + oException.Message  + ")";
                MessageBox.Show(sMessage,sCaption,MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if a node was not read
            // (because the string data represented an empty collection of
            // rules).

            if (oNode == null)
            {
                return;
            }

            //**************************************************************
            // For each of the node's features, call SetFeature() to display
            // the feature in the ListView and to copy it to the
            // DisplayedNode.Features collection.

            foreach (SyntaxFeature oFeature in oNode.Features)
            {
                SetFeature(oFeature.Name,oFeature.Value);
            }

            //**************************************************************
            // In the ListView, select the features that were pasted.

            moListView.SelectedItems.Clear();
            foreach (ListViewItem oItem in moListView.Items)
            {
                string sName = oItem.SubItems[moNameColumn.Index].Text;
                if (oNode.Features.Contains(sName))
                {
                    oItem.Selected = true;
                }
            }

            //**************************************************************
            // Make sure the first selected feature is scrolled into view
            // and has focus within the ListView.

            if (moListView.SelectedItems.Count > 0)
            {
                moListView.SelectedItems[0].Focused = true;
                moListView.SelectedItems[0].EnsureVisible();
            }
        }
Beispiel #2
0
        //******************************************************************
        /// <summary>
        /// Loads and displays the indicated rule file (sFileName). The
        /// Modified property is set to false after the file is loaded.
        /// </summary>
        public void LoadRuleFile(string sFileName)
        {
            //**************************************************************
            // Validate the parameters.

            if ((sFileName == null) || (sFileName == ""))
            {
                string sMessage = "Invalid argument: "
                    + "RuleListViewer.LoadRuleFile() requires "
                    + "a file name that is not null or blank.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Clear the linked FindPatternViewer and ReplacePatternViewer.

            UpdateFindAndReplacePatternViewers(null);

            //**************************************************************
            // Reset the TreeTransferData object.

            ResetTreeTransferData();

            //**************************************************************
            // Clear the undo information.

            ClearUndoInformation();

            //**************************************************************
            // Clear the list of items in the ListView.

            moListView.Items.Clear();

            //**************************************************************
            // Create a RuleReader to read from the indicated rule file.

            StreamReader oStreamReader = new StreamReader(sFileName);
            RuleReader oRuleReader = new RuleReader(oStreamReader);

            //**************************************************************
            // For each rule loaded from the rule file, create a new rule
            // item and append it to the ListView.

            while (oRuleReader.Read())
            {
                RuleListViewerItem oRuleItem = new RuleListViewerItem();
                oRuleItem.Text
                    = oRuleReader.RuleName;
                oRuleItem.FindPatternRoot
                    = oRuleReader.FindPatternRoot;
                oRuleItem.ReplacePatternRoot
                    = oRuleReader.ReplacePatternRoot;
                moListView.Items.Add(oRuleItem);
            }

            //**************************************************************
            // Close the RuleReader.

            oRuleReader.Close();

            //**************************************************************
            // Select the first item in the ListView. Make sure it is
            // scrolled into view and has focus within the ListView.

            if (moListView.Items.Count > 0)
            {
                ListViewItem oItem = moListView.Items[0];
                oItem.Selected = true;
                oItem.EnsureVisible();
                oItem.Focused = true;
            }

            //**************************************************************
            // Set the Modified property to false.

            Modified = false;

            //**************************************************************
            // Raise the SelectionChanged event.

            OnSelectionChanged(new EventArgs());

            //**************************************************************
            // Raise the ListChanged event.

            OnListChanged(new EventArgs());
        }
        //******************************************************************
        // EXAMPLE UNDO INFORMATION FOR A PASTE OPERATION
        //
        // Before the paste operation, suppose the ListView displays the
        // following items:
        //
        //     (index 0) Item-A
        //     (index 1) Item-B
        //     (index 2) Item-C (selected)
        //     (index 3) Item-D
        //     (index 4) Item-E
        //     (index 5) Item-F (selected)
        //     (index 6) Item-G
        //
        // Suppose the clipboard contains (Item-X,Item-Y,Item-Z). After the
        // paste operation, the ListView will display the following items:
        //
        //     (index 0) Item-A
        //     (index 1) Item-B
        //     (index 2) Item-X (selected)
        //     (index 3) Item-Y (selected)
        //     (index 4) Item-Z (selected)
        //     (index 5) Item-C
        //     (index 6) Item-D
        //     (index 7) Item-E
        //     (index 8) Item-F
        //     (index 9) Item-G
        //
        // And the undo information will contain:
        //
        //     FirstIndexForUndo = 2
        //     ItemCountForUndo = 3
        //     ParseTreesForUndo = ()
        //
        // This undo information indicates what is needed to reverse the
        // paste operation: replace the 3 items starting at index 2 with
        // the items in the ParseTreesForUndo collection (which in this case
        // contains no items).
        //******************************************************************
        /// <summary>
        /// Pastes the current contents of the clipboard.
        /// </summary>
        public void Paste()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanPaste())
            {
                string sMessage = "Invalid state: "
                    + "A call to ParseListViewer.Paste() is not allowed "
                    + "if ParseListViewer.CanPaste() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Prevent modification to a read-only list.

            if (ReadOnly)
            {
                return;
            }

            //**************************************************************
            // Clear the undo information.

            ClearUndoInformation();

            //**************************************************************
            // Get the string data on the clipboard, or return (without
            // reporting an error) if there is no string data on the
            // clipboard.

            IDataObject oDataObject = Clipboard.GetDataObject();
            if (oDataObject == null)
            {
                return;
            }
            if (! oDataObject.GetDataPresent(typeof(string)))
            {
                return;
            }
            string sString = (string) oDataObject.GetData(typeof(string));
            if (sString == null)
            {
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if the string data does
            // not look at all like XML.

            if (sString.IndexOf("<") < 0)
            {
                return;
            }
            if (sString.IndexOf("/") < 0)
            {
                return;
            }
            if (sString.IndexOf(">") < 0)
            {
                return;
            }

            //**************************************************************
            // Use a RuleReader to read the all the rules represented by the
            // string data.
            //
            // Each rule is interpreted as a parse tree: the .RuleName will
            // be the displayed text in the list, the .FindPatternRoot is
            // the parse tree, and the .ReplacePatternRoot is ignored.

            TransferRuleCollection oParseTrees
                = new TransferRuleCollection();
            try
            {
                TextReader oTextReader = new StringReader(sString);
                RuleReader oRuleReader = new RuleReader(oTextReader);
                while (oRuleReader.Read())
                {
                    TransferRule oRule = new TransferRule();
                    oRule.RuleName = oRuleReader.RuleName;
                    oRule.FindPatternRoot = oRuleReader.FindPatternRoot;
                    oRule.ReplacePatternRoot = null;
                    oParseTrees.Add(oRule);
                }
                oRuleReader.Close();
            }
            catch (Exception oException)
            {
                string sCaption = "Paste";
                string sMessage = "Cannot paste because "
                    + "the clipboard data is not compatible."
                    + Environment.NewLine + Environment.NewLine
                    + "(" + oException.Message  + ")";
                MessageBox.Show(sMessage,sCaption,MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if the collection of
            // parses (from the string data) is empty.

            if (oParseTrees.Count == 0)
            {
                return;
            }

            //**************************************************************
            // Set the Modified property to true.

            Modified = true;

            //**************************************************************
            // Determine the first index where the parses will be pasted.

            int iFirstIndex = 0;
            ParseListViewerItem oFirstSelectedItem = FirstSelectedItem();
            if (oFirstSelectedItem != null)
            {
                //**********************************************************
                // Insert before the first selected item in the list.

                iFirstIndex = oFirstSelectedItem.Index;
            }
            else
            {
                //**********************************************************
                // If no items are selected, append after the last item in
                // the list.

                iFirstIndex = moListView.Items.Count;
            }

            //**************************************************************
            // Paste the parses. (The pasted parses will be selected.)

            InsertParses(iFirstIndex,oParseTrees);

            Debug.Assert(FirstSelectedItem() != null);

            //**************************************************************
            // Set the undo information.

            FirstIndexForUndo = iFirstIndex;
            ItemCountForUndo = oParseTrees.Count;
            ParseTreesForUndo.Clear();

            //**************************************************************
            // Raise the ListChanged event.

            OnListChanged(new EventArgs());
        }
        //******************************************************************
        /// <summary>
        /// Pastes the current contents of the clipboard.
        /// </summary>
        public void Paste()
        {
            //**************************************************************
            // Validate the current state.

            if (! CanPaste())
            {
                string sMessage = "Invalid state: "
                    + "A call to ParseTreeViewer.Paste() is not allowed "
                    + "if ParseTreeViewer.CanPaste() returns false.";
                throw new Exception(sMessage);
            }

            //**************************************************************
            // Prevent modification to a read-only tree.

            if (ReadOnly)
            {
                return;
            }

            //**************************************************************
            // Use the current contents of the tree (before the paste
            // operation) to set the undo information.

            TreeTransferForUndo = RecreateTreeTransfer();

            //**************************************************************
            // Get the string data on the clipboard, or return (without
            // reporting an error) if there is no string data on the
            // clipboard.

            IDataObject oDataObject = Clipboard.GetDataObject();
            if (oDataObject == null)
            {
                return;
            }
            if (! oDataObject.GetDataPresent(typeof(string)))
            {
                return;
            }
            string sString = (string) oDataObject.GetData(typeof(string));
            if (sString == null)
            {
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if the string data does
            // not look at all like XML.

            if (sString.IndexOf("<") < 0)
            {
                return;
            }
            if (sString.IndexOf("/") < 0)
            {
                return;
            }
            if (sString.IndexOf(">") < 0)
            {
                return;
            }

            //**************************************************************
            // Get the branch to paste from the first tree represented by
            // the string data.

            SyntaxNode oSyntaxBranchToPaste = null;
            try
            {
                //**********************************************************
                // Use a RuleReader to read the first rule from the string.
                // Get the rule's FindPatternRoot as the branch to paste.

                TextReader oTextReader = new StringReader(sString);
                RuleReader oRuleReader = new RuleReader(oTextReader);
                if (oRuleReader.Read())
                {
                    oSyntaxBranchToPaste = oRuleReader.FindPatternRoot;
                }
                oRuleReader.Close();
            }
            catch (Exception oException)
            {
                string sCaption = "Paste";
                string sMessage = "Cannot paste because "
                    + "the clipboard data is not compatible."
                    + Environment.NewLine + Environment.NewLine
                    + "(" + oException.Message  + ")";
                MessageBox.Show(sMessage,sCaption,MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return;
            }

            //**************************************************************
            // Return (without reporting an error) if the branch to paste
            // (from the string data) is null.

            if (oSyntaxBranchToPaste == null)
            {
                return;
            }

            //**************************************************************
            // If the displayed tree is a find pattern or a replace pattern,
            // the labels of the new nodes should all be unique.

            if ((DisplayFindPattern) || (DisplayReplacePattern))
            {
                //**********************************************************
                // Collect all the node labels in the current tree. Then go
                // through the new branch and make sure all the nodes have
                // labels that are not already in use.

                SyntaxNode oSyntaxRoot = CloneTree();
                if (oSyntaxRoot != null)
                {
                    StringCollection oLabelsInUse = new StringCollection();
                    CollectLabelsInUse(oSyntaxRoot,oLabelsInUse);
                    RenameLabelsInUse(oSyntaxBranchToPaste,oLabelsInUse);
                }
            }

            //**************************************************************
            // Call BeginUpdate() to disable redrawing the tree, but not if
            // redrawing was already disabled by the calling code.

            bool bCallEndUpdate = false;
            if (! IsUpdating)
            {
                BeginUpdate();
                bCallEndUpdate = true;
            }

            //**************************************************************
            // If the root node is null or empty, paste a new tree.
            // Otherwise, paste a new child of the selected node.

            if (NodeIsNullOrEmpty(moTreeViewer.RootNode))
            {
                //**********************************************************
                // Paste the branch as the root of the tree. Select the new
                // root node.

                moTreeViewer.RootNode = new TreeViewerNode();
                PopulateBranch(moTreeViewer.RootNode,oSyntaxBranchToPaste);
                moTreeViewer.SelectedNode = moTreeViewer.RootNode;
            }
            else
            {
                //**********************************************************
                // Paste the branch as a child of the selected node. Select
                // the new child node that was pasted.

                if (moTreeViewer.SelectedNode != null)
                {
                    //******************************************************
                    // The entire branch dominated by the selected node will
                    // be repopulated. (This is because we want the pasted
                    // branch to be displayed, even if ShowMorphology is
                    // false and we are pasting a new morphology child of a
                    // leaf node).
                    //
                    // First, clone the entire branch dominated by the
                    // selected node. Delete the children of the selected
                    // node in the tree.

                    SyntaxNode oSyntaxParent
                        = CloneBranch(moTreeViewer.SelectedNode);
                    moTreeViewer.SelectedNode.ChildNodes.Clear();

                    //******************************************************
                    // Add the oSyntaxBranchToPaste as a child of the cloned
                    // branch. Then use the cloned branch to repopulate the
                    // branch in the tree dominated by the selected node.
                    //
                    // The oTreeTransfer.CurrentParseTreeNode is set to the
                    // oSyntaxBranchToPaste, so this new child will be the
                    // new selected node (even if it is a morphology node
                    // and ShowMorphology is false).

                    oSyntaxParent.ChildNodes.Add(oSyntaxBranchToPaste);
                    TreeTransfer oTreeTransfer = new TreeTransfer();
                    oTreeTransfer.CurrentParseTreeNode
                        = oSyntaxBranchToPaste;
                    PopulateBranch(moTreeViewer.SelectedNode,oSyntaxParent,
                        oTreeTransfer);
                }
            }

            //**************************************************************
            // Call EndUpdate() to redraw the tree, but not if redrawing was
            // already disabled by the calling code.

            if (bCallEndUpdate)
            {
                EndUpdate();
            }

            //**************************************************************
            // Set the Modified property to true and raise the TreeChanged
            // event.

            Modified = true;
            OnTreeChanged(new EventArgs());
        }