ViewerSaveChanges.cs
//
// This code is part of GrapeCity Documents for PDF samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System.IO;
using GrapeCity.Documents.Pdf;
using System.Drawing;
using GrapeCity.Documents.Text;

namespace GcPdfWeb.Samples
{
    // This sample demonstrates how to create custom save button.
    // In this example, we create a custom toolbar button which saves the document changes on the server.

    // This and other samples in this section demonstrate the features of GcPdfViewer
    // (a JavaScript PDF viewer control included with GcPdf), mainly the ability
    // to change PDF files (add or edit annotations and AcroForm fields, rotate pages etc.)
    // when the JS viewer on the client is supported by GcPdf running on the server.
    //
    // To enable the editing features of the viewer, its supportApi property must be set
    // to a URL on the server that implements all or some of the edit supporting APIs
    // that are known to/expected by the viewer. This GcPdf demo site provides those APIs,
    // which makes it possible to demonstrate the editing when you open the PDF viewer
    // in this sample. When you download this sample, in addition to the .NET Core
    // console app project that generates the sample PDF, an ASP.NET Core project is
    // also included in the download zip (located in the GcPdfViewerWeb sub-folder of the
    // downloaded zip), which also provides the necessary APIs. In particular, it includes
    // a project that implements the APIs and provides them via a special controller.
    // It is actually the same controller that is used by this GcPdf demo site, and which
    // can be used in any ASP.NET Core site to enable the viewer editing features.
    //
    // Look at the following files in the sample download zip for more info:
    // - GcPdfViewerWeb\SupportApiDemo: the sample ASP.NET Core web site.
    // - GcPdfViewerWeb\SupportApiDemo.sln: solution to build/run the sample web site.
    // - GcPdfViewerWeb\SupportApi: support API implementation (can be used in any site).
    // - GcPdfViewerWeb\SupportApi\Controllers\GcPdfViewerController.cs: support API controller.
    // 
    // Please note that this and other samples in this section are only available in C# at this time.
    //
    public class ViewerSaveChanges
    {
        public void CreatePDF(Stream stream)
        {
            GcPdfDocument doc = new GcPdfDocument();
            GcPdfGraphics g = doc.NewPage().Graphics;
            g.DrawString("In this example, we create a custom toolbar button which saves the document changes on the server.",
                new TextFormat() { Font = StandardFonts.Times, FontSize = 12 },
                new PointF(72, 72));
            doc.Save(stream);
        }

        public const string JS_CODE = @"
var viewer;
var React;
function findBaseUrl(options) {  
  var s = window.__baseUrl || ((options.supportApi || {}).apiUrl || '');
  return s[s.length - 1] !== '/' ? s + '/' : s; 
}
function createPdfViewer(selector, baseOptions) {
  // Prepare viewer options:
  var options = baseOptions || {};
  if(!options.supportApi) {
      options.supportApi = {
          apiUrl: (window.__baseUrl || '') + 'support-api/gc-pdf-viewer',
          token: window.afToken || '',
          webSocketUrl: false, 
          suppressInfoMessages: true, 
          suppressErrorMessages: true
      };
  }
  // Arbitrary data associated with the viewer. 
  // This data is sent to the server when the document is saved:        
  options.userData = { sampleName: 'SaveChangesSample', docName: new Date().getTime() + '.pdf' };
  // Create viewer instance:
  viewer = new GcPdfViewer(selector, options);
  // Add annotation editor:
  viewer.addAnnotationEditorPanel();
  // Create custom 'Save changes' button
  React = viewer.getType('React');
  viewer.toolbar.addItem({ 
    key: 'custom-save', 
    icon: { type: 'svg', content: React.createElement('svg', { xmlns: 'http://www.w3.org/2000/svg', version: '1.1', width: '24', height: '24', viewBox: '0 0 24 24', fill: '#ff0000' }, React.createElement('path', { d: 'M20.913 9.058c0.057-0.26 0.087-0.531 0.087-0.808 0-2.071-1.679-3.75-3.75-3.75-0.333 0-0.657 0.044-0.964 0.125-0.581-1.813-2.28-3.125-4.286-3.125-2.047 0-3.775 1.367-4.32 3.238-0.533-0.155-1.097-0.238-1.68-0.238-3.314 0-6 2.686-6 6s2.686 6 6 6h3v4.5h6v-4.5h5.25c2.071 0 3.75-1.679 3.75-3.75 0-1.845-1.333-3.379-3.087-3.692zM13.5 15v4.5h-3v-4.5h-3.75l5.25-5.25 5.25 5.25h-3.75z' })) }, 
    title: 'Save document',
    enabled: false,
    action: function() {
        // Save changes on server:
        viewer.saveChanges().then(function(result) {
            if(result) {
                var docUrl = findBaseUrl(options) + 'GetPdfFromCloud?docName=' + options.userData.docName + '&clientId=' + viewer.supportApi.clientId;
                viewer.open(docUrl).then(function() {
                    alert('The document is saved in the cloud. The service life of the document is 10 minutes.');
                });
            }
        });
    },
    onUpdate: function() {
        return {
            enabled: viewer.hasDocument,
            title: 'Save changes'
        };
    }
  });
  viewer.toolbarLayout.viewer.default.splice(0, 0, 'download');
  // Insert 'custom-save' item into viewer toolbar layout:
  viewer.toolbarLayout.viewer.default.splice(0, 0, 'custom-save');
  // Change annotationEditor toolbar layout:
  var annotationEditorButtons = ['custom-save', 'download', 'edit-select', 'edit-sign-tool', '$split', 'edit-text', 'edit-free-text', 'edit-ink', 'edit-square',
        'edit-circle', 'edit-line', 'edit-polyline', 'edit-polygon', 'edit-stamp', 'edit-link',
        '$split', 'edit-redact', 'edit-redact-apply', 'edit-erase', '$split', 'new-document', '$split', 'new-page', 'delete-page'];
  viewer.toolbarLayout.annotationEditor = { default: annotationEditorButtons, mobile: annotationEditorButtons, fullscreen: annotationEditorButtons };
  return viewer;
}";
    }
}