TX Text Control .NET Server

Document Protection

Topic

A contract that customers may complete only in a few places is protected: its text can be read and selected, and only marked passages can be changed. The protection itself applies in the Document Editor, while the server prepares and processes the documents. Your code marks editable regions for everyone or for single users, reads the text users entered there and removes the regions before the document is finalized.

How users protect a document with a password and which permissions a protected document has is the subject of Document Protection in the Document Editor section. Passwords and access permissions of PDF files are a different mechanism, set when a document is saved as PDF.

How Document Protection Works

A protected document is opened in the Document Editor with the edit mode ReadAndSelect. In this mode, the text is read-only, and the permissions stored in the document apply, for example whether text can be formatted or printed. Editable regions are the exceptions:

  • An editable region is a range of text that stays editable in a protected document. It's editable by everyone or only by the user whose name the region carries.
  • The users who work with the editor are passed to it with TextControlSettings.UserNames. A user can change the regions marked with their name and the regions without a name.
  • Regions can overlap. A region that overlaps or directly follows another region with the same user name and ID is combined with it.

ServerTextControl has no edit mode and no document permissions, so passwords and permissions are set in the Document Editor. On the server, you work with the editable regions: ServerTextControl.EditableRegions returns the EditableRegionCollection of the main text, and HeaderFooter.EditableRegions and TextFrame.EditableRegions those of a header, footer or text frame.

What the Document Permissions Are

The permissions of a protected document, such as whether it can be formatted, copied or printed, are the properties of the DocumentPermissions class, which The Document Permissions in the Document Editor lists. All of them are true by default, including ReadOnly, AllowFormattingStyles works only together with AllowFormatting, and the permissions take effect when the edit mode changes from Edit to ReadAndSelect. A document protected with a password keeps the permissions and the password in encrypted form in RTF, DOC, DOCX, PDF and the TX Text Control format, and it opens read-only.

ServerTextControl has no property that returns a DocumentPermissions object. On the server, the class is reachable through TextViewGenerator.DocumentPermissions together with TextViewGenerator.EditMode, a special kind of ServerTextControl that renders the document as images. In the Document Editor, users set the permissions on the Permissions tab, as Document Protection shows.

Mark Editable Regions

The following program writes a short contract with a header, marks the customer name as editable for everyone, the approver as editable for one user and a reference number in the header as editable for everyone. It saves the document in the TX Text Control format:

using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    tx.Text = "Service Agreement\r\n" +
        "Customer: [Customer name]\r\n" +
        "Approved by: [Approver]\r\n" +
        "The terms of this agreement are fixed.";

    // An empty user name makes a region editable for everyone
    AddRegion(tx.EditableRegions, tx.Find("[Customer name]"), "[Customer name]", "", 1);
    AddRegion(tx.EditableRegions, tx.Find("[Approver]"), "[Approver]", "Paul Proof", 2);

    tx.HeadersAndFooters.Add(HeaderFooterType.Header);
    HeaderFooter header = tx.HeadersAndFooters.GetItem(HeaderFooterType.Header);
    header.Selection.Text = "Reference: [Reference]";

    AddRegion(header.EditableRegions, header.Find("[Reference]", 0, FindOptions.MatchCase), "[Reference]", "", 3);

    tx.Save("Documents/contract.tx", StreamType.InternalUnicodeFormat);
}

static void AddRegion(EditableRegionCollection regions, int position, string text, string userName, int id)
{
    if (position == -1)
    {
        Console.WriteLine($"{text} wasn't found.");
        return;
    }

    // Find returns a zero-based position, the region expects a one-based start
    EditableRegion region = new EditableRegion(userName, id, position + 1, text.Length);
    EditableRegionCollection.AddResult result = regions.Add(region);

    Console.WriteLine($"{text}: {result}");
}

The code works as follows:

  • ServerTextControl.Find and HeaderFooter.Find return the zero-based position of the text in the main text and in the header, or -1. HeaderFooter.Find has one overload only, which also takes the position to start at and a value of FindOptions.
  • The EditableRegion constructor takes the user name, a one-based ID, the one-based start position and the length. A user name that is null or empty means everyone, and the ID 0 means no ID. Without a start position and length, Add uses the current selection.
  • EditableRegionCollection.Add returns an AddResult: Successful, Combined when the region was merged with another one, PositionInvalid, NoSelection, SelectionTooComplex or Error.
  • The document is saved in the TX Text Control format, in which the Document Editor loads it with its editable regions.

The document now has three editable regions but no protection yet. When it's opened for Paul Proof in ReadAndSelect, as Open a Protected Document shows, Paul Proof can change the customer name, the approver and the reference, and the rest of the text is read-only.

Read What Users Entered

After users have edited their regions and the document is back on the server, the regions tell you what they entered. The following program lists all regions, saves the text of the approver region as HTML and saves a final DOCX without the regions:

using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/contract.tx", StreamType.InternalUnicodeFormat);

    foreach (IFormattedText textPart in tx.TextParts)
    {
        foreach (EditableRegion region in textPart.EditableRegions)
        {
            string user = string.IsNullOrEmpty(region.UserName) ? "everyone" : region.UserName;
            Console.WriteLine($"Region {region.ID} ({user}) at {region.Start}: \"{region.Text}\"");
        }
    }

    // null if no region of the main text has the ID 2
    EditableRegion approver = tx.EditableRegions.GetItem(2);

    if (approver != null)
    {
        approver.Save(out string html, StringStreamType.HTMLFormat);
        File.WriteAllText("approver.html", html);

        // false: the complete region is removed, its text stays
        tx.EditableRegions.Remove(approver, false);
    }

    // Leave out the markers of the remaining regions, keep their text
    SaveSettings saveSettings = new SaveSettings()
    {
        OmittedContent = OmittedContent.EditableRegions
    };

    tx.Save("contract-final.docx", StreamType.WordprocessingML, saveSettings);
}

The code works as follows:

  • ServerTextControl.TextParts contains the main text, the text frames and the headers and footers, each with its EditableRegions.
  • UserName, ID, Start and Text describe a region. Number counts the regions in the text flow from 1.
  • GetItem returns the first region with an ID, or null. GetItems returns the regions at the input position.
  • EditableRegion.Save writes the text of a region to a string or a byte array in a format you choose.
  • EditableRegionCollection.Remove removes a region but not its text. With true as the second parameter, it removes only the part of the region that is selected, which can split the region in two.
  • OmittedContent.EditableRegions saves the document without its editable regions; the text and its formatting are saved. This setting can't be used for PDF.

Events of Editable Regions

EditableRegionCreated and EditableRegionDeleted occur when a region is created or deleted. The EditableRegionEventArgs contain the region; in an EditableRegionDeleted handler, only its UserName, ID and highlight settings are still valid. Events lists all events of ServerTextControl.

Single fields can be protected as well: TextField.Editable and Deleteable decide whether users can change or delete a field, as Fields describes.

The blog article Document Protection in ASP.NET with TX Text Control: Healthcare Use Cases combines editable regions, users and the Document Editor in an application.

Next Steps