diff --git a/Demos/ASP.NET Core/README.md b/Demos/ASP.NET Core/README.md index ce30905dd..b663f8ef3 100644 --- a/Demos/ASP.NET Core/README.md +++ b/Demos/ASP.NET Core/README.md @@ -19,29 +19,15 @@ GroupDocs.Viewer supports over [170 file-formats](https://docs.groupdocs.com/vie

## Features - -- Clean, modern and intuitive design -- Easily switchable colour theme (create your own colour theme in 5 minutes) - Responsive design -- Mobile support (open application on any mobile device) -- Support over 170 document and image formats including **DOCX**, **PPTX**, and **XLSX** -- HTML and image modes -- Fully customizable navigation panel -- Open password protected documents +- Fully customizable navigation panel & thumbnails - Text searching & highlighting -- Download documents -- Upload documents -- Print document -- Rotate pages +- Download & upload documents +- Print document as PDF - Zoom in/out documents without quality loss in HTML mode -- Thumbnails -- Smooth page navigation -- Smooth document scrolling +- Smooth page navigation & scrolling - Preload pages for faster document rendering -- Multi-language support for displaying errors -- Display two or more pages side by side (when zooming out) -- Cross-browser support (Safari, Chrome, Opera, Firefox) -- Cross-platform support (Windows, Linux, MacOS) +- Multi-language support ## How to run @@ -70,11 +56,15 @@ Open the app by navigating to in your favorite br The MIT License (MIT). -Please have a look at the LICENSE.md for more details +Please have a look at the [LICENSE](LICENSE) for more details -## GroupDocs Document Viewer on other platforms +## More Demo Projects -- [JAVA DropWizard Document Viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) -- [JAVA Spring Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [Java Dropwizard Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) +- [Java Spring Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [ASP.NET Web Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Web%20Forms) +- [ASP.NET MVC Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20MVC) +- [Windows Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/Windows%20Forms) +- [WPF Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/WPF) -[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) +[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Examples) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/ASP.NET Core/src/Files/password.pdf b/Demos/ASP.NET Core/src/Files/password.pdf deleted file mode 100644 index ea7e42868..000000000 Binary files a/Demos/ASP.NET Core/src/Files/password.pdf and /dev/null differ diff --git a/Demos/ASP.NET Core/src/Files/sample.docx b/Demos/ASP.NET Core/src/Files/sample.docx deleted file mode 100644 index 4f0190b8e..000000000 Binary files a/Demos/ASP.NET Core/src/Files/sample.docx and /dev/null differ diff --git a/Demos/ASP.NET Core/src/Files/sample.pdf b/Demos/ASP.NET Core/src/Files/sample.pdf deleted file mode 100644 index b290105ee..000000000 Binary files a/Demos/ASP.NET Core/src/Files/sample.pdf and /dev/null differ diff --git a/Demos/ASP.NET Core/src/Files/sample.pptx b/Demos/ASP.NET Core/src/Files/sample.pptx deleted file mode 100644 index 6a3fc4f71..000000000 Binary files a/Demos/ASP.NET Core/src/Files/sample.pptx and /dev/null differ diff --git a/Demos/ASP.NET Core/src/Files/sample.xlsx b/Demos/ASP.NET Core/src/Files/sample.xlsx deleted file mode 100644 index 21db220d8..000000000 Binary files a/Demos/ASP.NET Core/src/Files/sample.xlsx and /dev/null differ diff --git a/Demos/ASP.NET Core/src/GroupDocs.Viewer.AspNetCore.csproj b/Demos/ASP.NET Core/src/GroupDocs.Viewer.AspNetCore.csproj index 7f61ae328..5f53d4003 100644 --- a/Demos/ASP.NET Core/src/GroupDocs.Viewer.AspNetCore.csproj +++ b/Demos/ASP.NET Core/src/GroupDocs.Viewer.AspNetCore.csproj @@ -10,7 +10,7 @@ - + diff --git a/Demos/ASP.NET Core/src/Storage/Files/flowchart.vsdx b/Demos/ASP.NET Core/src/Storage/Files/flowchart.vsdx new file mode 100644 index 000000000..12db7e009 Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/flowchart.vsdx differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/groupdocs.pptx b/Demos/ASP.NET Core/src/Storage/Files/groupdocs.pptx new file mode 100644 index 000000000..d94d696dd Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/groupdocs.pptx differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/house-plan.dwg b/Demos/ASP.NET Core/src/Storage/Files/house-plan.dwg new file mode 100644 index 000000000..ff07697b5 Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/house-plan.dwg differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/invoice.xlsx b/Demos/ASP.NET Core/src/Storage/Files/invoice.xlsx new file mode 100644 index 000000000..f223175b2 Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/invoice.xlsx differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/resume.docx b/Demos/ASP.NET Core/src/Storage/Files/resume.docx new file mode 100644 index 000000000..1d9f67edb Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/resume.docx differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/resume.pdf b/Demos/ASP.NET Core/src/Storage/Files/resume.pdf new file mode 100644 index 000000000..ef4cae4db Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/resume.pdf differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/software-development-plan.mpp b/Demos/ASP.NET Core/src/Storage/Files/software-development-plan.mpp new file mode 100644 index 000000000..5e48341a2 Binary files /dev/null and b/Demos/ASP.NET Core/src/Storage/Files/software-development-plan.mpp differ diff --git a/Demos/ASP.NET Core/src/Storage/Files/vector-image.svg b/Demos/ASP.NET Core/src/Storage/Files/vector-image.svg new file mode 100644 index 000000000..6df8640de --- /dev/null +++ b/Demos/ASP.NET Core/src/Storage/Files/vector-image.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/MVC/.gitattributes b/Demos/ASP.NET MVC/.gitattributes similarity index 100% rename from Demos/MVC/.gitattributes rename to Demos/ASP.NET MVC/.gitattributes diff --git a/Demos/MVC/.gitignore b/Demos/ASP.NET MVC/.gitignore similarity index 100% rename from Demos/MVC/.gitignore rename to Demos/ASP.NET MVC/.gitignore diff --git a/Demos/WebForms/LICENSE b/Demos/ASP.NET MVC/LICENSE similarity index 100% rename from Demos/WebForms/LICENSE rename to Demos/ASP.NET MVC/LICENSE diff --git a/Demos/ASP.NET MVC/README.md b/Demos/ASP.NET MVC/README.md new file mode 100644 index 000000000..cca6d78b9 --- /dev/null +++ b/Demos/ASP.NET MVC/README.md @@ -0,0 +1,69 @@ +![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") + +# GroupDocs.Viewer for .NET ASP.NET MVC Demo + +![GitHub](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET) + +In order to demonstrate [GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) reach and powerful features we prepared **document viewer** demo. Which can be used as a standalone application or easily integrated into your project. + +## System Requirements +- .NET Framework 4.8 +- Visual Studio 2022 + +## Supported Document Formats + +GroupDocs.Viewer for .NET enables you to render Microsoft Word, Microsoft Excel, Microsoft PowerPoint, and many more file types in HTML, PDF, PNG, and JPEG formats. The complete list of the supported document and file formats can be found in the [Supported document formats](https://docs.groupdocs.com/viewer/net/supported-document-formats/) documentation article. + +## Demo Video + +

+ + + +

+ +## Features +- Responsive design +- Fully customizable navigation panel & thumbnails +- Text searching & highlighting +- Download & upload documents +- Print document as PDF +- Zoom in/out documents without quality loss in HTML mode +- Smooth page navigation & scrolling +- Preload pages for faster document rendering +- Multi-language support + +## How To Run + +Download the [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/archive/master.zip) from github or clone this repository: + +```bash +git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET +``` + +Navigate to `Demos\ASP.NET MVC\src` and open `GroupDocs.Viewer.AspNetMvc.sln` in Visual Studio. Build and run the project. + +Open the app by navigating to in your favorite browser. + +## Configuration + +You can configure this demo project in [Global.asax.cs](./src/Global.asax.cs) file in `ConfigureServices` method which includes configuration for GroupDocs.Viewer and UI. + +NOTE: without a license application will run in trial mode, [purchase a license](https://purchase.groupdocs.com/buy) or [request a temporary license](https://purchase.groupdocs.com/temporary-license). + +## License + +The MIT License (MIT). + +Please have a look at the [LICENSE](LICENSE) for more details + +## More Demo Projects + +- [Java Dropwizard Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) +- [Java Spring Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [ASP.NET Core Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Core) +- [ASP.NET Web Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Web%20Forms) +- [Windows Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/Windows%20Forms) +- [WPF Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/WPF) + +[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Examples) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/ASP.NET MVC/src/ActionResults/FileActionResult.cs b/Demos/ASP.NET MVC/src/ActionResults/FileActionResult.cs new file mode 100644 index 000000000..27f8cb376 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ActionResults/FileActionResult.cs @@ -0,0 +1,50 @@ +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetMvc.ActionResults +{ + internal class FileActionResult : IHttpActionResult + { + private readonly byte[] _data; + private readonly string _fileName; + private readonly string _contentType; + readonly HttpRequestMessage _request; + + public FileActionResult(byte[] data, string fileName, string contentType, + HttpRequestMessage request) + { + _data = data; + _fileName = fileName; + _contentType = contentType; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var response = new HttpResponseMessage + { + Content = new ByteArrayContent(_data), + StatusCode = HttpStatusCode.OK, + RequestMessage = _request + }; + + var contentType = string.IsNullOrEmpty(_contentType) + ? "application/octet-stream" + : _contentType; + + response.Content.Headers.ContentType = + new MediaTypeHeaderValue(contentType); + response.Content.Headers.ContentDisposition = + new ContentDispositionHeaderValue("attachment") + { + FileName = _fileName + }; + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/ActionResults/JsonActionResult.cs b/Demos/ASP.NET MVC/src/ActionResults/JsonActionResult.cs new file mode 100644 index 000000000..23a7920d2 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ActionResults/JsonActionResult.cs @@ -0,0 +1,39 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.ActionResults +{ + internal class JsonActionResult : IHttpActionResult + { + readonly object _value; + public HttpStatusCode StatusCode { get; set; } = HttpStatusCode.OK; + + readonly HttpRequestMessage _request; + + public JsonActionResult(object value, HttpRequestMessage request) + { + _value = value; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var json = JsonConvert.SerializeObject(_value, Formatting.Indented); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = new HttpResponseMessage + { + Content = content, + StatusCode = StatusCode, + RequestMessage = _request + }; + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/ActionResults/ResourceActionResult.cs b/Demos/ASP.NET MVC/src/ActionResults/ResourceActionResult.cs new file mode 100644 index 000000000..09a67c8c8 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ActionResults/ResourceActionResult.cs @@ -0,0 +1,40 @@ +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetMvc.ActionResults +{ + internal class ResourceActionResult : IHttpActionResult + { + private readonly byte[] _data; + private readonly string _contentType; + readonly HttpRequestMessage _request; + + public ResourceActionResult(byte[] data, string contentType, HttpRequestMessage request) + { + _data = data; + _contentType = contentType; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var response = new HttpResponseMessage + { + Content = new ByteArrayContent(_data), + StatusCode = HttpStatusCode.OK, + RequestMessage = _request + }; + + response.Content.Headers.ContentType = + new MediaTypeHeaderValue(_contentType); + response.Content.Headers.ContentDisposition + = new ContentDispositionHeaderValue("inline"); + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/MVC/src/App_Start/RouteConfig.cs b/Demos/ASP.NET MVC/src/App_Start/RouteConfig.cs similarity index 90% rename from Demos/MVC/src/App_Start/RouteConfig.cs rename to Demos/ASP.NET MVC/src/App_Start/RouteConfig.cs index bf6418998..f9e325661 100644 --- a/Demos/MVC/src/App_Start/RouteConfig.cs +++ b/Demos/ASP.NET MVC/src/App_Start/RouteConfig.cs @@ -1,19 +1,19 @@ -using System.Web.Mvc; -using System.Web.Routing; - -namespace GroupDocs.Viewer.MVC -{ - public class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Viewer", action = "Index", id = UrlParameter.Optional } - ); - } - } -} +using System.Web.Mvc; +using System.Web.Routing; + +namespace GroupDocs.Viewer.AspNetMvc +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Viewer", action = "Index", id = UrlParameter.Optional } + ); + } + } +} diff --git a/Demos/ASP.NET MVC/src/App_Start/WebApiConfig.cs b/Demos/ASP.NET MVC/src/App_Start/WebApiConfig.cs new file mode 100644 index 000000000..846ce4cff --- /dev/null +++ b/Demos/ASP.NET MVC/src/App_Start/WebApiConfig.cs @@ -0,0 +1,13 @@ +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetMvc +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + config.EnableCors(); + config.MapHttpAttributeRoutes(); + } + } +} diff --git a/Demos/ASP.NET MVC/src/ClientApp/.browserslistrc b/Demos/ASP.NET MVC/src/ClientApp/.browserslistrc new file mode 100644 index 000000000..427441dc9 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/.browserslistrc @@ -0,0 +1,17 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/Demos/WebForms/src/client/.gitignore b/Demos/ASP.NET MVC/src/ClientApp/.gitignore similarity index 79% rename from Demos/WebForms/src/client/.gitignore rename to Demos/ASP.NET MVC/src/ClientApp/.gitignore index ee5c9d833..86d943a9b 100644 --- a/Demos/WebForms/src/client/.gitignore +++ b/Demos/ASP.NET MVC/src/ClientApp/.gitignore @@ -4,10 +4,16 @@ /dist /tmp /out-tsc +# Only exists if Bazel was run +/bazel-out # dependencies /node_modules +# profiling files +chrome-profiler-events*.json +speed-measure-plugin*.json + # IDEs and editors /.idea .project @@ -23,6 +29,7 @@ !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +.history/* # misc /.sass-cache diff --git a/Demos/ASP.NET MVC/src/ClientApp/README.md b/Demos/ASP.NET MVC/src/ClientApp/README.md new file mode 100644 index 000000000..daf9ae209 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/README.md @@ -0,0 +1,19 @@ +# GroupdocsViewerUI + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.3. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/Demos/ASP.NET MVC/src/ClientApp/angular.json b/Demos/ASP.NET MVC/src/ClientApp/angular.json new file mode 100644 index 000000000..55575bfe2 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/angular.json @@ -0,0 +1,116 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "groupdocs-viewer-ui": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "inlineTemplate": true, + "inlineStyle": true, + "skipTests": true + }, + "@schematics/angular:class": { + "skipTests": true + }, + "@schematics/angular:directive": { + "skipTests": true + }, + "@schematics/angular:guard": { + "skipTests": true + }, + "@schematics/angular:interceptor": { + "skipTests": true + }, + "@schematics/angular:module": { + "skipTests": true + }, + "@schematics/angular:pipe": { + "skipTests": true + }, + "@schematics/angular:service": { + "skipTests": true + }, + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/assets" + ], + "styles": [], + "scripts": [], + "allowedCommonJsDependencies": [ + "hammerjs", "jquery" + ] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "index": { + "input": "src/index.prod.html", + "output": "index.html" + }, + "outputPath": "../assets", + "optimization": true, + "outputHashing": "none", + "sourceMap": false, + "namedChunks": false, + "extractLicenses": false, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "4000kb", + "maximumError": "5000kb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "5kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "groupdocs-viewer-ui:build" + }, + "configurations": { + "production": { + "browserTarget": "groupdocs-viewer-ui:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "groupdocs-viewer-ui:build" + } + } + } + } + } +} diff --git a/Demos/ASP.NET MVC/src/ClientApp/package.json b/Demos/ASP.NET MVC/src/ClientApp/package.json new file mode 100644 index 000000000..e6ff78140 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/package.json @@ -0,0 +1,31 @@ +{ + "name": "groupdocs-viewer-ui", + "version": "1.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --configuration=production" + }, + "private": true, + "dependencies": { + "@angular/animations": "^14.1.0", + "@angular/common": "^14.1.0", + "@angular/compiler": "^14.1.0", + "@angular/core": "^14.1.0", + "@angular/forms": "^14.1.0", + "@angular/platform-browser": "^14.1.0", + "@angular/platform-browser-dynamic": "^14.1.0", + "@angular/router": "^14.1.0", + "@groupdocs.examples.angular/viewer": "^0.8.92", + "rxjs": "^7.5.6", + "tslib": "^2.4.0", + "zone.js": "^0.11.7" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^14.1.0", + "@angular/cli": "^14.1.0", + "@angular/compiler-cli": "^14.1.0", + "@types/node": "^18.0.6", + "typescript": "^4.7.4" + } +} diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.html b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.html new file mode 100644 index 000000000..be08b9bd6 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.html @@ -0,0 +1,109 @@ + +
+
+ + + + + + + + + + +
{{currentPage}}/{{countPages}}
+ + + + + + + + + + + + +
+
+ +
+ + + {{'Present' | translate}} +
+
+
+
+ +
Viewer
+
{{getFileName()}}
+
+ + + + {{'Stop' | translate}} +
+
+
+
+ + + + + + +
+
+ {{secondsLeft}} +
+ + +
+
+ + + {{'Click' | translate}} {{'to open file' | translate}}
+ {{'Or drop file here' | translate}} +
+ + + + + +
diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.less b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.less new file mode 100644 index 000000000..5bf4280e9 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.less @@ -0,0 +1,256 @@ +@import (css) url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap'); +@import "./variables"; + +:host * { + font-family: 'Open Sans', Arial, Helvetica, sans-serif; +} + +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome, Edge, Opera and Firefox */ +} + +.current-page-number { + margin-left: 7px; + font-size : 14px; + color : @regent-gray; + width : 37px; + height : 37px; + line-height: 37px; + text-align : center; + + &.active { + color: #fff; + } +} + +.wrapper { + align-items: stretch; + height : 100%; + width : 100%; + position : fixed; + top : 0; + bottom : 0; + left : 0; + right : 0; +} + +.doc-panel { + display : flex; + height : calc(100vh - 60px); + flex-direction: row; +} + +.top-panel { + display : flex; + align-items: center; + width : 100%; +} + +.toolbar-panel { + background-color: @nav-main-background; + width : 100%; +} + +.toolbar-panel-right { + display: flex; + flex: 1; + place-content: flex-end; +} + +.btn-right { + margin-right: 7px; +} + +.smp-start-stop { + ::ng-deep .button { + flex-direction: row; + border: 1px solid; + border-radius: 5px; + padding: 0px 10px !important; + } +} + +.language-menu { + margin-right: 15px; +} + +.select-language-menu { + ::ng-deep .select { + width: 100%; + ::ng-deep .dropdown-menu { + overflow-y: scroll; + max-height: 90%; + } + } + + ::ng-deep .selected-value { + max-width: 100%; + } +} + +.thumbnails-button { + ::ng-deep .button { + margin-left: 0 !important; + } +} + + +::ng-deep .tools { + + .button, + .selected-value, + .nav-caret { + color: #fff !important; + + &.inactive { + color: @regent-gray !important; + } + } + + .button { + flex-flow: column; + } + + .select-left { + .select { + position: relative; + } + + .dropdown-menu { + top: 40px; + left: 0px; + } + } + + .select-right { + .select { + position: relative; + } + + .dropdown-menu { + top: 40px; + right: 0px; + } + } + + .dropdown-menu .option { + color: @dove-gray !important; + } + + .dropdown-menu .option:hover { + background-color: @folder !important; + } + + .icon-button { + margin: 0px 0px 0px 15px !important; + } + + .select { + width : 37px; + height : 37px; + margin-left: 7px; + line-height: 37px; + text-align : center; + } + + .slides-title { + color: white; + padding-left: 12px; + font-size: 18px; + } + + .slides-filename { + flex-grow: 1; + text-align: center; + color: white; + text-overflow: ellipsis; + white-space: nowrap; + padding-left: 20px; + overflow: hidden; + } + + .slides-buttons { + display: flex; + ::ng-deep .select { + color: white; + cursor: pointer; + } + } + + ::ng-deep .gd-nav-search-container + .icon-button { + margin: 0 0 0 7px !important; + } +} + +.slides-nav { + position: absolute; + right: 30px; + bottom: 30px; + display: flex; + ::ng-deep .button { + font-size: 37px; + background-color: @porcelain; + border-radius: 3px; + } + ::ng-deep .timer { + font-size: 42px; + line-height: 6px; + color: @regent-gray; + position: relative; + .seconds-remaining { + position: absolute; + margin-left: 5px; + font-size: 16px; + top: 18px; + left: 12px; + &.two-digits { + left: 6px !important; + } + } + } +} + +::ng-deep .page.presentation .gd-wrapper { + pointer-events: none; +} + +@media (max-width: 1037px) { + + .mobile-hide, + .current-page-number { + display: none; + } + + ::ng-deep .tools { + gd-button:nth-child(1)>.icon-button { + margin: 0px 0px 0px 10px !important; + } + + .icon-button { + height: 60px; + width : 60px; + } + + .gd-nav-search-btn { + .icon-button { + height: 37px; + width : 37px; + } + + .button { + font-size: 14px; + } + } + + .gd-nav-search-container { + top: 59px !important; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.ts b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.ts new file mode 100644 index 000000000..54b9deeda --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.component.ts @@ -0,0 +1,122 @@ +import { Component, ChangeDetectorRef } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +import { ViewerAppComponent, ViewerService, ViewerConfigService } from '@groupdocs.examples.angular/viewer'; +import { Api, ConfigService, ModalService, UploadFilesService, NavigateService, ZoomService, PagePreloadService, RenderPrintService, PasswordService, WindowService, LoadingMaskService, PageModel, TypedFileCredentials } from '@groupdocs.examples.angular/common-components'; + +import { TranslateService } from '@ngx-translate/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.less', './variables.less'] +}) +export class AppComponent extends ViewerAppComponent { + + configService: ConfigService; + viewerService: ViewerService; + pagesLoading: number[]; + http: HttpClient; + + constructor(viewerService: ViewerService, + modalService: ModalService, + viewerConfigService: ViewerConfigService, + uploadFilesService: UploadFilesService, + navigateService: NavigateService, + zoomService: ZoomService, + pagePreloadService: PagePreloadService, + renderPrintService: RenderPrintService, + passwordService: PasswordService, + windowService: WindowService, + loadingMaskService: LoadingMaskService, + http: HttpClient, + configService: ConfigService, + cdr: ChangeDetectorRef, + translate: TranslateService) { + + super(viewerService, + modalService, + viewerConfigService, + uploadFilesService, + navigateService, + zoomService, + pagePreloadService, + renderPrintService, + passwordService, + windowService, + loadingMaskService, + cdr, + translate); + + this.configService = configService; + this.viewerService = viewerService; + this.pagesLoading = []; + this.http = http; + } + + preloadPages(start: number, end: number) { + const pagesToLoad = []; + const isInitialLoad = start === 1; + const minPagesToLoad = this.viewerConfig.preloadPageCount; + const countPages = this.file.pages.length; + this.selectedPageNumber = 1; + + if (isInitialLoad) { + this.pagesLoading = []; + } + + for (let i = start; i <= end; i++) { + const page = this.file.pages.find(p => p.number === i); + if(page && page.data) { + continue; + } + + if (this.pagesLoading.indexOf(i) === -1) { + this.pagesLoading.push(i); + pagesToLoad.push(i); + } + } + + if (pagesToLoad.length > 0) { + const last = pagesToLoad[pagesToLoad.length - 1]; + if (!isInitialLoad && pagesToLoad.length < minPagesToLoad) { + const addPages = minPagesToLoad - pagesToLoad.length; + for (let i = last; i < last + addPages; i++) { + const pageNumber = i + 1; + + if (pageNumber <= countPages && this.pagesLoading.indexOf(pageNumber) === -1) { + pagesToLoad.push(pageNumber); + this.pagesLoading.push(pageNumber); + } + } + } + + this.loadPages(this.credentials, pagesToLoad).subscribe(( + (pages: any) => { + pages.forEach((page: PageModel) => { + const pageIndex = page.number - 1; + const currPage = this.file.pages[pageIndex]; + + if (currPage) { + currPage.data = page.data; + if (this.file.thumbnails[pageIndex]) { + this.file.thumbnails[pageIndex].data = page.data; + this.file.thumbnails[pageIndex].width = currPage.width; + this.file.thumbnails[pageIndex].height = currPage.height; + } + } + }); + } + )); + } + } + + loadPages(credentials: TypedFileCredentials, pages: number[]) { + return this.http.post(this.configService.getViewerApiEndpoint() + Api.LOAD_DOCUMENT_PAGE + "s", { + 'guid': credentials.guid, + 'fileType': credentials.fileType, + 'password': credentials.password, + 'pages': pages + }, Api.httpOptionsJson); + } +} diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/app/app.module.ts b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.module.ts new file mode 100644 index 000000000..645a436d3 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/app/app.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { APP_BASE_HREF } from '@angular/common'; + +import { AppComponent } from './app.component'; +import { ConfigService } from '@groupdocs.examples.angular/common-components'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { ViewerConfigService, ViewerModule } from '@groupdocs.examples.angular/viewer'; +import { BehaviorSubject, Observable } from 'rxjs'; + +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { ViewerTranslateLoader } from "@groupdocs.examples.angular/viewer"; + +declare global { + interface Window { + apiEndpoint: string; + uiSettingsPath: string; + } +} + +/* +export class StaticViewerConfigService { + public updatedConfig: Observable = new BehaviorSubject({ + pageSelector: true, + download: true, + upload: true, + print: true, + browse: true, + rewrite: true, + enableRightClick: true, + filesDirectory: "", + fontsDirectory: "", + defaultDocument: "", + watermarkText: "", + preloadPageCount: 3, + zoom: true, + search: true, + thumbnails: true, + rotate: false, + htmlMode: true, + cache: true, + saveRotateState: false, + printAllowed: true, + showGridLines: true, + showLanguageMenu: true, + defaultLanguage: 'en', + supportedLanguages: ['en', 'fr', 'de'] + }).asObservable(); + + load(): Promise { + return Promise.resolve(); + } +} +*/ + +export function configServiceFactory() { + let config = new ConfigService(); + config.apiEndpoint = window.apiEndpoint; + config.getViewerApiEndpoint = () => window.apiEndpoint; + config.getConfigEndpoint = () => window.uiSettingsPath; + return config; +} + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), + ViewerModule, + FontAwesomeModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: ViewerTranslateLoader + } + }) + ], + providers: [ + { provide: APP_BASE_HREF, useValue: '/' }, + { provide: ConfigService, useFactory: configServiceFactory }, +/* + { provide: ViewerConfigService, useClass: StaticViewerConfigService }, +*/ + { provide: 'WINDOW', useValue: window }, + ], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/app/variables.less b/Demos/ASP.NET MVC/src/ClientApp/src/app/variables.less new file mode 100644 index 000000000..6a8bedf1d --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/app/variables.less @@ -0,0 +1,31 @@ +@wide-screen-down: ~'(max-width: 1199px)'; +@desktop-down: ~'(max-width: 991px)'; +@tablet-down: ~'(max-width: 767px)'; +@phone-down: ~'(max-width: 1037px)'; +@small-phone-down: ~'(max-width: 320px)'; + +@nav-logo-background: #25c2d4; +@nav-main-background: #3e4e5a; +@nav-accent-background: #E5E5E5; +@nav-tabs-height: 30px; +@editor-nav-height: 90px; +@nav-tabs-height-m: 60px; +@nav-height: 60px; +@nav-icon-size: 20px; + +@primary: #3E4E5A; +@brand: #25c2d4; +@silver-chalice: #acacac; +@dove-gray: #6e6e6e; +@regent-gray: #959da5; +@wild-sand: #f4f4f4; +@mercury: #e7e7e7; +@silver: #c4c4c4; +@porcelain: #EDF0F2; + +@pdf: #e04e4e; +@word: #539CF0; +@powerpoint: #e29e1e; +@excel: #7cbc46; +@image: #c375ed; +@folder: #4b566c; diff --git a/Demos/MVC/src/DocumentSamples/Viewer/.gitkeep b/Demos/ASP.NET MVC/src/ClientApp/src/assets/.gitkeep similarity index 100% rename from Demos/MVC/src/DocumentSamples/Viewer/.gitkeep rename to Demos/ASP.NET MVC/src/ClientApp/src/assets/.gitkeep diff --git a/Demos/MVC/src/client/apps/viewer/src/environments/environment.prod.ts b/Demos/ASP.NET MVC/src/ClientApp/src/environments/environment.prod.ts similarity index 100% rename from Demos/MVC/src/client/apps/viewer/src/environments/environment.prod.ts rename to Demos/ASP.NET MVC/src/ClientApp/src/environments/environment.prod.ts diff --git a/Demos/MVC/src/client/apps/viewer/src/environments/environment.ts b/Demos/ASP.NET MVC/src/ClientApp/src/environments/environment.ts similarity index 100% rename from Demos/MVC/src/client/apps/viewer/src/environments/environment.ts rename to Demos/ASP.NET MVC/src/ClientApp/src/environments/environment.ts diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/application.ico b/Demos/ASP.NET MVC/src/ClientApp/src/favicon.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/application.ico rename to Demos/ASP.NET MVC/src/ClientApp/src/favicon.ico diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/index.html b/Demos/ASP.NET MVC/src/ClientApp/src/index.html new file mode 100644 index 000000000..0b3e826b6 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/index.html @@ -0,0 +1,16 @@ + + + + + + GroupDocs.Viewer UI + + + + + + + diff --git a/Demos/ASP.NET MVC/src/ClientApp/src/index.prod.html b/Demos/ASP.NET MVC/src/ClientApp/src/index.prod.html new file mode 100644 index 000000000..e42db0a95 --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/src/index.prod.html @@ -0,0 +1,17 @@ + + + + + + GroupDocs.Viewer UI + + + + + + + + diff --git a/Demos/MVC/src/client/apps/viewer/src/main.ts b/Demos/ASP.NET MVC/src/ClientApp/src/main.ts similarity index 85% rename from Demos/MVC/src/client/apps/viewer/src/main.ts rename to Demos/ASP.NET MVC/src/ClientApp/src/main.ts index fa4e0aef3..c7b673cf4 100644 --- a/Demos/MVC/src/client/apps/viewer/src/main.ts +++ b/Demos/ASP.NET MVC/src/ClientApp/src/main.ts @@ -8,6 +8,5 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule) +platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); diff --git a/Demos/MVC/src/client/apps/viewer/src/polyfills.ts b/Demos/ASP.NET MVC/src/ClientApp/src/polyfills.ts similarity index 94% rename from Demos/MVC/src/client/apps/viewer/src/polyfills.ts rename to Demos/ASP.NET MVC/src/ClientApp/src/polyfills.ts index 2f258e56c..d5f67bd91 100644 --- a/Demos/MVC/src/client/apps/viewer/src/polyfills.ts +++ b/Demos/ASP.NET MVC/src/ClientApp/src/polyfills.ts @@ -18,7 +18,9 @@ * BROWSER POLYFILLS */ -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +/** + * IE11 requires the following for NgClass support on SVG elements + */ // import 'classlist.js'; // Run `npm install --save classlist.js`. /** @@ -35,7 +37,7 @@ * will put import in the top of bundle, so user need to create a separate file * in this directory (for example: zone-flags.ts), and put the following flags * into that file, and then add the following code before importing zone.js. - * import './zone-flags.ts'; + * import './zone-flags'; * * The flags allowed in zone-flags.ts are listed here. * @@ -55,7 +57,8 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. +import 'zone.js/dist/zone'; // Included with Angular CLI. + /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/Demos/MVC/src/client/apps/viewer/src/styles.less b/Demos/ASP.NET MVC/src/ClientApp/src/styles.css similarity index 100% rename from Demos/MVC/src/client/apps/viewer/src/styles.less rename to Demos/ASP.NET MVC/src/ClientApp/src/styles.css diff --git a/Demos/ASP.NET MVC/src/ClientApp/tsconfig.app.json b/Demos/ASP.NET MVC/src/ClientApp/tsconfig.app.json new file mode 100644 index 000000000..82d91dc4a --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/Demos/ASP.NET MVC/src/ClientApp/tsconfig.json b/Demos/ASP.NET MVC/src/ClientApp/tsconfig.json new file mode 100644 index 000000000..94a24fe1e --- /dev/null +++ b/Demos/ASP.NET MVC/src/ClientApp/tsconfig.json @@ -0,0 +1,30 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "es2015", + "module": "es2020", + "lib": [ + "es2018", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/Demos/ASP.NET MVC/src/Controllers/ViewerApiController.cs b/Demos/ASP.NET MVC/src/Controllers/ViewerApiController.cs new file mode 100644 index 000000000..d0cf3b042 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Controllers/ViewerApiController.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using System.Web.Http.Cors; +using GroupDocs.Viewer.AspNetMvc.ActionResults; +using GroupDocs.Viewer.AspNetMvc.Core; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.Extensions; +using GroupDocs.Viewer.AspNetMvc.Core.Utils; +using GroupDocs.Viewer.AspNetMvc.Models; + +namespace GroupDocs.Viewer.AspNetMvc.Controllers +{ + [RoutePrefix(Constants.API_PATH)] + [EnableCors(origins: "*", headers: "*", methods: "*")] + public class ViewerApiController : ApiController + { + private readonly UIConfig _config; + private readonly IFileStorage _fileStorage; + private readonly IViewer _viewer; + + public ViewerApiController( + UIConfig uiConfig, + IFileStorage fileStorage, + IViewer viewer) + { + _config = uiConfig; + _fileStorage = fileStorage; + _viewer = viewer; + } + + [HttpGet] + [Route(Constants.LOAD_CONFIG_ACTION_NAME)] + public IHttpActionResult LoadConfig() + { + var config = new LoadConfigResponse + { + PageSelector = _config.PageSelector, + Download = _config.Download, + Upload = _config.Upload, + Print = _config.Print, + Browse = _config.Browse, + Rewrite = _config.Rewrite, + EnableRightClick = _config.EnableRightClick, + DefaultDocument = _config.DefaultDocument, + PreloadPageCount = _config.PreloadPageCount, + Zoom = _config.Zoom, + Search = _config.Search, + Thumbnails = _config.Thumbnails, + HtmlMode = _config.HtmlMode, + PrintAllowed = _config.PrintAllowed, + Rotate = _config.Rotate, + SaveRotateState = _config.SaveRotateState, + DefaultLanguage = _config.DefaultLanguage, + SupportedLanguages = _config.SupportedLanguages, + ShowLanguageMenu = _config.ShowLanguageMenu + }; + + return OkJsonResult(config); + } + + [HttpPost] + [Route(Constants.LOAD_FILE_TREE_ACTION_NAME)] + public async Task GetFileTree(LoadFileTreeRequest request) + { + if (!_config.Browse) + return ErrorJsonResult("Browsing files is disabled."); + + try + { + var files = + await _fileStorage.ListDirsAndFilesAsync(request.Path); + + var result = files + .Select(entity => new FileDescription(entity.FilePath, entity.FilePath, entity.IsDirectory, entity.Size)) + .ToList(); + + return OkJsonResult(result); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpGet] + [Route(Constants.DOWNLOAD_DOCUMENT_ACTION_NAME)] + public async Task DownloadDocument(string path) + { + if (!_config.Download) + return ErrorJsonResult("Downloading files is disabled."); + + try + { + var fileName = Path.GetFileName(path); + var bytes = await _fileStorage.ReadFileAsync(path); + + return FileResult(bytes, fileName); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpGet] + [Route(Constants.LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME)] + public async Task LoadDocumentPageResource( + [FromUri]string guid, [FromUri] int pageNumber, [FromUri] string resourceName) + { + if (!_config.HtmlMode) + return ErrorJsonResult("Loading page resources is disabled in image mode."); + + try + { + var fileCredentials = + new FileCredentials(guid, "", ""); + var bytes = + await _viewer.GetPageResourceAsync(fileCredentials, pageNumber, resourceName); + + if (bytes.Length == 0) + return NotFoundJsonResult($"Resource {resourceName} was not found"); + + var contentType = resourceName.ContentTypeFromFileName(); + + return ResourceFileResult(bytes, contentType); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.UPLOAD_DOCUMENT_ACTION_NAME)] + public async Task UploadDocument() + { + if (!_config.Upload) + return ErrorJsonResult("Uploading files is disabled."); + + try + { + var url = HttpContext.Current.Request.Form["url"]; + var (fileName, bytes) = await ReadOrDownloadFile(url); + bool.TryParse(HttpContext.Current.Request.Form["rewrite"], out var rewrite); + + var filePath = await _fileStorage.WriteFileAsync(fileName, bytes, rewrite); + var result = new UploadFileResponse(filePath); + + return OkJsonResult(result); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.PRINT_PDF_ACTION_NAME)] + public async Task PrintPdf([FromBody] PrintPdfRequest request) + { + if (!_config.Print) + return ErrorJsonResult("Printing files is disabled."); + + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + + var filename = Path.GetFileName(request.Guid); + var pdfFileName = Path.ChangeExtension(filename, ".pdf"); + var pdfFileBytes = await _viewer.GetPdfAsync(fileCredentials); + + return FileResult(pdfFileBytes, pdfFileName, "application/pdf"); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_DESCRIPTION_ACTION_NAME)] + public async Task LoadDocumentDescription([FromBody] LoadDocumentDescriptionRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var documentDescription = + await _viewer.GetDocumentInfoAsync(fileCredentials); + + var pageNumbers = GetPageNumbers(documentDescription.Pages.Count()); + var pagesData = await _viewer.GetPagesAsync(fileCredentials, pageNumbers); + + var pages = new List(); + foreach (PageInfo pageInfo in documentDescription.Pages) + { + var pageData = pagesData.FirstOrDefault(p => p.PageNumber == pageInfo.Number); + var pageDescription = new PageDescription + { + Width = pageInfo.Width, + Height = pageInfo.Height, + Number = pageInfo.Number, + SheetName = pageInfo.Name, + Data = pageData?.GetContent() + }; + + pages.Add(pageDescription); + } + + var result = new LoadDocumentDescriptionResponse + { + Guid = request.Guid, + FileType = documentDescription.FileType, + PrintAllowed = documentDescription.PrintAllowed, + Pages = pages + }; + + return OkJsonResult(result); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + private int[] GetPageNumbers(int totalPageCount) + { + if (_config.PreloadPageCount == 0) + return Enumerable.Range(1, totalPageCount).ToArray(); + + var pageCount = + Math.Min(totalPageCount, _config.PreloadPageCount); + + return Enumerable.Range(1, pageCount).ToArray(); + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_PAGES_ACTION_NAME)] + public async Task LoadDocumentPages([FromBody] LoadDocumentPagesRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var pages = await _viewer.GetPagesAsync(fileCredentials, request.Pages); + var pageContents = pages + .Select(page => new PageContent { Number = page.PageNumber, Data = page.GetContent() }) + .ToList(); + + return OkJsonResult(pageContents); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_PAGE_ACTION_NAME)] + public async Task LoadDocumentPage([FromBody] LoadDocumentPageRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var page = await _viewer.GetPageAsync(fileCredentials, request.Page); + var pageContent = new PageContent { Number = page.PageNumber, Data = page.GetContent() }; + + return OkJsonResult(pageContent); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + private Task<(string, byte[])> ReadOrDownloadFile(string url) + { + return string.IsNullOrEmpty(url) + ? ReadFileFromRequest() + : DownloadFileAsync(url); + } + + private async Task<(string, byte[])> ReadFileFromRequest() + { + var provider = await Request.Content.ReadAsMultipartAsync(); + var firstFile = provider.Contents.First(); + + var bytes = await firstFile.ReadAsByteArrayAsync(); + var fileName = PathUtils.RemoveInvalidFileNameChars( + firstFile.Headers.ContentDisposition.FileName); + + return (fileName, bytes); + } + + private async Task<(string, byte[])> DownloadFileAsync(string url) + { + using (HttpClient httpClient = new HttpClient()) + { + httpClient.DefaultRequestHeaders.Add("User-Agent", "Other"); + + Uri uri = new Uri(url); + string fileName = Path.GetFileName(uri.LocalPath); + byte[] bytes = await httpClient.GetByteArrayAsync(uri); + + return (fileName, bytes); + } + } + + private IHttpActionResult ErrorJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.InternalServerError + }; + + private IHttpActionResult ForbiddenJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.Forbidden + }; + + private IHttpActionResult NotFoundJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.NotFound + }; + + private IHttpActionResult OkJsonResult(object result) => + new JsonActionResult(result, Request); + + private IHttpActionResult FileResult(byte[] data, string fileName) => + new FileActionResult(data, fileName, "application/octet-stream", Request); + + private IHttpActionResult FileResult(byte[] data, string fileName, string contentType) => + new FileActionResult(data, fileName, contentType, Request); + + private IHttpActionResult ResourceFileResult(byte[] data, string contentType) => + new ResourceActionResult(data, contentType, Request); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Controllers/ViewerController.cs b/Demos/ASP.NET MVC/src/Controllers/ViewerController.cs new file mode 100644 index 000000000..fea470e07 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Controllers/ViewerController.cs @@ -0,0 +1,12 @@ +using System.Web.Mvc; + +namespace GroupDocs.Viewer.AspNetMvc.Controllers +{ + public class ViewerController : Controller + { + public ActionResult Index() + { + return View(); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/AsyncDuplicateLock.cs b/Demos/ASP.NET MVC/src/Core/Caching/AsyncDuplicateLock.cs new file mode 100644 index 000000000..ffae062d6 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/AsyncDuplicateLock.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + public sealed class AsyncDuplicateLock : IAsyncLock + { + private sealed class RefCounted + { + public RefCounted(T value) + { + RefCount = 1; + Value = value; + } + + public int RefCount { get; set; } + public T Value { get; private set; } + } + + private static readonly Dictionary> SemaphoreSlims + = new Dictionary>(); + + private SemaphoreSlim GetOrCreate(object key) + { + RefCounted item; + lock (SemaphoreSlims) + { + if (SemaphoreSlims.TryGetValue(key, out item)) + { + ++item.RefCount; + } + else + { + item = new RefCounted(new SemaphoreSlim(1, 1)); + SemaphoreSlims[key] = item; + } + } + return item.Value; + } + + public IDisposable Lock(object key) + { + GetOrCreate(key).Wait(); + return new Releaser { Key = key }; + } + + public async Task LockAsync(object key) + { + await GetOrCreate(key).WaitAsync().ConfigureAwait(false); + return new Releaser { Key = key }; + } + + private sealed class Releaser : IDisposable + { + public object Key { get; set; } + + public void Dispose() + { + RefCounted item; + lock (SemaphoreSlims) + { + item = SemaphoreSlims[Key]; + --item.RefCount; + if (item.RefCount == 0) + SemaphoreSlims.Remove(Key); + } + item.Value.Release(); + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/CacheKeys.cs b/Demos/ASP.NET MVC/src/Core/Caching/CacheKeys.cs new file mode 100644 index 000000000..e67263d97 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/CacheKeys.cs @@ -0,0 +1,14 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + public static class CacheKeys + { + public const string FILE_INFO_CACHE_KEY = "info.json"; + public const string PDF_FILE_CACHE_KEY = "file.pdf"; + + public static string GetHtmlPageResourceCacheKey(int pageNumber, string resourceName) + => $"p{pageNumber}_{resourceName}"; + + public static string GetPageCacheKey(int pageNumber, string extension) => + $"p{pageNumber}{extension}"; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/CachedPage.cs b/Demos/ASP.NET MVC/src/Core/Caching/CachedPage.cs new file mode 100644 index 000000000..142ef385b --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/CachedPage.cs @@ -0,0 +1,21 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + internal class CachedPage + { + /// + /// The page number. + /// + public int PageNumber { get; } + + /// + /// The data. Can be null. + /// + public byte[] Data { get; } + + public CachedPage(int pageNumber, byte[] data) + { + PageNumber = pageNumber; + Data = data; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/CachingViewer.cs b/Demos/ASP.NET MVC/src/Core/Caching/CachingViewer.cs new file mode 100644 index 000000000..e489decce --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/CachingViewer.cs @@ -0,0 +1,204 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.Extensions; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + public class CachingViewer : IViewer + { + private readonly IViewer _viewer; + private readonly IFileCache _fileCache; + private readonly IAsyncLock _asyncLock; + + public string PageExtension => + _viewer.PageExtension; + + public Page CreatePage(int pageNumber, byte[] data) => + _viewer.CreatePage(pageNumber, data); + + public CachingViewer(IViewer viewer, IFileCache fileCache, IAsyncLock asyncLock) + { + _viewer = viewer; + _fileCache = fileCache; + _asyncLock = asyncLock; + } + + public async Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers) + { + var pagesOrNulls = GetPagesOrNullsFromCache(fileCredentials.FilePath, pageNumbers); + var missingPageNumbers = GetMissingPageNumbers(pagesOrNulls); + + if (missingPageNumbers.Length == 0) + return ToPages(pagesOrNulls); + + var createdPages = await CreatePages(fileCredentials, missingPageNumbers); + + var pages = Combine(pagesOrNulls, createdPages); + + return pages; + } + + public async Task GetPageAsync(FileCredentials fileCredentials, int pageNumber) + { + var cacheKey = CacheKeys.GetPageCacheKey(pageNumber, PageExtension); + var bytes = await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + var newPage = await _viewer.GetPageAsync(fileCredentials, pageNumber); + + await SaveResourcesAsync(fileCredentials.FilePath, newPage.PageNumber, newPage.Resources); + + return newPage.Data; + }); + } + }); + + var page = CreatePage(pageNumber, bytes); + return page; + } + + public Task GetDocumentInfoAsync(FileCredentials fileCredentials) + { + var cacheKey = CacheKeys.FILE_INFO_CACHE_KEY; + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetDocumentInfoAsync(fileCredentials)); + } + }); + } + + public Task GetPdfAsync(FileCredentials fileCredentials) + { + var cacheKey = CacheKeys.PDF_FILE_CACHE_KEY; + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetPdfAsync(fileCredentials)); + } + }); + } + + public Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, + string resourceName) + { + var cacheKey = CacheKeys.GetHtmlPageResourceCacheKey(pageNumber, resourceName); + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, + async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetPageResourceAsync(fileCredentials, pageNumber, resourceName)); + } + }); + } + + private async Task SaveResourcesAsync(string filePath, int pageNumber, IEnumerable pageResources) + { + var tasks = pageResources.Select(resource => + { + var resourceCacheKey = + CacheKeys.GetHtmlPageResourceCacheKey(pageNumber, resource.ResourceName); + + return _fileCache.SetAsync(resourceCacheKey, filePath, resource.Data); + }); + + await Task.WhenAll(tasks); + } + + private async Task CreatePages(FileCredentials fileCredentials, int[] pageNumbers) + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + var pagesOrNulls = GetPagesOrNullsFromCache(fileCredentials.FilePath, pageNumbers); + var missingPageNumbers = GetMissingPageNumbers(pagesOrNulls); + + if (missingPageNumbers.Length == 0) + return ToPages(pagesOrNulls); + + var createdPages = await _viewer.GetPagesAsync(fileCredentials, missingPageNumbers); + + await SaveToCache(fileCredentials.FilePath, createdPages); + + var pages = Combine(pagesOrNulls, createdPages); + + return pages; + } + } + + private Pages Combine(List dst, Pages missing) + { + var pages = dst + .Select(pageOrNull => + { + if (pageOrNull.Data == null) + { + var page = missing + .Where(p => p.PageNumber == pageOrNull.PageNumber) + .Select(p => p) + .FirstOrDefault(); + + return page; + } + + return CreatePage(pageOrNull.PageNumber, pageOrNull.Data); + }).ToList(); + + return new Pages(pages); + } + + private Task SaveToCache(string filePath, Pages createdPages) + { + var tasks = createdPages + .SelectMany(page => + { + var cacheKey = CacheKeys.GetPageCacheKey(page.PageNumber, _viewer.PageExtension); + + var savePageTask = _fileCache.SetAsync(cacheKey, filePath, page.Data); + var saveResourcesTask = SaveResourcesAsync(filePath, page.PageNumber, page.Resources); + + return new[] {savePageTask, saveResourcesTask}; + }); + + return Task.WhenAll(tasks); + } + + private Pages ToPages(List pagesOrNulls) + { + var pages = pagesOrNulls + .Select(p => CreatePage(p.PageNumber, p.Data)) + .ToList(); + + var result = new Pages(pages); + return result; + } + + private int[] GetMissingPageNumbers(List pagesOrNulls) + { + return pagesOrNulls + .Where(p => p.Data == null) + .Select(p => p.PageNumber) + .ToArray(); + } + + private List GetPagesOrNullsFromCache(string filePath, int[] pageNumbers) + { + return pageNumbers + .Select(pageNumber => + (pageNumber, cacheKey: CacheKeys.GetPageCacheKey(pageNumber, PageExtension))) + .Select(page => + new CachedPage(page.pageNumber, _fileCache.TryGetValue(page.cacheKey, filePath))) + .ToList(); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/LocalFileCache.cs b/Demos/ASP.NET MVC/src/Core/Caching/LocalFileCache.cs new file mode 100644 index 000000000..2ca1a9495 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/LocalFileCache.cs @@ -0,0 +1,277 @@ +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + public class LocalFileCache : IFileCache + { + /// + /// The Relative or absolute path to the cache folder. + /// + private string CachePath { get; } + + private readonly TimeSpan _waitTimeout = TimeSpan.FromMilliseconds(100); + + /// + /// Creates new instance of class. + /// + /// Relative or absolute path where document cache will be stored. + /// Thrown when is null. + public LocalFileCache(string cachePath) + { + if (cachePath == null) + throw new ArgumentNullException(nameof(cachePath)); + + CachePath = cachePath; + } + + /// + /// Deserializes data associated with this key if present. + /// + /// A key identifying the requested entry. + /// The relative or absolute filepath. + /// True if the key was found. + public TEntry TryGetValue(string cacheKey, string filePath) + { + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (File.Exists(cacheFilePath)) + { + if (typeof(TEntry) == typeof(byte[])) + return (TEntry)ReadBytes(cacheFilePath); + + if (typeof(TEntry) == typeof(Stream)) + return (TEntry)ReadStream(cacheFilePath); + + return Deserialize(cacheFilePath); + } + + return default(TEntry); + } + + /// + /// Deserializes data associated with this key if present. + /// + /// A key identifying the requested entry. + /// The relative or absolute filepath. + /// True if the key was found. + public async Task TryGetValueAsync(string cacheKey, string filePath) + { + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (File.Exists(cacheFilePath)) + { + if (typeof(TEntry) == typeof(byte[])) + return (TEntry)ReadBytes(cacheFilePath); + + if (typeof(TEntry) == typeof(Stream)) + return (TEntry)ReadStream(cacheFilePath); + + return await DeserializeAsync(cacheFilePath); + } + + return default(TEntry); + } + + /// + /// Serializes data to the local disk. + /// + /// An unique identifier for the cache entry. + /// The relative or absolute filepath. + /// The object to serialize. + public void Set(string cacheKey, string filePath, TEntry value) + { + if (value == null) + return; + + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (value is byte[] data) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + dst.Write(data, 0, data.Length); + } + } + else if (value is Stream src) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + if (src.CanSeek) + src.Position = 0; + src.CopyTo(dst); + } + } + else + { + var json = JsonConvert.SerializeObject(value, Formatting.Indented); + var bytes = Encoding.UTF8.GetBytes(json); + + using (FileStream stream = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + stream.Write(bytes, 0, bytes.Length); + } + } + } + + /// + /// Serializes data to the local disk. + /// + /// An unique identifier for the cache entry. + /// The relative or absolute filepath. + /// The object to serialize. + public async Task SetAsync(string cacheKey, string filePath, TEntry value) + { + if (value == null) + return; + + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (value is byte[] data) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + await dst.WriteAsync(data, 0, data.Length); + } + } + else if (value is Stream src) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + if (src.CanSeek) + src.Position = 0; + + await src.CopyToAsync(dst); + } + } + else + { + var json = JsonConvert.SerializeObject(value, Formatting.Indented); + var bytes = Encoding.UTF8.GetBytes(json); + + using (FileStream stream = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + await stream.WriteAsync(bytes, 0, bytes.Length); + } + } + } + + private object ReadStream(string cacheFilePath) + => GetStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); + + private object ReadBytes(string cacheFilePath) + => GetBytes(cacheFilePath); + + private TEntry Deserialize(string cachePath) + { + object data; + try + { + var bytes = GetBytes(cachePath); + var json = Encoding.UTF8.GetString(bytes); + + data = JsonConvert.DeserializeObject(json); + } + catch (SerializationException) + { + data = default(TEntry); + } + + return (TEntry)data; + } + + private async Task DeserializeAsync(string cachePath) + { + object data; + try + { + using (var stream = GetStream(cachePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + var memory = new MemoryStream(); + await stream.CopyToAsync(memory); + var json = Encoding.UTF8.GetString(memory.ToArray()); + + data = JsonConvert.DeserializeObject(json); + } + } + catch (SerializationException) + { + data = default(TEntry); + } + + return (TEntry)data; + } + + private string GetCacheFilePath(string cacheKey, string filePath) + { + string cacheSubFolder = string.Join("_", filePath.Split(Path.GetInvalidPathChars())) + .Replace(".", "_"); + string cacheDirPath = Path.Combine(CachePath, cacheSubFolder); + string cacheFilePath = Path.Combine(cacheDirPath, cacheKey); + + if (!Directory.Exists(cacheDirPath)) + Directory.CreateDirectory(cacheDirPath); + + return cacheFilePath; + } + + private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) + { + FileStream stream = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (stream == null) + { + try + { + stream = File.Open(path, mode, access, share); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return stream; + } + + private byte[] GetBytes(string path) + { + byte[] bytes = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (bytes == null) + { + try + { + bytes = File.ReadAllBytes(path); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return bytes; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Caching/NoopFileCache.cs b/Demos/ASP.NET MVC/src/Core/Caching/NoopFileCache.cs new file mode 100644 index 000000000..1a8817d66 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Caching/NoopFileCache.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Caching +{ + internal class NoopFileCache : IFileCache + { + public TEntry TryGetValue(string cacheKey, string filePath) => + default(TEntry); + + public Task TryGetValueAsync(string cacheKey, string filePath) => + Task.FromResult(default(TEntry)); + + public void Set(string cacheKey, string filePath, TEntry entry) { } + + public Task SetAsync(string cacheKey, string filePath, TEntry entry) => + Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Configuration/Language.cs b/Demos/ASP.NET MVC/src/Core/Configuration/Language.cs new file mode 100644 index 000000000..caf05c40e --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Configuration/Language.cs @@ -0,0 +1,43 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Configuration +{ + public class Language + { + public static readonly Language Arabic = new Language("ar"); + public static readonly Language Catalan = new Language("ca"); + public static readonly Language Czech = new Language("cs"); + public static readonly Language Danish = new Language("da"); + public static readonly Language German = new Language("de"); + public static readonly Language Greek = new Language("el"); + public static readonly Language English = new Language("en"); + public static readonly Language Spanish = new Language("es"); + public static readonly Language Filipino = new Language("fil"); + public static readonly Language French = new Language("fr"); + public static readonly Language Hebrew = new Language("he"); + public static readonly Language Hindi = new Language("hi"); + public static readonly Language Indonesian = new Language("id"); + public static readonly Language Italian = new Language("it"); + public static readonly Language Japanese = new Language("ja"); + public static readonly Language Kazakh = new Language("kk"); + public static readonly Language Korean = new Language("ko"); + public static readonly Language Malay = new Language("ms"); + public static readonly Language Dutch = new Language("nl"); + public static readonly Language Polish = new Language("pl"); + public static readonly Language Portuguese = new Language("pt"); + public static readonly Language Romanian = new Language("ro"); + public static readonly Language Russian = new Language("ru"); + public static readonly Language Swedish = new Language("sv"); + public static readonly Language Vietnamese = new Language("vi"); + public static readonly Language Thai = new Language("th"); + public static readonly Language Turkish = new Language("tr"); + public static readonly Language Ukrainian = new Language("uk"); + public static readonly Language ChineseSimplified = new Language("zh-hans"); + public static readonly Language ChineseTraditional = new Language("zh-hant"); + + public string Code { get; } + + public Language(string code) + { + Code = code; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Configuration/UIConfig.cs b/Demos/ASP.NET MVC/src/Core/Configuration/UIConfig.cs new file mode 100644 index 000000000..948c5fe18 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Configuration/UIConfig.cs @@ -0,0 +1,238 @@ +using System.Linq; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Configuration +{ + public class UIConfig + { + public static readonly UIConfig Instance = new UIConfig(); + + internal string DefaultDocument { get; private set; } = string.Empty; + internal int PreloadPageCount { get; private set; } = 3; + internal bool PageSelector { get; private set; } = true; + internal bool Thumbnails { get; private set; } = true; + internal bool Zoom { get; private set; } = true; + internal bool Search { get; private set; } = true; + internal bool EnableRightClick { get; private set; } = true; + internal bool Download { get; private set; } = true; + internal bool Upload { get; private set; } = true; + internal bool Rewrite { get; private set; } = false; + internal bool Print { get; private set; } = true; + internal bool Browse { get; private set; } = true; + internal bool PrintAllowed { get; private set; } = true; + internal bool HtmlMode { get; private set; } = true; + internal bool ShowLanguageMenu { get; private set; } = true; + internal string DefaultLanguage { get; private set; } = "en"; + internal string[] SupportedLanguages { get; private set; } = new string[] + { + "ar", // ar - العربية + "ca", // ca-ES - Català + "cs", // cs-CZ - Čeština + "da", // da-DK - Dansk + "de", // de-DE - Deutsch + "el", // el-GR - Ελληνικά + "en", // en-US - English + "es", // es-ES - Español + "fil", // fil-PH - Filipino + "fr", // fr-FR - Français + "he", // he-IL - עברית + "hi", // hi-IN - हिन्दी + "id", // id-ID - Indonesia + "it", // it-IT - Italiano + "ja", // ja-JP - 日本語 + "kk", // kk-KZ - Қазақ Тілі + "ko", // ko-KR - 한국어 + "ms", // ms-MY - Melayu + "nl", // nl-NL - Nederlands + "pl", // pl-PL - Polski + "pt", // pt-PT - Português + "ro", // ro-RO - Română + "ru", // ru-RU - Русский + "sv", // sv-SE - Svenska + "vi", // vi-VN - Tiếng Việt + "th", // th-TH - ไทย + "tr", // tr-TR - Türkçe + "uk", // uk-UA - Українська + "zh-hans", // zh-Hans - 中文(简体) + "zh-hant", // zh-Hant" - 中文(繁體) + }; + + internal bool Rotate { get; private set; } = false; + internal bool SaveRotateState { get; private set; } = false; + internal ViewerType ViewerType { get; private set; } + + public UIConfig SetViewerType(ViewerType viewerType) + { + ViewerType = viewerType; + HtmlMode = viewerType == ViewerType.HtmlWithExternalResources || + viewerType == ViewerType.HtmlWithEmbeddedResources; + return this; + } + + public UIConfig SetPreloadPageCount(int countPages) + { + PreloadPageCount = countPages; + return this; + } + + public UIConfig SetDefaultDocument(string filePath) + { + DefaultDocument = filePath; + return this; + } + + public UIConfig HidePageSelectorControl() + { + PageSelector = false; + return this; + } + + public UIConfig HideThumbnailsControl() + { + Thumbnails = false; + return this; + } + + public UIConfig DisableFileDownload() + { + Download = false; + return this; + } + + public UIConfig DisableFileUpload() + { + Upload = false; + return this; + } + + public UIConfig RewriteFilesOnUpload() + { + Rewrite = true; + return this; + } + + public UIConfig DisablePrint() + { + Print = false; + PrintAllowed = false; + return this; + } + + public UIConfig DisableFileBrowsing() + { + Browse = false; + return this; + } + + public UIConfig HideZoomButton() + { + Zoom = false; + return this; + } + + public UIConfig HideSearchControl() + { + Search = false; + return this; + } + + public UIConfig HidePageRotationControl() + { + Rotate = false; + return this; + } + + public UIConfig DisableRightClick() + { + EnableRightClick = false; + return this; + } + + public UIConfig HideLanguageMenu() + { + ShowLanguageMenu = false; + return this; + } + + /// + /// Sets default language out of supported: + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// + /// + /// Default language e.g. . + /// This UIConfig instance. + public UIConfig SetDefaultLanguage(Language language) + { + DefaultLanguage = language.Code; + return this; + } + + /// + /// Set supported UI languages. The following languages are supported: + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// + /// + /// Supported languages. + /// This UIConfig instance. + public UIConfig SetSupportedLanguages(params Language[] languages) + { + SupportedLanguages = languages.Select(l => l.Code).ToArray(); + return this; + } + } +} diff --git a/Demos/ASP.NET MVC/src/Core/Configuration/ViewerConfig.cs b/Demos/ASP.NET MVC/src/Core/Configuration/ViewerConfig.cs new file mode 100644 index 000000000..460e98a16 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Configuration/ViewerConfig.cs @@ -0,0 +1,48 @@ +using System; +using GroupDocs.Viewer.Options; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Configuration +{ + public class ViewerConfig + { + public static ViewerConfig Instance = new ViewerConfig(); + + internal string LicensePath = string.Empty; + internal readonly HtmlViewOptions HtmlViewOptions = HtmlViewOptions.ForEmbeddedResources(); + internal readonly PngViewOptions PngViewOptions = new PngViewOptions(); + internal readonly JpgViewOptions JpgViewOptions = new JpgViewOptions(); + internal readonly PdfViewOptions PdfViewOptions = new PdfViewOptions(); + + private ViewerConfig() { } + + public ViewerConfig SetLicensePath(string licensePath) + { + LicensePath = licensePath; + return this; + } + + public ViewerConfig ConfigureHtmlViewOptions(Action setupOptions) + { + setupOptions?.Invoke(HtmlViewOptions); + return this; + } + + public ViewerConfig ConfigurePngViewOptions(Action setupOptions) + { + setupOptions?.Invoke(PngViewOptions); + return this; + } + + public ViewerConfig ConfigureJpgViewOptions(Action setupOptions) + { + setupOptions?.Invoke(JpgViewOptions); + return this; + } + + public ViewerConfig ConfigurePdfViewOptions(Action setupOptions) + { + setupOptions?.Invoke(PdfViewOptions); + return this; + } + } +} diff --git a/Demos/ASP.NET MVC/src/Core/Constants.cs b/Demos/ASP.NET MVC/src/Core/Constants.cs new file mode 100644 index 000000000..6ce879ed5 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Constants.cs @@ -0,0 +1,16 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public class Constants + { + public const string API_PATH = "viewer-api"; + public const string LOAD_CONFIG_ACTION_NAME = "LoadConfig"; + public const string LOAD_FILE_TREE_ACTION_NAME = "LoadFileTree"; + public const string DOWNLOAD_DOCUMENT_ACTION_NAME = "DownloadDocument"; + public const string LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME = "LoadDocumentPageResource"; + public const string UPLOAD_DOCUMENT_ACTION_NAME = "UploadDocument"; + public const string LOAD_DOCUMENT_DESCRIPTION_ACTION_NAME = "LoadDocumentDescription"; + public const string LOAD_DOCUMENT_PAGES_ACTION_NAME = "LoadDocumentPages"; + public const string LOAD_DOCUMENT_PAGE_ACTION_NAME = "LoadDocumentPage"; + public const string PRINT_PDF_ACTION_NAME = "PrintPdf"; + } +} diff --git a/Demos/ASP.NET MVC/src/Core/Entities/DocumentInfo.cs b/Demos/ASP.NET MVC/src/Core/Entities/DocumentInfo.cs new file mode 100644 index 000000000..040443283 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/DocumentInfo.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class DocumentInfo + { + public string FileType { get; set; } + + public bool PrintAllowed { get; set; } + + public IEnumerable Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/FileCredentials.cs b/Demos/ASP.NET MVC/src/Core/Entities/FileCredentials.cs new file mode 100644 index 000000000..8adadac48 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/FileCredentials.cs @@ -0,0 +1,16 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class FileCredentials + { + public string FilePath { get; } + public string FileType { get; } + public string Password { get; } + + public FileCredentials(string filePath, string fileType, string password) + { + FilePath = filePath; + FileType = fileType; + Password = password; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/FileSystemEntry.cs b/Demos/ASP.NET MVC/src/Core/Entities/FileSystemEntry.cs new file mode 100644 index 000000000..45598d499 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/FileSystemEntry.cs @@ -0,0 +1,33 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class FileSystemEntry + { + public string FileName { get; private set; } + + public string FilePath { get; private set; } + + public bool IsDirectory { get; private set; } + + public long Size { get; private set; } + + private FileSystemEntry () { } + + public static FileSystemEntry Directory(string name, string path, long size) => + new FileSystemEntry + { + FileName = name, + FilePath = path, + IsDirectory = true, + Size = size + }; + + public static FileSystemEntry File(string name, string path, long size) => + new FileSystemEntry + { + FileName = name, + FilePath = path, + IsDirectory = false, + Size = size + }; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/HtmlPage.cs b/Demos/ASP.NET MVC/src/Core/Entities/HtmlPage.cs new file mode 100644 index 000000000..b448bbf4a --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/HtmlPage.cs @@ -0,0 +1,22 @@ +using System.Text; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class HtmlPage : Page + { + public static string Extension => ".html"; + + public override string GetContent() => + Encoding.UTF8.GetString(Data); + + public override void SetContent(string contents) + { + Data = Encoding.UTF8.GetBytes(contents); + } + + public HtmlPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/JpgPage.cs b/Demos/ASP.NET MVC/src/Core/Entities/JpgPage.cs new file mode 100644 index 000000000..171882600 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/JpgPage.cs @@ -0,0 +1,30 @@ +using System; +using System.Text; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class JpgPage : Page + { + const string DATA_IMAGE = "data:image/jpeg;base64,"; + + public static string Extension => ".jpeg"; + + public override string GetContent() + { + return DATA_IMAGE + Convert.ToBase64String(Data); + } + + public override void SetContent(string content) + { + this.Data = content.StartsWith(DATA_IMAGE) + ? Encoding.UTF8.GetBytes(content) + : Encoding.UTF8.GetBytes(content.Substring(DATA_IMAGE.Length - 1)); + } + + public JpgPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/Page.cs b/Demos/ASP.NET MVC/src/Core/Entities/Page.cs new file mode 100644 index 000000000..265ca76ca --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/Page.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public abstract class Page + { + private readonly List _resources = new List(); + + protected Page(int pageNumber, byte[] data) + { + PageNumber = pageNumber; + Data = data; + } + + protected Page(int pageNumber, byte[] data, IEnumerable resources) + { + PageNumber = pageNumber; + Data = data; + _resources.AddRange(resources); + } + + public IEnumerable Resources => _resources; + + public int PageNumber { get; } + + public byte[] Data { get; protected set; } + + public abstract string GetContent(); + + public abstract void SetContent(string content); + + public void AddResource(PageResource pageResource) + { + _resources.Add(pageResource); + } + + public PageResource GetResource(string resourceName) => + _resources.First(resource => + resource.ResourceName.Equals(resourceName, StringComparison.InvariantCulture)); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/PageInfo.cs b/Demos/ASP.NET MVC/src/Core/Entities/PageInfo.cs new file mode 100644 index 000000000..0cbf7d6dd --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/PageInfo.cs @@ -0,0 +1,10 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class PageInfo + { + public int Width { get; set; } + public int Height { get; set; } + public int Number { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/PageResource.cs b/Demos/ASP.NET MVC/src/Core/Entities/PageResource.cs new file mode 100644 index 000000000..382d4b6b1 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/PageResource.cs @@ -0,0 +1,15 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class PageResource + { + public PageResource(string resourceName, byte[] data) + { + ResourceName = resourceName; + Data = data; + } + + public string ResourceName { get; } + + public byte[] Data { get; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/Pages.cs b/Demos/ASP.NET MVC/src/Core/Entities/Pages.cs new file mode 100644 index 000000000..99d058707 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/Pages.cs @@ -0,0 +1,35 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class Pages : IEnumerable + { + readonly List _pages; + + public Pages() + { + _pages = new List(); + } + + public Pages(IEnumerable pages) + { + _pages = pages.ToList(); + } + + public void Add(Page page) => _pages.Add(page); + + public Page this[int index] + { + get => _pages[index]; + set => _pages.Insert(index, value); + } + + public IEnumerator GetEnumerator() + => _pages.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Entities/PngPage.cs b/Demos/ASP.NET MVC/src/Core/Entities/PngPage.cs new file mode 100644 index 000000000..85b4dd293 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Entities/PngPage.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Entities +{ + public class PngPage : Page + { + const string DATA_IMAGE = "data:image/png;base64,"; + + public static string Extension => ".png"; + + public override string GetContent() => + DATA_IMAGE + Convert.ToBase64String(Data); + + public override void SetContent(string content) + { + this.Data = content.StartsWith(DATA_IMAGE) + ? Encoding.UTF8.GetBytes(content) + : Encoding.UTF8.GetBytes(content.Substring(DATA_IMAGE.Length - 1)); + } + + public PngPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Extensions/FileCacheExtensions.cs b/Demos/ASP.NET MVC/src/Core/Extensions/FileCacheExtensions.cs new file mode 100644 index 000000000..dd5ec7499 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Extensions/FileCacheExtensions.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Extensions +{ + public static class FileCacheExtensions + { + /// + /// Gets the entry associated with this key if present or acquires and sets the entry if not present. + /// + /// Type of entry. + /// The cache. + /// A key identifying the requested entry. + /// The source file relative file path. + /// The method which returns entry. + /// The entry associated with this key if present or acquires and sets the entry if not present. + public static async Task GetValueAsync(this IFileCache cache, string cacheKey, string filePath, Func> acquire) + { + var entry = await cache.TryGetValueAsync(cacheKey, filePath); + if (entry == null) + { + entry = await acquire(); + await cache.SetAsync(cacheKey, filePath, entry); + } + + return entry; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Extensions/MediaTypeExtensions.cs b/Demos/ASP.NET MVC/src/Core/Extensions/MediaTypeExtensions.cs new file mode 100644 index 000000000..7183eb355 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Extensions/MediaTypeExtensions.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Extensions +{ + public static class ContentTypeExtensions + { + public static string ContentTypeFromFileName(this string filename) + { + var extension = Path.GetExtension(filename); + + switch (extension) + { + case ".css": return "text/css"; + case ".woff": return "font/woff"; + case ".png": return "image/png"; + case ".jpg": + case ".jpeg": return "image/jpeg"; + case ".svg": return "image/svg+xml"; + default: + return "application/octet-stream"; + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs b/Demos/ASP.NET MVC/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs new file mode 100644 index 000000000..b78d8e66d --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs @@ -0,0 +1,16 @@ +using System.IO; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution +{ + public class FileExtensionFileTypeResolver : IFileTypeResolver + { + public Task ResolveFileTypeAsync(string filePath) + { + string extension = Path.GetExtension(filePath); + FileType fileType = FileType.FromExtension(extension); + + return Task.FromResult(fileType); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/FileTypeResolution/IFileTypeResolver.cs b/Demos/ASP.NET MVC/src/Core/FileTypeResolution/IFileTypeResolver.cs new file mode 100644 index 000000000..7920a9255 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/FileTypeResolution/IFileTypeResolver.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution +{ + public interface IFileTypeResolver + { + Task ResolveFileTypeAsync(string filePath); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/IAsyncLock.cs b/Demos/ASP.NET MVC/src/Core/IAsyncLock.cs new file mode 100644 index 000000000..63df19206 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/IAsyncLock.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public interface IAsyncLock + { + Task LockAsync(object key); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/IFileCache.cs b/Demos/ASP.NET MVC/src/Core/IFileCache.cs new file mode 100644 index 000000000..fa2d859f0 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/IFileCache.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public interface IFileCache + { + TEntry TryGetValue(string cacheKey, string filePath); + + Task TryGetValueAsync(string cacheKey, string filePath); + + void Set(string cacheKey, string filePath, TEntry entry); + + Task SetAsync(string cacheKey, string filePath, TEntry entry); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/IFileStorage.cs b/Demos/ASP.NET MVC/src/Core/IFileStorage.cs new file mode 100644 index 000000000..560ba8c4c --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/IFileStorage.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; + +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public interface IFileStorage + { + Task> ListDirsAndFilesAsync(string dirPath); + + Task ReadFileAsync(string filePath); + + Task WriteFileAsync(string fileName, byte[] bytes, bool rewrite); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/IPageFormatter.cs b/Demos/ASP.NET MVC/src/Core/IPageFormatter.cs new file mode 100644 index 000000000..6a625c762 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/IPageFormatter.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; + +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public interface IPageFormatter + { + Task FormatAsync(FileCredentials fileCredentials, Page page); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/IViewer.cs b/Demos/ASP.NET MVC/src/Core/IViewer.cs new file mode 100644 index 000000000..39ccd7db8 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/IViewer.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; + +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public interface IViewer + { + string PageExtension { get; } + Page CreatePage(int pageNumber, byte[] data); + Task GetDocumentInfoAsync(FileCredentials fileCredentials); + Task GetPageAsync(FileCredentials fileCredentials, int pageNumber); + Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers); + Task GetPdfAsync(FileCredentials fileCredentials); + Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, string resourceName); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Licensing/IViewerLicenser.cs b/Demos/ASP.NET MVC/src/Core/Licensing/IViewerLicenser.cs new file mode 100644 index 000000000..1b35c295d --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Licensing/IViewerLicenser.cs @@ -0,0 +1,7 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core.Licensing +{ + internal interface IViewerLicenser + { + void SetLicense(); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Licensing/LicenseFileViewerLicenser.cs b/Demos/ASP.NET MVC/src/Core/Licensing/LicenseFileViewerLicenser.cs new file mode 100644 index 000000000..7c9b13bf7 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Licensing/LicenseFileViewerLicenser.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Licensing +{ + internal class LicenseFileViewerLicenser : IViewerLicenser + { + private readonly ViewerConfig _config; + private readonly object _lock = new object(); + private bool _licenseSet; + + public LicenseFileViewerLicenser(ViewerConfig config) + { + _config = config; + } + + public void SetLicense() + { + if (_licenseSet) + return; + + if (File.Exists(_config.LicensePath)) + SetLicense(_config.LicensePath); + + string licensePath = Environment.GetEnvironmentVariable("GROUPDOCS_LIC_PATH"); + if (!string.IsNullOrEmpty(licensePath)) + SetLicense(licensePath); + } + + private void SetLicense(string licensePath) + { + lock (_lock) + { + if (!_licenseSet) + { + License license = new License(); + license.SetLicense(licensePath); + + _licenseSet = true; + } + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/PageFormatting/NoopPageFormatter.cs b/Demos/ASP.NET MVC/src/Core/PageFormatting/NoopPageFormatter.cs new file mode 100644 index 000000000..135d9cf04 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/PageFormatting/NoopPageFormatter.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; + +namespace GroupDocs.Viewer.AspNetMvc.Core.PageFormatting +{ + public class NoopPageFormatter : IPageFormatter + { + public Task FormatAsync(FileCredentials fileCredentials, Page page) => + Task.FromResult(page); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Storage/LocalFileStorage.cs b/Demos/ASP.NET MVC/src/Core/Storage/LocalFileStorage.cs new file mode 100644 index 000000000..38cf9798c --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Storage/LocalFileStorage.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.Utils; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Storage +{ + public class LocalFileStorage : IFileStorage + { + private readonly string _storagePath; + private readonly TimeSpan _waitTimeout = TimeSpan.FromMilliseconds(100); + + public LocalFileStorage(string storagePath) + { + _storagePath = storagePath; + } + + private IEnumerable ListFiles(string folderPath) + { + var folderFullPath = string.IsNullOrEmpty(folderPath) + ? _storagePath + : Path.Combine(_storagePath, folderPath); + + var dirs = Directory.GetDirectories(folderFullPath) + .Select(file => new FileInfo(file)) + .Where(fileInfo => !fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + .OrderBy(fileInfo => fileInfo.Name) + .ThenByDescending(fileInfo => fileInfo.CreationTime) + .Select(directory => + FileSystemEntry.Directory(directory.Name, PathUtils.GetRelativePath(_storagePath, directory.FullName), 0L)); + + var files = Directory + .GetFiles(folderFullPath) + .Select(file => new FileInfo(file)) + .Where(fileInfo => !fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + .OrderBy(fileInfo => fileInfo.Name) + .ThenByDescending(fileInfo => fileInfo.CreationTime) + .Select(file => + FileSystemEntry.File(file.Name, PathUtils.GetRelativePath(_storagePath, file.FullName), file.Length)); + + var dirsAndFiles = dirs.Concat(files); + return dirsAndFiles; + } + + public Task> ListDirsAndFilesAsync(string dirPath) => + Task.FromResult(ListFiles(dirPath)); + + public async Task ReadFileAsync(string filePath) + { + var fullPath = Path.Combine(_storagePath, filePath); + using (FileStream fs = GetStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + var memoryStream = new MemoryStream(); + await fs.CopyToAsync(memoryStream); + + return memoryStream.ToArray(); + } + } + + public async Task WriteFileAsync(string fileName, byte[] bytes, bool rewrite) + { + var newFileName = rewrite ? fileName : GetFreeFileName(fileName); + var fullPath = Path.Combine(_storagePath, newFileName); + var fileMode = rewrite ? FileMode.Create : FileMode.CreateNew; + + using (FileStream fs = GetStream(fullPath, fileMode, FileAccess.Write, FileShare.None)) + { + await fs.WriteAsync(bytes, 0, bytes.Length); + } + + return newFileName; + } + + private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) + { + FileStream stream = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (stream == null) + { + try + { + stream = File.Open(path, mode, access, share); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return stream; + } + + private string GetFreeFileName(string fileName) + { + var fullPath = Path.Combine(_storagePath, fileName); + + if (!File.Exists(fullPath)) + return fileName; + + List dirFiles = Directory.GetFiles(_storagePath) + .Select(filePath => Path.GetFileName(filePath)) + .ToList(); + + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); + var number = 1; + string fileNameCandidate; + do + { + string newFileName = $"{fileNameWithoutExtension} ({number})"; + fileNameCandidate = fileName.Replace(fileNameWithoutExtension, newFileName); + number++; + } while (dirFiles.Contains(fileNameCandidate)); + + return fileNameCandidate; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Utils/PathUtils.cs b/Demos/ASP.NET MVC/src/Core/Utils/PathUtils.cs new file mode 100644 index 000000000..418b52214 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Utils/PathUtils.cs @@ -0,0 +1,54 @@ +using System.IO; +using System; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Utils +{ + public static class PathUtils + { + public static string GetRelativePath(string relativeTo, string path) + { + if (string.IsNullOrEmpty(relativeTo)) + throw new ArgumentNullException(nameof(relativeTo)); + + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException("path"); + + Uri fromUri = new Uri(AppendDirectorySeparatorChar(relativeTo)); + Uri toUri = new Uri(AppendDirectorySeparatorChar(path)); + + if (fromUri.Scheme != toUri.Scheme) + return path; + + Uri relativeUri = fromUri.MakeRelativeUri(toUri); + string relativePath = Uri.UnescapeDataString(relativeUri.ToString()); + + if (string.Equals(toUri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase)) + relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + + return relativePath; + } + + private static string AppendDirectorySeparatorChar(string path) + { + // Append a slash only if the path is a directory and does not have a slash. + if (!Path.HasExtension(path) && + !path.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + return path + Path.DirectorySeparatorChar; + } + + return path; + } + + public static string RemoveInvalidFileNameChars(string path) + { + Path.GetInvalidFileNameChars().ToList().ForEach(ch => + { + path = path.Replace(ch.ToString(), string.Empty); + }); + + return path; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/ViewerType.cs b/Demos/ASP.NET MVC/src/Core/ViewerType.cs new file mode 100644 index 000000000..4a2726d44 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/ViewerType.cs @@ -0,0 +1,10 @@ +namespace GroupDocs.Viewer.AspNetMvc.Core +{ + public enum ViewerType + { + HtmlWithEmbeddedResources, + HtmlWithExternalResources, + Png, + Jpg, + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/BaseViewer.cs b/Demos/ASP.NET MVC/src/Core/Viewers/BaseViewer.cs new file mode 100644 index 000000000..83511cad9 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/BaseViewer.cs @@ -0,0 +1,175 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using GroupDocs.Viewer.Results; +using Page = GroupDocs.Viewer.AspNetMvc.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers +{ + internal abstract class BaseViewer : IViewer, IDisposable + { + private readonly ViewerConfig _config; + private readonly IViewerLicenser _viewerLicenser; + private readonly IFileStorage _fileStorage; + private readonly IFileTypeResolver _fileTypeResolver; + private readonly IPageFormatter _pageFormatter; + private Viewer _viewer; + + protected BaseViewer(ViewerConfig config, + IViewerLicenser viewerLicenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + { + _config = config; + _viewerLicenser = viewerLicenser; + _fileStorage = fileStorage; + _fileTypeResolver = fileTypeResolver; + _pageFormatter = pageFormatter; + } + + public abstract string PageExtension { get; } + + public abstract Page CreatePage(int pageNumber, byte[] data); + + protected abstract Page RenderPage(Viewer viewer, string filePath, int pageNumber); + + protected abstract ViewInfoOptions CreateViewInfoOptions(); + + public async Task GetDocumentInfoAsync(FileCredentials fileCredentials) + { + var viewer = await InitViewerAsync(fileCredentials); + var viewInfoOptions = CreateViewInfoOptions(); + var viewInfo = viewer.GetViewInfo(viewInfoOptions); + + var documentInfo = ToDocumentInfo(viewInfo); + return documentInfo; + } + + public async Task GetPageAsync(FileCredentials fileCredentials, int pageNumber) + { + var viewer = await InitViewerAsync(fileCredentials); + var page = await RenderPageInternalAsync(viewer, fileCredentials, pageNumber); + + return page; + } + + public async Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers) + { + var viewer = await InitViewerAsync(fileCredentials); + + var pages = new Pages(); + + foreach (var pageNumber in pageNumbers) + { + var page = await RenderPageInternalAsync(viewer, fileCredentials, pageNumber); + pages.Add(page); + } + + return pages; + } + + public async Task GetPdfAsync(FileCredentials fileCredentials) + { + var pdfStream = new MemoryStream(); + var viewOptions = CreatePdfViewOptions(pdfStream); + + var viewer = await InitViewerAsync(fileCredentials); + viewer.View(viewOptions); + + return pdfStream.ToArray(); + } + + public abstract Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, string resourceName); + + private PdfViewOptions CreatePdfViewOptions(MemoryStream pdfStream) + { + var viewOptions = new PdfViewOptions(() => pdfStream, _ => { /* NOTE: nothing to do here */ }); + + viewOptions.CopyViewOptions(_config.PdfViewOptions); + + return viewOptions; + } + + private async Task InitViewerAsync(FileCredentials fileCredentials) + { + if (_viewer == null) + { + _viewerLicenser.SetLicense(); + + var fileStream = await GetFileStreamAsync(fileCredentials.FilePath); + var loadOptions = await CreateLoadOptionsAsync(fileCredentials); + _viewer = new Viewer(fileStream, loadOptions); + } + + return _viewer; + } + + private async Task GetFileStreamAsync(string filePath) + { + byte[] bytes = await _fileStorage.ReadFileAsync(filePath); + MemoryStream memoryStream = new MemoryStream(bytes); + return memoryStream; + } + + private async Task CreateLoadOptionsAsync(FileCredentials fileCredentials) + { + FileType loadFileType = FileType.FromExtension(fileCredentials.FileType); + if(loadFileType == FileType.Unknown) + loadFileType = await _fileTypeResolver.ResolveFileTypeAsync(fileCredentials.FilePath); + + LoadOptions loadOptions = new LoadOptions + { + FileType = FileType.FromExtension(loadFileType.Extension), + Password = fileCredentials.Password, + ResourceLoadingTimeout = TimeSpan.FromSeconds(3) + }; + return loadOptions; + } + + private async Task RenderPageInternalAsync( + Viewer viewer, FileCredentials fileCredentials, int pageNumber) + { + var page = RenderPage(viewer, fileCredentials.FilePath, pageNumber); + page = await _pageFormatter.FormatAsync(fileCredentials, page); + + return page; + } + + private static DocumentInfo ToDocumentInfo(ViewInfo viewInfo) + { + var printAllowed = true; + if (viewInfo is PdfViewInfo info) + printAllowed = info.PrintingAllowed; + + var fileType = viewInfo.FileType.Extension + .Replace(".", string.Empty); + + return new DocumentInfo + { + FileType = fileType, + PrintAllowed = printAllowed, + Pages = viewInfo.Pages.Select(page => new PageInfo + { + Number = page.Number, + Width = page.Width, + Height = page.Height, + Name = page.Name + }) + }; + } + + public void Dispose() + { + _viewer?.Dispose(); + _viewer = null; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs b/Demos/ASP.NET MVC/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs new file mode 100644 index 000000000..3a450ae76 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs @@ -0,0 +1,90 @@ +using GroupDocs.Viewer.Options; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions +{ + internal static class ViewOptionsExtensions + { + public static void CopyViewOptions(this HtmlViewOptions dst, HtmlViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyHtmlViewOptions(src); + } + + public static void CopyViewOptions(this PdfViewOptions dst, PdfViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyPdfViewOptions(src); + } + + public static void CopyViewOptions(this PngViewOptions dst, PngViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyPngViewOptions(src); + } + + public static void CopyViewOptions(this JpgViewOptions dst, JpgViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyJpgViewOptions(src); + } + + private static void CopyBaseViewOptions(this BaseViewOptions dst, BaseViewOptions src) + { + dst.RenderComments = src.RenderComments; + dst.RenderNotes = src.RenderNotes; + dst.RenderHiddenPages = src.RenderHiddenPages; + dst.DefaultFontName = src.DefaultFontName; + dst.ArchiveOptions = src.ArchiveOptions; + dst.CadOptions = src.CadOptions; + dst.EmailOptions = src.EmailOptions; + dst.OutlookOptions = src.OutlookOptions; + dst.PdfOptions = src.PdfOptions; + dst.ProjectManagementOptions = src.ProjectManagementOptions; + dst.SpreadsheetOptions = src.SpreadsheetOptions; + dst.WordProcessingOptions = src.WordProcessingOptions; + } + + private static void CopyHtmlViewOptions(this HtmlViewOptions dst, HtmlViewOptions src) + { + dst.RenderResponsive = src.RenderResponsive; + dst.Minify = src.Minify; + dst.RenderToSinglePage = src.RenderToSinglePage; + dst.ImageMaxWidth = src.ImageMaxWidth; + dst.ImageMaxHeight = src.ImageMaxHeight; + dst.ImageWidth = src.ImageWidth; + dst.ImageHeight = src.ImageHeight; + dst.ForPrinting = src.ForPrinting; + dst.ExcludeFonts = src.ExcludeFonts; + dst.FontsToExclude = src.FontsToExclude; + dst.FontsToExclude = src.FontsToExclude; + } + + private static void CopyPdfViewOptions(this PdfViewOptions dst, PdfViewOptions src) + { + dst.JpgQuality = src.JpgQuality; + dst.Security = src.Security; + dst.ImageMaxWidth = src.ImageMaxWidth; + dst.ImageMaxHeight = src.ImageMaxHeight; + dst.ImageWidth = src.ImageWidth; + dst.ImageHeight = src.ImageHeight; + } + + private static void CopyPngViewOptions(this PngViewOptions dst, PngViewOptions src) + { + dst.ExtractText = src.ExtractText; + dst.Width = src.Width; + dst.Height = src.Height; + dst.MaxWidth = src.MaxWidth; + dst.MaxHeight = src.MaxHeight; + } + private static void CopyJpgViewOptions(this JpgViewOptions dst, JpgViewOptions src) + { + dst.Quality = src.Quality; + dst.ExtractText = src.ExtractText; + dst.Width = src.Width; + dst.Height = src.Height; + dst.MaxWidth = src.MaxWidth; + dst.MaxHeight = src.MaxHeight; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs b/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs new file mode 100644 index 000000000..d979c0600 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetMvc.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers +{ + internal class HtmlWithEmbeddedResourcesViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public HtmlWithEmbeddedResourcesViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => HtmlPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) + => new HtmlPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(HtmlWithEmbeddedResourcesViewer)} does not support retrieving external HTML resources."); + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromHtmlViewOptions(_config.HtmlViewOptions); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + private HtmlViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = HtmlViewOptions.ForEmbeddedResources(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.HtmlViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs b/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs new file mode 100644 index 000000000..8b85efc93 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions; +using GroupDocs.Viewer.Interfaces; +using GroupDocs.Viewer.Options; +using GroupDocs.Viewer.Results; +using Page = GroupDocs.Viewer.AspNetMvc.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers +{ + internal class HtmlWithExternalResourcesViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public HtmlWithExternalResourcesViewer( + ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => HtmlPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) + => new HtmlPage(pageNumber, data); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var basePath = Constants.API_PATH; + var actionName = Constants.LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME; + + var streamFactory = new MemoryPageStreamFactory(basePath, actionName, filePath); + var viewOptions = HtmlViewOptions.ForExternalResources(streamFactory, streamFactory); + viewOptions.CopyViewOptions(_config.HtmlViewOptions); + viewer.View(viewOptions, pageNumber); + + var pageContents = streamFactory.GetPageContents(); + var page = CreatePage(pageNumber, pageContents.GetPageData()); + foreach (var resource in pageContents.Resources) + { + var pageResource = new PageResource(resource.Key, resource.Value.ToArray()); + page.AddResource(pageResource); + } + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromHtmlViewOptions(_config.HtmlViewOptions); + + public override async Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) + { + var page = await GetPageAsync(fileCredentials, pageNumber); + var resource = page.GetResource(resourceName); + + return resource.Data; + } + + private class MemoryPageStreamFactory : IPageStreamFactory, IResourceStreamFactory + { + private readonly string _basePath; + private readonly string _actionName; + private readonly string _filePath; + private readonly PageContents _pageContents; + + public MemoryPageStreamFactory(string basePath, string actionName, string filePath) + { + _basePath = basePath; + _actionName = actionName; + _filePath = WebUtility.UrlEncode(filePath); + _pageContents = new PageContents(); + } + + public PageContents GetPageContents() => + _pageContents; + + public Stream CreatePageStream(int pageNumber) => + _pageContents.GetPageStream(); + + public void ReleasePageStream(int pageNumber, Stream pageStream) { } + + public Stream CreateResourceStream(int pageNumber, Resource resource) => + _pageContents.GetResourceStream(resource.FileName); + + public string CreateResourceUrl(int pageNumber, Resource resource) => + $"/{_basePath}/{_actionName}?guid={_filePath}&pageNumber={pageNumber}&resourceName={resource.FileName}"; + + public void ReleaseResourceStream(int pageNumber, Resource resource, Stream resourceStream) { } + } + + private class PageContents + { + private MemoryStream PageStream { get; } = new MemoryStream(); + + public Dictionary Resources { get; } = new Dictionary(); + + public byte[] GetPageData() => PageStream.ToArray(); + + public Stream GetPageStream() => PageStream; + + public Stream GetResourceStream(string fileName) + { + var resourceStream = new MemoryStream(); + Resources.Add(fileName, resourceStream); + return resourceStream; + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/JpgViewer.cs b/Demos/ASP.NET MVC/src/Core/Viewers/JpgViewer.cs new file mode 100644 index 000000000..8aa060203 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/JpgViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetMvc.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers +{ + internal class JpgViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public JpgViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => JpgPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) => + new JpgPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(JpgViewer)} does not support retrieving external HTML resources."); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromJpgViewOptions(_config.JpgViewOptions); + + private JpgViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = new JpgViewOptions(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.JpgViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Core/Viewers/PngViewer.cs b/Demos/ASP.NET MVC/src/Core/Viewers/PngViewer.cs new file mode 100644 index 000000000..d114172b0 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Core/Viewers/PngViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.Entities; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetMvc.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetMvc.Core.Viewers +{ + internal class PngViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public PngViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => PngPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) => + new PngPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(PngViewer)} does not support retrieving external HTML resources."); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromJpgViewOptions(_config.JpgViewOptions); + + private PngViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = new PngViewOptions(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.PngViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/MVC/src/Global.asax b/Demos/ASP.NET MVC/src/Global.asax similarity index 54% rename from Demos/MVC/src/Global.asax rename to Demos/ASP.NET MVC/src/Global.asax index 8c1c899fe..84e6facc2 100644 --- a/Demos/MVC/src/Global.asax +++ b/Demos/ASP.NET MVC/src/Global.asax @@ -1 +1 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="GroupDocs.Viewer.MVC.WebApiApplication" Language="C#" %> +<%@ Application Codebehind="Global.asax.cs" Inherits="GroupDocs.Viewer.AspNetMvc.MvcApplication" Language="C#" %> diff --git a/Demos/ASP.NET MVC/src/Global.asax.cs b/Demos/ASP.NET MVC/src/Global.asax.cs new file mode 100644 index 000000000..e79f7b294 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Global.asax.cs @@ -0,0 +1,80 @@ +using GroupDocs.Viewer.AspNetMvc.Core.Configuration; +using GroupDocs.Viewer.AspNetMvc.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetMvc.Core.Licensing; +using GroupDocs.Viewer.AspNetMvc.Core.PageFormatting; +using GroupDocs.Viewer.AspNetMvc.Core.Viewers; +using GroupDocs.Viewer.AspNetMvc.Core; +using System.Web; +using System.Web.Http; +using System.Web.Routing; +using GroupDocs.Viewer.AspNetMvc.Core.Caching; +using GroupDocs.Viewer.AspNetMvc.Core.Storage; +using Unity; +using Unity.WebApi; + +namespace GroupDocs.Viewer.AspNetMvc +{ + public class MvcApplication : HttpApplication + { + protected void Application_Start() + { + UnityContainer container = new UnityContainer(); + ConfigureServices(container); + + GlobalConfiguration.Configuration.DependencyResolver = + new UnityDependencyResolver(container); + + GlobalConfiguration.Configure(WebApiConfig.Register); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + + private void ConfigureServices(UnityContainer container) + { + var viewerType = ViewerType.HtmlWithEmbeddedResources; + + //Temporary license can be requested at https://purchase.groupdocs.com/temporary-license + var licensePath = Server.MapPath("~/GroupDocs.Viewer.lic"); + var filesPath = Server.MapPath("~/Storage/Files"); + var cachePath = Server.MapPath("~/Storage/Cache"); + + var uiConfig = UIConfig.Instance + .SetViewerType(viewerType); + var viewerConfig = ViewerConfig.Instance + .SetLicensePath(licensePath); + + container.RegisterFactory(c => viewerConfig); + container.RegisterFactory(c => uiConfig); + container.RegisterFactory(c => new LocalFileStorage(filesPath)); + container.RegisterFactory(c => new LocalFileCache(cachePath)); + container.RegisterType(); + container.RegisterType(); + container.RegisterType(); + container.RegisterType(); + + container.RegisterFactory(c => + { + IViewer viewer; + switch (uiConfig.ViewerType) + { + case ViewerType.HtmlWithExternalResources: + viewer = c.Resolve(); + break; + case ViewerType.Jpg: + viewer = c.Resolve(); + break; + case ViewerType.Png: + viewer = c.Resolve(); + break; + default: + viewer = c.Resolve(); + break; + } + + var fileCache = c.Resolve(); + var asyncLock = c.Resolve(); + + return new CachingViewer(viewer, fileCache, asyncLock); + }); + } + } +} diff --git a/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.csproj b/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.csproj new file mode 100644 index 000000000..980b7f176 --- /dev/null +++ b/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.csproj @@ -0,0 +1,295 @@ + + + + + Debug + AnyCPU + + + 2.0 + {C2FB838B-47FC-47BF-9532-C2D4DAAA58B7} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + GroupDocs.Viewer.AspNetMvc + GroupDocs.Viewer.AspNetMvc + v4.8 + false + true + + 44305 + + + + + + false + ClientApp\ + true + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + packages\GroupDocs.Viewer.22.9.0\lib\net40\GroupDocs.Viewer.dll + + + packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + + + packages\Microsoft.Web.Infrastructure.2.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll + + + packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + packages\Microsoft.AspNet.Cors.5.2.9\lib\net45\System.Web.Cors.dll + + + + + + + + + packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.Helpers.dll + + + packages\Microsoft.AspNet.WebApi.Core.5.2.9\lib\net45\System.Web.Http.dll + + + packages\Microsoft.AspNet.WebApi.Cors.5.2.9\lib\net45\System.Web.Http.Cors.dll + + + packages\Microsoft.AspNet.WebApi.WebHost.5.2.9\lib\net45\System.Web.Http.WebHost.dll + + + packages\Microsoft.AspNet.Mvc.5.2.9\lib\net45\System.Web.Mvc.dll + + + packages\Microsoft.AspNet.Razor.3.2.9\lib\net45\System.Web.Razor.dll + + + packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.dll + + + packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.Deployment.dll + + + packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.Razor.dll + + + + + + + + + + + + + + + + packages\Unity.5.11.9\lib\net48\Unity.Abstractions.dll + + + packages\Unity.5.11.9\lib\net48\Unity.Container.dll + + + packages\Unity.WebAPI.5.4.0\lib\net45\Unity.WebApi.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Global.asax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + True + True + 8080 + / + https://localhost:44391/ + False + False + + + False + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.sln b/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.sln new file mode 100644 index 000000000..7cc86dc27 --- /dev/null +++ b/Demos/ASP.NET MVC/src/GroupDocs.Viewer.AspNetMvc.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32510.428 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.AspNetMvc", "GroupDocs.Viewer.AspNetMvc.csproj", "{C2FB838B-47FC-47BF-9532-C2D4DAAA58B7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C2FB838B-47FC-47BF-9532-C2D4DAAA58B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2FB838B-47FC-47BF-9532-C2D4DAAA58B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2FB838B-47FC-47BF-9532-C2D4DAAA58B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2FB838B-47FC-47BF-9532-C2D4DAAA58B7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {074D56D1-F6C6-4C9A-9D2B-6FA06AB48B29} + EndGlobalSection +EndGlobal diff --git a/Demos/ASP.NET MVC/src/Models/ErrorResponse.cs b/Demos/ASP.NET MVC/src/Models/ErrorResponse.cs new file mode 100644 index 000000000..54e2013b1 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/ErrorResponse.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class ErrorResponse + { + /// + /// The error message. + /// + [JsonProperty("message")] + public string Message { get; set; } + + public ErrorResponse(string message) + { + this.Message = message; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/FileDescription.cs b/Demos/ASP.NET MVC/src/Models/FileDescription.cs new file mode 100644 index 000000000..34da217f2 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/FileDescription.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class FileDescription + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; } + + /// + /// File file name. + /// + [JsonProperty("name")] + public string Name { get; } + + /// + /// True when it is a directory. + /// + [JsonProperty("isDirectory")] + public bool IsDirectory { get; } + + /// + /// Size in bytes. + /// + [JsonProperty("size")] + public long Size { get; } + + /// + /// .ctor + /// + public FileDescription(string guid, string name, bool isDirectory, long size) + { + Guid = guid; + Name = name; + IsDirectory = isDirectory; + Size = size; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadConfigResponse.cs b/Demos/ASP.NET MVC/src/Models/LoadConfigResponse.cs new file mode 100644 index 000000000..d56a1b46b --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadConfigResponse.cs @@ -0,0 +1,121 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadConfigResponse + { + /// + /// Enables page selector control. + /// + [JsonProperty("pageSelector")] + public bool PageSelector { get; set; } + + /// + /// Enables download button. + /// + [JsonProperty("download")] + public bool Download { get; set; } + + /// + /// Enables upload. + /// + [JsonProperty("upload")] + public bool Upload { get; set; } + + /// + /// Enables printing. + /// + [JsonProperty("print")] + public bool Print { get; set; } + + /// + /// Enables file browser. + /// + [JsonProperty("browse")] + public bool Browse { get; set; } + + /// + /// Enables file rewrite. + /// + [JsonProperty("rewrite")] + public bool Rewrite { get; set; } + + /// + /// Enables right click. + /// + [JsonProperty("enableRightClick")] + public bool EnableRightClick { get; set; } + + /// + /// The default document to view. + /// + [JsonProperty("defaultDocument")] + public string DefaultDocument { get; set; } + + /// + /// Count pages to preload. + /// + [JsonProperty("preloadPageCount")] + public int PreloadPageCount { get; set; } + + /// + /// Enables zoom. + /// + [JsonProperty("zoom")] + public bool Zoom { get; set; } + + /// + /// Enables searching. + /// + [JsonProperty("search")] + public bool Search { get; set; } + + /// + /// Enables thumbnails. + /// + [JsonProperty("thumbnails")] + public bool Thumbnails { get; set; } + + /// + /// Image or HTML mode. + /// + [JsonProperty("htmlMode")] + public bool HtmlMode { get; set; } + + /// + /// Enables printing + /// + [JsonProperty("printAllowed")] + public bool PrintAllowed { get; set; } + + /// + /// Enables rotation + /// + [JsonProperty("rotate")] + public bool Rotate { get; set; } + + /// + /// Enables saving of rotation state + /// + [JsonProperty("saveRotateState")] + public bool SaveRotateState { get; set; } + + /// + /// Default language e.g. "en". + /// + [JsonProperty("defaultLanguage")] + public string DefaultLanguage { get; set; } + + /// + /// Supported languages e.g. [ "en", "fr", "de" ] + /// + [JsonProperty("supportedLanguages")] + public string[] SupportedLanguages { get; set; } + + /// + /// Enables language menu. + /// + [JsonProperty("showLanguageMenu")] + public bool ShowLanguageMenu { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionRequest.cs b/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionRequest.cs new file mode 100644 index 000000000..ab0ce624c --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionRequest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadDocumentDescriptionRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionResponse.cs b/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionResponse.cs new file mode 100644 index 000000000..8c99a3d1e --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadDocumentDescriptionResponse.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadDocumentDescriptionResponse + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// Indicates if printing of the document is allowed. + /// + [JsonProperty("printAllowed")] + public bool PrintAllowed { get; set; } + + /// + /// Document pages. + /// + [JsonProperty("pages")] + public List Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadDocumentPageRequest.cs b/Demos/ASP.NET MVC/src/Models/LoadDocumentPageRequest.cs new file mode 100644 index 000000000..58d842853 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadDocumentPageRequest.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadDocumentPageRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + + /// + /// The page to return. + /// + [JsonProperty("page")] + public int Page { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadDocumentPagesRequest.cs b/Demos/ASP.NET MVC/src/Models/LoadDocumentPagesRequest.cs new file mode 100644 index 000000000..ea0516350 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadDocumentPagesRequest.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadDocumentPagesRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g. "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + + /// + /// The pages to return. + /// + [JsonProperty("pages")] + public int[] Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/LoadFileTreeRequest.cs b/Demos/ASP.NET MVC/src/Models/LoadFileTreeRequest.cs new file mode 100644 index 000000000..3f7ee5ca4 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/LoadFileTreeRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class LoadFileTreeRequest + { + /// + /// Folder path. + /// + [JsonProperty("path")] + public string Path { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/PageContent.cs b/Demos/ASP.NET MVC/src/Models/PageContent.cs new file mode 100644 index 000000000..9f8ebab9d --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/PageContent.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class PageContent + { + /// + /// Page number. + /// + [JsonProperty("number")] + public int Number { get; set; } + + /// + /// Page contents. It can be HTML or base64-encoded image. + /// + [JsonProperty("data")] + public string Data { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/PageDescription.cs b/Demos/ASP.NET MVC/src/Models/PageDescription.cs new file mode 100644 index 000000000..025f0649c --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/PageDescription.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class PageDescription : PageContent + { + /// + /// Page with in pixels. + /// + [JsonProperty("width")] + public int Width { get; set; } + + /// + /// Page height in pixels. + /// + [JsonProperty("height")] + public int Height { get; set; } + + /// + /// Worksheet name for spreadsheets. + /// + [JsonProperty("sheetName")] + public string SheetName { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/PrintPdfRequest.cs b/Demos/ASP.NET MVC/src/Models/PrintPdfRequest.cs new file mode 100644 index 000000000..63f5ceba8 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/PrintPdfRequest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class PrintPdfRequest + { + /// + /// Unique file ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g. "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// Password to open the document. + /// + [JsonProperty("password")] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/Models/UploadFileResponse.cs b/Demos/ASP.NET MVC/src/Models/UploadFileResponse.cs new file mode 100644 index 000000000..a4c087b12 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Models/UploadFileResponse.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetMvc.Models +{ + public class UploadFileResponse + { + /// + /// Unique file ID. + /// + [JsonProperty("guid")] + public string Guid { get; } + + /// + /// .ctor + /// + public UploadFileResponse(string filePath) + { + Guid = filePath; + } + } +} \ No newline at end of file diff --git a/Demos/MVC/src/Properties/AssemblyInfo.cs b/Demos/ASP.NET MVC/src/Properties/AssemblyInfo.cs similarity index 73% rename from Demos/MVC/src/Properties/AssemblyInfo.cs rename to Demos/ASP.NET MVC/src/Properties/AssemblyInfo.cs index 175774fff..b8ad6f19d 100644 --- a/Demos/MVC/src/Properties/AssemblyInfo.cs +++ b/Demos/ASP.NET MVC/src/Properties/AssemblyInfo.cs @@ -1,35 +1,35 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GroupDocs.Viewer MVC")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Aspose Pty Ltd")] -[assembly: AssemblyProduct("GroupDocs.Viewer MVC")] -[assembly: AssemblyCopyright("2001-2018 Aspose Pty Ltd")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("cb1d0987-217d-43e0-afff-fae210c23d96")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.20.0.0")] -[assembly: AssemblyFileVersion("1.20.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GroupDocs.Viewer.AspNetMvc")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("GroupDocs.Viewer.AspNetMvc")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4647bffb-d10b-4211-8782-2e9d3f57166e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demos/MVC/src/Licenses/.gitkeep b/Demos/ASP.NET MVC/src/Storage/Cache/.gitkeep similarity index 100% rename from Demos/MVC/src/Licenses/.gitkeep rename to Demos/ASP.NET MVC/src/Storage/Cache/.gitkeep diff --git a/Demos/ASP.NET MVC/src/Storage/Files/flowchart.vsdx b/Demos/ASP.NET MVC/src/Storage/Files/flowchart.vsdx new file mode 100644 index 000000000..12db7e009 Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/flowchart.vsdx differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/groupdocs.pptx b/Demos/ASP.NET MVC/src/Storage/Files/groupdocs.pptx new file mode 100644 index 000000000..d94d696dd Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/groupdocs.pptx differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/house-plan.dwg b/Demos/ASP.NET MVC/src/Storage/Files/house-plan.dwg new file mode 100644 index 000000000..ff07697b5 Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/house-plan.dwg differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/invoice.xlsx b/Demos/ASP.NET MVC/src/Storage/Files/invoice.xlsx new file mode 100644 index 000000000..f223175b2 Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/invoice.xlsx differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/resume.docx b/Demos/ASP.NET MVC/src/Storage/Files/resume.docx new file mode 100644 index 000000000..1d9f67edb Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/resume.docx differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/resume.pdf b/Demos/ASP.NET MVC/src/Storage/Files/resume.pdf new file mode 100644 index 000000000..ef4cae4db Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/resume.pdf differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/software-development-plan.mpp b/Demos/ASP.NET MVC/src/Storage/Files/software-development-plan.mpp new file mode 100644 index 000000000..5e48341a2 Binary files /dev/null and b/Demos/ASP.NET MVC/src/Storage/Files/software-development-plan.mpp differ diff --git a/Demos/ASP.NET MVC/src/Storage/Files/vector-image.svg b/Demos/ASP.NET MVC/src/Storage/Files/vector-image.svg new file mode 100644 index 000000000..6df8640de --- /dev/null +++ b/Demos/ASP.NET MVC/src/Storage/Files/vector-image.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/ASP.NET MVC/src/Views/Viewer/Index.cshtml b/Demos/ASP.NET MVC/src/Views/Viewer/Index.cshtml new file mode 100644 index 000000000..1708d9c0b --- /dev/null +++ b/Demos/ASP.NET MVC/src/Views/Viewer/Index.cshtml @@ -0,0 +1,23 @@ +@using GroupDocs.Viewer.AspNetMvc.Core +@{ + var apiEndpoint = $"/{Constants.API_PATH}"; + var uiSettingsPath = $"/{Constants.API_PATH}/{Constants.LOAD_CONFIG_ACTION_NAME}"; +} + + + + + + GroupDocs.Viewer for .NET ASP.NET MVC Demo + + + + + + + + + \ No newline at end of file diff --git a/Demos/MVC/src/Views/Web.config b/Demos/ASP.NET MVC/src/Views/Web.config similarity index 83% rename from Demos/MVC/src/Views/Web.config rename to Demos/ASP.NET MVC/src/Views/Web.config index 48d2d9d7f..b2c758bef 100644 --- a/Demos/MVC/src/Views/Web.config +++ b/Demos/ASP.NET MVC/src/Views/Web.config @@ -1,43 +1,42 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/ASP.NET MVC/src/Web.Debug.config b/Demos/ASP.NET MVC/src/Web.Debug.config new file mode 100644 index 000000000..d7712aaf1 --- /dev/null +++ b/Demos/ASP.NET MVC/src/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/Demos/ASP.NET MVC/src/Web.Release.config b/Demos/ASP.NET MVC/src/Web.Release.config new file mode 100644 index 000000000..28a4d5fcc --- /dev/null +++ b/Demos/ASP.NET MVC/src/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/Demos/MVC/src/Web.config b/Demos/ASP.NET MVC/src/Web.config similarity index 52% rename from Demos/MVC/src/Web.config rename to Demos/ASP.NET MVC/src/Web.config index ff7ad2dae..50ef64a20 100644 --- a/Demos/MVC/src/Web.config +++ b/Demos/ASP.NET MVC/src/Web.config @@ -1,179 +1,136 @@ - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/ASP.NET MVC/src/packages.config b/Demos/ASP.NET MVC/src/packages.config new file mode 100644 index 000000000..0d61d9edf --- /dev/null +++ b/Demos/ASP.NET MVC/src/packages.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/WebForms/.gitattributes b/Demos/ASP.NET Web Forms/.gitattributes similarity index 100% rename from Demos/WebForms/.gitattributes rename to Demos/ASP.NET Web Forms/.gitattributes diff --git a/Demos/WebForms/.gitignore b/Demos/ASP.NET Web Forms/.gitignore similarity index 100% rename from Demos/WebForms/.gitignore rename to Demos/ASP.NET Web Forms/.gitignore diff --git a/Demos/MVC/LICENSE b/Demos/ASP.NET Web Forms/LICENSE similarity index 98% rename from Demos/MVC/LICENSE rename to Demos/ASP.NET Web Forms/LICENSE index 23998b433..af0a3dfc5 100644 --- a/Demos/MVC/LICENSE +++ b/Demos/ASP.NET Web Forms/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2001-2018 Aspose Pty Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2001-2018 Aspose Pty Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Demos/ASP.NET Web Forms/README.md b/Demos/ASP.NET Web Forms/README.md new file mode 100644 index 000000000..aba8fbbd4 --- /dev/null +++ b/Demos/ASP.NET Web Forms/README.md @@ -0,0 +1,69 @@ +![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") + +# GroupDocs.Viewer for .NET ASP.NET Web Forms Demo + +![GitHub](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET) + +In order to demonstrate [GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) reach and powerful features we prepared **document viewer** demo. Which can be used as a standalone application or easily integrated into your project. + +## System Requirements +- .NET Framework 4.8 +- Visual Studio 2022 + +## Supported Document Formats + +GroupDocs.Viewer for .NET enables you to render Microsoft Word, Microsoft Excel, Microsoft PowerPoint, and many more file types in HTML, PDF, PNG, and JPEG formats. The complete list of the supported document and file formats can be found in the [Supported document formats](https://docs.groupdocs.com/viewer/net/supported-document-formats/) documentation article. + +## Demo Video + +

+ + + +

+ +## Features +- Responsive design +- Fully customizable navigation panel & thumbnails +- Text searching & highlighting +- Download & upload documents +- Print document as PDF +- Zoom in/out documents without quality loss in HTML mode +- Smooth page navigation & scrolling +- Preload pages for faster document rendering +- Multi-language support + +## How To Run + +Download the [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/archive/master.zip) from github or clone this repository: + +```bash +git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET +``` + +Navigate to `Demos\ASP.NET Web Forms\src` and open `GroupDocs.Viewer.AspNetWebForms.sln` in Visual Studio. Build and run the project. + +Open the app by navigating to in your favorite browser. + +## Configuration + +You can configure this demo project in [Global.asax.cs](./src/Global.asax.cs) file in `ConfigureServices` method which includes configuration for GroupDocs.Viewer and UI. + +NOTE: without a license application will run in trial mode, [purchase a license](https://purchase.groupdocs.com/buy) or [request a temporary license](https://purchase.groupdocs.com/temporary-license). + +## License + +The MIT License (MIT). + +Please have a look at the [LICENSE](LICENSE) for more details + +## More Demo Projects + +- [Java Dropwizard Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) +- [Java Spring Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [ASP.NET Core Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Core) +- [ASP.NET MVC Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20MVC) +- [Windows Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/Windows%20Forms) +- [WPF Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/WPF) + +[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Examples) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/ASP.NET Web Forms/src/ActionResults/FileActionResult.cs b/Demos/ASP.NET Web Forms/src/ActionResults/FileActionResult.cs new file mode 100644 index 000000000..1e56f8103 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ActionResults/FileActionResult.cs @@ -0,0 +1,50 @@ +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetWebForms.ActionResults +{ + internal class FileActionResult : IHttpActionResult + { + private readonly byte[] _data; + private readonly string _fileName; + private readonly string _contentType; + readonly HttpRequestMessage _request; + + public FileActionResult(byte[] data, string fileName, string contentType, + HttpRequestMessage request) + { + _data = data; + _fileName = fileName; + _contentType = contentType; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var response = new HttpResponseMessage + { + Content = new ByteArrayContent(_data), + StatusCode = HttpStatusCode.OK, + RequestMessage = _request + }; + + var contentType = string.IsNullOrEmpty(_contentType) + ? "application/octet-stream" + : _contentType; + + response.Content.Headers.ContentType = + new MediaTypeHeaderValue(contentType); + response.Content.Headers.ContentDisposition = + new ContentDispositionHeaderValue("attachment") + { + FileName = _fileName + }; + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/ActionResults/JsonActionResult.cs b/Demos/ASP.NET Web Forms/src/ActionResults/JsonActionResult.cs new file mode 100644 index 000000000..8d2eb0b8a --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ActionResults/JsonActionResult.cs @@ -0,0 +1,39 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.ActionResults +{ + internal class JsonActionResult : IHttpActionResult + { + readonly object _value; + public HttpStatusCode StatusCode { get; set; } = HttpStatusCode.OK; + + readonly HttpRequestMessage _request; + + public JsonActionResult(object value, HttpRequestMessage request) + { + _value = value; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var json = JsonConvert.SerializeObject(_value, Formatting.Indented); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = new HttpResponseMessage + { + Content = content, + StatusCode = StatusCode, + RequestMessage = _request + }; + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/ActionResults/ResourceActionResult.cs b/Demos/ASP.NET Web Forms/src/ActionResults/ResourceActionResult.cs new file mode 100644 index 000000000..7a7f313f9 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ActionResults/ResourceActionResult.cs @@ -0,0 +1,40 @@ +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetWebForms.ActionResults +{ + internal class ResourceActionResult : IHttpActionResult + { + private readonly byte[] _data; + private readonly string _contentType; + readonly HttpRequestMessage _request; + + public ResourceActionResult(byte[] data, string contentType, HttpRequestMessage request) + { + _data = data; + _contentType = contentType; + _request = request; + } + + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var response = new HttpResponseMessage + { + Content = new ByteArrayContent(_data), + StatusCode = HttpStatusCode.OK, + RequestMessage = _request + }; + + response.Content.Headers.ContentType = + new MediaTypeHeaderValue(_contentType); + response.Content.Headers.ContentDisposition + = new ContentDispositionHeaderValue("inline"); + + return Task.FromResult(response); + } + } +} \ No newline at end of file diff --git a/Demos/MVC/src/App_Start/WebApiConfig.cs b/Demos/ASP.NET Web Forms/src/App_Start/WebApiConfig.cs similarity index 78% rename from Demos/MVC/src/App_Start/WebApiConfig.cs rename to Demos/ASP.NET Web Forms/src/App_Start/WebApiConfig.cs index df8d9156e..c5d261b34 100644 --- a/Demos/MVC/src/App_Start/WebApiConfig.cs +++ b/Demos/ASP.NET Web Forms/src/App_Start/WebApiConfig.cs @@ -1,16 +1,14 @@ -using System.Web.Http; - -namespace GroupDocs.Viewer.MVC -{ - public static class WebApiConfig - { - public static void Register(HttpConfiguration config) - { - // enable CORS - config.EnableCors(); - - // Web API routes - config.MapHttpAttributeRoutes(); - } - } -} +using System.Web.Http; + +namespace GroupDocs.Viewer.AspNetWebForms +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API routes + config.EnableCors(); + config.MapHttpAttributeRoutes(); + } + } +} diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/.browserslistrc b/Demos/ASP.NET Web Forms/src/ClientApp/.browserslistrc new file mode 100644 index 000000000..427441dc9 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/.browserslistrc @@ -0,0 +1,17 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/Demos/MVC/src/client/.gitignore b/Demos/ASP.NET Web Forms/src/ClientApp/.gitignore similarity index 79% rename from Demos/MVC/src/client/.gitignore rename to Demos/ASP.NET Web Forms/src/ClientApp/.gitignore index ee5c9d833..86d943a9b 100644 --- a/Demos/MVC/src/client/.gitignore +++ b/Demos/ASP.NET Web Forms/src/ClientApp/.gitignore @@ -4,10 +4,16 @@ /dist /tmp /out-tsc +# Only exists if Bazel was run +/bazel-out # dependencies /node_modules +# profiling files +chrome-profiler-events*.json +speed-measure-plugin*.json + # IDEs and editors /.idea .project @@ -23,6 +29,7 @@ !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +.history/* # misc /.sass-cache diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/README.md b/Demos/ASP.NET Web Forms/src/ClientApp/README.md new file mode 100644 index 000000000..daf9ae209 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/README.md @@ -0,0 +1,19 @@ +# GroupdocsViewerUI + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.2.3. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/angular.json b/Demos/ASP.NET Web Forms/src/ClientApp/angular.json new file mode 100644 index 000000000..55575bfe2 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/angular.json @@ -0,0 +1,116 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "groupdocs-viewer-ui": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "inlineTemplate": true, + "inlineStyle": true, + "skipTests": true + }, + "@schematics/angular:class": { + "skipTests": true + }, + "@schematics/angular:directive": { + "skipTests": true + }, + "@schematics/angular:guard": { + "skipTests": true + }, + "@schematics/angular:interceptor": { + "skipTests": true + }, + "@schematics/angular:module": { + "skipTests": true + }, + "@schematics/angular:pipe": { + "skipTests": true + }, + "@schematics/angular:service": { + "skipTests": true + }, + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "aot": true, + "assets": [ + "src/assets" + ], + "styles": [], + "scripts": [], + "allowedCommonJsDependencies": [ + "hammerjs", "jquery" + ] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "index": { + "input": "src/index.prod.html", + "output": "index.html" + }, + "outputPath": "../assets", + "optimization": true, + "outputHashing": "none", + "sourceMap": false, + "namedChunks": false, + "extractLicenses": false, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "4000kb", + "maximumError": "5000kb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "5kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "groupdocs-viewer-ui:build" + }, + "configurations": { + "production": { + "browserTarget": "groupdocs-viewer-ui:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "groupdocs-viewer-ui:build" + } + } + } + } + } +} diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/package.json b/Demos/ASP.NET Web Forms/src/ClientApp/package.json new file mode 100644 index 000000000..e6ff78140 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/package.json @@ -0,0 +1,31 @@ +{ + "name": "groupdocs-viewer-ui", + "version": "1.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --configuration=production" + }, + "private": true, + "dependencies": { + "@angular/animations": "^14.1.0", + "@angular/common": "^14.1.0", + "@angular/compiler": "^14.1.0", + "@angular/core": "^14.1.0", + "@angular/forms": "^14.1.0", + "@angular/platform-browser": "^14.1.0", + "@angular/platform-browser-dynamic": "^14.1.0", + "@angular/router": "^14.1.0", + "@groupdocs.examples.angular/viewer": "^0.8.92", + "rxjs": "^7.5.6", + "tslib": "^2.4.0", + "zone.js": "^0.11.7" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^14.1.0", + "@angular/cli": "^14.1.0", + "@angular/compiler-cli": "^14.1.0", + "@types/node": "^18.0.6", + "typescript": "^4.7.4" + } +} diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.html b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.html new file mode 100644 index 000000000..be08b9bd6 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.html @@ -0,0 +1,109 @@ + +
+
+ + + + + + + + + + +
{{currentPage}}/{{countPages}}
+ + + + + + + + + + + + +
+
+ +
+ + + {{'Present' | translate}} +
+
+
+
+ +
Viewer
+
{{getFileName()}}
+
+ + + + {{'Stop' | translate}} +
+
+
+
+ + + + + + +
+
+ {{secondsLeft}} +
+ + +
+
+ + + {{'Click' | translate}} {{'to open file' | translate}}
+ {{'Or drop file here' | translate}} +
+ + + + + +
diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.less b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.less new file mode 100644 index 000000000..5bf4280e9 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.less @@ -0,0 +1,256 @@ +@import (css) url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap'); +@import "./variables"; + +:host * { + font-family: 'Open Sans', Arial, Helvetica, sans-serif; +} + +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome, Edge, Opera and Firefox */ +} + +.current-page-number { + margin-left: 7px; + font-size : 14px; + color : @regent-gray; + width : 37px; + height : 37px; + line-height: 37px; + text-align : center; + + &.active { + color: #fff; + } +} + +.wrapper { + align-items: stretch; + height : 100%; + width : 100%; + position : fixed; + top : 0; + bottom : 0; + left : 0; + right : 0; +} + +.doc-panel { + display : flex; + height : calc(100vh - 60px); + flex-direction: row; +} + +.top-panel { + display : flex; + align-items: center; + width : 100%; +} + +.toolbar-panel { + background-color: @nav-main-background; + width : 100%; +} + +.toolbar-panel-right { + display: flex; + flex: 1; + place-content: flex-end; +} + +.btn-right { + margin-right: 7px; +} + +.smp-start-stop { + ::ng-deep .button { + flex-direction: row; + border: 1px solid; + border-radius: 5px; + padding: 0px 10px !important; + } +} + +.language-menu { + margin-right: 15px; +} + +.select-language-menu { + ::ng-deep .select { + width: 100%; + ::ng-deep .dropdown-menu { + overflow-y: scroll; + max-height: 90%; + } + } + + ::ng-deep .selected-value { + max-width: 100%; + } +} + +.thumbnails-button { + ::ng-deep .button { + margin-left: 0 !important; + } +} + + +::ng-deep .tools { + + .button, + .selected-value, + .nav-caret { + color: #fff !important; + + &.inactive { + color: @regent-gray !important; + } + } + + .button { + flex-flow: column; + } + + .select-left { + .select { + position: relative; + } + + .dropdown-menu { + top: 40px; + left: 0px; + } + } + + .select-right { + .select { + position: relative; + } + + .dropdown-menu { + top: 40px; + right: 0px; + } + } + + .dropdown-menu .option { + color: @dove-gray !important; + } + + .dropdown-menu .option:hover { + background-color: @folder !important; + } + + .icon-button { + margin: 0px 0px 0px 15px !important; + } + + .select { + width : 37px; + height : 37px; + margin-left: 7px; + line-height: 37px; + text-align : center; + } + + .slides-title { + color: white; + padding-left: 12px; + font-size: 18px; + } + + .slides-filename { + flex-grow: 1; + text-align: center; + color: white; + text-overflow: ellipsis; + white-space: nowrap; + padding-left: 20px; + overflow: hidden; + } + + .slides-buttons { + display: flex; + ::ng-deep .select { + color: white; + cursor: pointer; + } + } + + ::ng-deep .gd-nav-search-container + .icon-button { + margin: 0 0 0 7px !important; + } +} + +.slides-nav { + position: absolute; + right: 30px; + bottom: 30px; + display: flex; + ::ng-deep .button { + font-size: 37px; + background-color: @porcelain; + border-radius: 3px; + } + ::ng-deep .timer { + font-size: 42px; + line-height: 6px; + color: @regent-gray; + position: relative; + .seconds-remaining { + position: absolute; + margin-left: 5px; + font-size: 16px; + top: 18px; + left: 12px; + &.two-digits { + left: 6px !important; + } + } + } +} + +::ng-deep .page.presentation .gd-wrapper { + pointer-events: none; +} + +@media (max-width: 1037px) { + + .mobile-hide, + .current-page-number { + display: none; + } + + ::ng-deep .tools { + gd-button:nth-child(1)>.icon-button { + margin: 0px 0px 0px 10px !important; + } + + .icon-button { + height: 60px; + width : 60px; + } + + .gd-nav-search-btn { + .icon-button { + height: 37px; + width : 37px; + } + + .button { + font-size: 14px; + } + } + + .gd-nav-search-container { + top: 59px !important; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.ts new file mode 100644 index 000000000..54b9deeda --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.component.ts @@ -0,0 +1,122 @@ +import { Component, ChangeDetectorRef } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +import { ViewerAppComponent, ViewerService, ViewerConfigService } from '@groupdocs.examples.angular/viewer'; +import { Api, ConfigService, ModalService, UploadFilesService, NavigateService, ZoomService, PagePreloadService, RenderPrintService, PasswordService, WindowService, LoadingMaskService, PageModel, TypedFileCredentials } from '@groupdocs.examples.angular/common-components'; + +import { TranslateService } from '@ngx-translate/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.less', './variables.less'] +}) +export class AppComponent extends ViewerAppComponent { + + configService: ConfigService; + viewerService: ViewerService; + pagesLoading: number[]; + http: HttpClient; + + constructor(viewerService: ViewerService, + modalService: ModalService, + viewerConfigService: ViewerConfigService, + uploadFilesService: UploadFilesService, + navigateService: NavigateService, + zoomService: ZoomService, + pagePreloadService: PagePreloadService, + renderPrintService: RenderPrintService, + passwordService: PasswordService, + windowService: WindowService, + loadingMaskService: LoadingMaskService, + http: HttpClient, + configService: ConfigService, + cdr: ChangeDetectorRef, + translate: TranslateService) { + + super(viewerService, + modalService, + viewerConfigService, + uploadFilesService, + navigateService, + zoomService, + pagePreloadService, + renderPrintService, + passwordService, + windowService, + loadingMaskService, + cdr, + translate); + + this.configService = configService; + this.viewerService = viewerService; + this.pagesLoading = []; + this.http = http; + } + + preloadPages(start: number, end: number) { + const pagesToLoad = []; + const isInitialLoad = start === 1; + const minPagesToLoad = this.viewerConfig.preloadPageCount; + const countPages = this.file.pages.length; + this.selectedPageNumber = 1; + + if (isInitialLoad) { + this.pagesLoading = []; + } + + for (let i = start; i <= end; i++) { + const page = this.file.pages.find(p => p.number === i); + if(page && page.data) { + continue; + } + + if (this.pagesLoading.indexOf(i) === -1) { + this.pagesLoading.push(i); + pagesToLoad.push(i); + } + } + + if (pagesToLoad.length > 0) { + const last = pagesToLoad[pagesToLoad.length - 1]; + if (!isInitialLoad && pagesToLoad.length < minPagesToLoad) { + const addPages = minPagesToLoad - pagesToLoad.length; + for (let i = last; i < last + addPages; i++) { + const pageNumber = i + 1; + + if (pageNumber <= countPages && this.pagesLoading.indexOf(pageNumber) === -1) { + pagesToLoad.push(pageNumber); + this.pagesLoading.push(pageNumber); + } + } + } + + this.loadPages(this.credentials, pagesToLoad).subscribe(( + (pages: any) => { + pages.forEach((page: PageModel) => { + const pageIndex = page.number - 1; + const currPage = this.file.pages[pageIndex]; + + if (currPage) { + currPage.data = page.data; + if (this.file.thumbnails[pageIndex]) { + this.file.thumbnails[pageIndex].data = page.data; + this.file.thumbnails[pageIndex].width = currPage.width; + this.file.thumbnails[pageIndex].height = currPage.height; + } + } + }); + } + )); + } + } + + loadPages(credentials: TypedFileCredentials, pages: number[]) { + return this.http.post(this.configService.getViewerApiEndpoint() + Api.LOAD_DOCUMENT_PAGE + "s", { + 'guid': credentials.guid, + 'fileType': credentials.fileType, + 'password': credentials.password, + 'pages': pages + }, Api.httpOptionsJson); + } +} diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.module.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.module.ts new file mode 100644 index 000000000..645a436d3 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/app.module.ts @@ -0,0 +1,89 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { APP_BASE_HREF } from '@angular/common'; + +import { AppComponent } from './app.component'; +import { ConfigService } from '@groupdocs.examples.angular/common-components'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { ViewerConfigService, ViewerModule } from '@groupdocs.examples.angular/viewer'; +import { BehaviorSubject, Observable } from 'rxjs'; + +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { ViewerTranslateLoader } from "@groupdocs.examples.angular/viewer"; + +declare global { + interface Window { + apiEndpoint: string; + uiSettingsPath: string; + } +} + +/* +export class StaticViewerConfigService { + public updatedConfig: Observable = new BehaviorSubject({ + pageSelector: true, + download: true, + upload: true, + print: true, + browse: true, + rewrite: true, + enableRightClick: true, + filesDirectory: "", + fontsDirectory: "", + defaultDocument: "", + watermarkText: "", + preloadPageCount: 3, + zoom: true, + search: true, + thumbnails: true, + rotate: false, + htmlMode: true, + cache: true, + saveRotateState: false, + printAllowed: true, + showGridLines: true, + showLanguageMenu: true, + defaultLanguage: 'en', + supportedLanguages: ['en', 'fr', 'de'] + }).asObservable(); + + load(): Promise { + return Promise.resolve(); + } +} +*/ + +export function configServiceFactory() { + let config = new ConfigService(); + config.apiEndpoint = window.apiEndpoint; + config.getViewerApiEndpoint = () => window.apiEndpoint; + config.getConfigEndpoint = () => window.uiSettingsPath; + return config; +} + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), + ViewerModule, + FontAwesomeModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: ViewerTranslateLoader + } + }) + ], + providers: [ + { provide: APP_BASE_HREF, useValue: '/' }, + { provide: ConfigService, useFactory: configServiceFactory }, +/* + { provide: ViewerConfigService, useClass: StaticViewerConfigService }, +*/ + { provide: 'WINDOW', useValue: window }, + ], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/app/variables.less b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/variables.less new file mode 100644 index 000000000..6a8bedf1d --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/app/variables.less @@ -0,0 +1,31 @@ +@wide-screen-down: ~'(max-width: 1199px)'; +@desktop-down: ~'(max-width: 991px)'; +@tablet-down: ~'(max-width: 767px)'; +@phone-down: ~'(max-width: 1037px)'; +@small-phone-down: ~'(max-width: 320px)'; + +@nav-logo-background: #25c2d4; +@nav-main-background: #3e4e5a; +@nav-accent-background: #E5E5E5; +@nav-tabs-height: 30px; +@editor-nav-height: 90px; +@nav-tabs-height-m: 60px; +@nav-height: 60px; +@nav-icon-size: 20px; + +@primary: #3E4E5A; +@brand: #25c2d4; +@silver-chalice: #acacac; +@dove-gray: #6e6e6e; +@regent-gray: #959da5; +@wild-sand: #f4f4f4; +@mercury: #e7e7e7; +@silver: #c4c4c4; +@porcelain: #EDF0F2; + +@pdf: #e04e4e; +@word: #539CF0; +@powerpoint: #e29e1e; +@excel: #7cbc46; +@image: #c375ed; +@folder: #4b566c; diff --git a/Demos/MVC/src/Resources/.gitkeep b/Demos/ASP.NET Web Forms/src/ClientApp/src/assets/.gitkeep similarity index 100% rename from Demos/MVC/src/Resources/.gitkeep rename to Demos/ASP.NET Web Forms/src/ClientApp/src/assets/.gitkeep diff --git a/Demos/WebForms/src/client/apps/viewer/src/environments/environment.prod.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/environments/environment.prod.ts similarity index 100% rename from Demos/WebForms/src/client/apps/viewer/src/environments/environment.prod.ts rename to Demos/ASP.NET Web Forms/src/ClientApp/src/environments/environment.prod.ts diff --git a/Demos/WebForms/src/client/apps/viewer/src/environments/environment.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/environments/environment.ts similarity index 100% rename from Demos/WebForms/src/client/apps/viewer/src/environments/environment.ts rename to Demos/ASP.NET Web Forms/src/ClientApp/src/environments/environment.ts diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/favicon.ico b/Demos/ASP.NET Web Forms/src/ClientApp/src/favicon.ico new file mode 100644 index 000000000..54fb2a9b6 Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/ClientApp/src/favicon.ico differ diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/index.html b/Demos/ASP.NET Web Forms/src/ClientApp/src/index.html new file mode 100644 index 000000000..0b3e826b6 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/index.html @@ -0,0 +1,16 @@ + + + + + + GroupDocs.Viewer UI + + + + + + + diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/src/index.prod.html b/Demos/ASP.NET Web Forms/src/ClientApp/src/index.prod.html new file mode 100644 index 000000000..e42db0a95 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/index.prod.html @@ -0,0 +1,17 @@ + + + + + + GroupDocs.Viewer UI + + + + + + + + diff --git a/Demos/WebForms/src/client/apps/viewer/src/main.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/main.ts similarity index 85% rename from Demos/WebForms/src/client/apps/viewer/src/main.ts rename to Demos/ASP.NET Web Forms/src/ClientApp/src/main.ts index fa4e0aef3..c7b673cf4 100644 --- a/Demos/WebForms/src/client/apps/viewer/src/main.ts +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/main.ts @@ -8,6 +8,5 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule) +platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); diff --git a/Demos/WebForms/src/client/apps/viewer/src/polyfills.ts b/Demos/ASP.NET Web Forms/src/ClientApp/src/polyfills.ts similarity index 94% rename from Demos/WebForms/src/client/apps/viewer/src/polyfills.ts rename to Demos/ASP.NET Web Forms/src/ClientApp/src/polyfills.ts index 2f258e56c..d5f67bd91 100644 --- a/Demos/WebForms/src/client/apps/viewer/src/polyfills.ts +++ b/Demos/ASP.NET Web Forms/src/ClientApp/src/polyfills.ts @@ -18,7 +18,9 @@ * BROWSER POLYFILLS */ -/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +/** + * IE11 requires the following for NgClass support on SVG elements + */ // import 'classlist.js'; // Run `npm install --save classlist.js`. /** @@ -35,7 +37,7 @@ * will put import in the top of bundle, so user need to create a separate file * in this directory (for example: zone-flags.ts), and put the following flags * into that file, and then add the following code before importing zone.js. - * import './zone-flags.ts'; + * import './zone-flags'; * * The flags allowed in zone-flags.ts are listed here. * @@ -55,7 +57,8 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. +import 'zone.js/dist/zone'; // Included with Angular CLI. + /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/Demos/WebForms/src/client/apps/viewer/src/styles.less b/Demos/ASP.NET Web Forms/src/ClientApp/src/styles.css similarity index 100% rename from Demos/WebForms/src/client/apps/viewer/src/styles.less rename to Demos/ASP.NET Web Forms/src/ClientApp/src/styles.css diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.app.json b/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.app.json new file mode 100644 index 000000000..82d91dc4a --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.json b/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.json new file mode 100644 index 000000000..94a24fe1e --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/ClientApp/tsconfig.json @@ -0,0 +1,30 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "es2015", + "module": "es2020", + "lib": [ + "es2018", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/Demos/ASP.NET Web Forms/src/Controllers/ViewerApiController.cs b/Demos/ASP.NET Web Forms/src/Controllers/ViewerApiController.cs new file mode 100644 index 000000000..3d06f1a50 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Controllers/ViewerApiController.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using System.Web.Http.Cors; +using GroupDocs.Viewer.AspNetWebForms.ActionResults; +using GroupDocs.Viewer.AspNetWebForms.Core; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.Extensions; +using GroupDocs.Viewer.AspNetWebForms.Core.Utils; +using GroupDocs.Viewer.AspNetWebForms.Models; + +namespace GroupDocs.Viewer.AspNetWebForms.Controllers +{ + [RoutePrefix(Constants.API_PATH)] + [EnableCors(origins: "*", headers: "*", methods: "*")] + public class ViewerApiController : ApiController + { + private readonly UIConfig _config; + private readonly IFileStorage _fileStorage; + private readonly IViewer _viewer; + + public ViewerApiController( + UIConfig uiConfig, + IFileStorage fileStorage, + IViewer viewer) + { + _config = uiConfig; + _fileStorage = fileStorage; + _viewer = viewer; + } + + [HttpGet] + [Route(Constants.LOAD_CONFIG_ACTION_NAME)] + public IHttpActionResult LoadConfig() + { + var config = new LoadConfigResponse + { + PageSelector = _config.PageSelector, + Download = _config.Download, + Upload = _config.Upload, + Print = _config.Print, + Browse = _config.Browse, + Rewrite = _config.Rewrite, + EnableRightClick = _config.EnableRightClick, + DefaultDocument = _config.DefaultDocument, + PreloadPageCount = _config.PreloadPageCount, + Zoom = _config.Zoom, + Search = _config.Search, + Thumbnails = _config.Thumbnails, + HtmlMode = _config.HtmlMode, + PrintAllowed = _config.PrintAllowed, + Rotate = _config.Rotate, + SaveRotateState = _config.SaveRotateState, + DefaultLanguage = _config.DefaultLanguage, + SupportedLanguages = _config.SupportedLanguages, + ShowLanguageMenu = _config.ShowLanguageMenu + }; + + return OkJsonResult(config); + } + + [HttpPost] + [Route(Constants.LOAD_FILE_TREE_ACTION_NAME)] + public async Task GetFileTree(LoadFileTreeRequest request) + { + if (!_config.Browse) + return ErrorJsonResult("Browsing files is disabled."); + + try + { + var files = + await _fileStorage.ListDirsAndFilesAsync(request.Path); + + var result = files + .Select(entity => new FileDescription(entity.FilePath, entity.FilePath, entity.IsDirectory, entity.Size)) + .ToList(); + + return OkJsonResult(result); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpGet] + [Route(Constants.DOWNLOAD_DOCUMENT_ACTION_NAME)] + public async Task DownloadDocument(string path) + { + if (!_config.Download) + return ErrorJsonResult("Downloading files is disabled."); + + try + { + var fileName = Path.GetFileName(path); + var bytes = await _fileStorage.ReadFileAsync(path); + + return FileResult(bytes, fileName); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpGet] + [Route(Constants.LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME)] + public async Task LoadDocumentPageResource( + [FromUri]string guid, [FromUri] int pageNumber, [FromUri] string resourceName) + { + if (!_config.HtmlMode) + return ErrorJsonResult("Loading page resources is disabled in image mode."); + + try + { + var fileCredentials = + new FileCredentials(guid, "", ""); + var bytes = + await _viewer.GetPageResourceAsync(fileCredentials, pageNumber, resourceName); + + if (bytes.Length == 0) + return NotFoundJsonResult($"Resource {resourceName} was not found"); + + var contentType = resourceName.ContentTypeFromFileName(); + + return ResourceFileResult(bytes, contentType); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.UPLOAD_DOCUMENT_ACTION_NAME)] + public async Task UploadDocument() + { + if (!_config.Upload) + return ErrorJsonResult("Uploading files is disabled."); + + try + { + var url = HttpContext.Current.Request.Form["url"]; + var (fileName, bytes) = await ReadOrDownloadFile(url); + bool.TryParse(HttpContext.Current.Request.Form["rewrite"], out var rewrite); + + var filePath = await _fileStorage.WriteFileAsync(fileName, bytes, rewrite); + var result = new UploadFileResponse(filePath); + + return OkJsonResult(result); + } + catch (Exception ex) + { + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.PRINT_PDF_ACTION_NAME)] + public async Task PrintPdf([FromBody] PrintPdfRequest request) + { + if (!_config.Print) + return ErrorJsonResult("Printing files is disabled."); + + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + + var filename = Path.GetFileName(request.Guid); + var pdfFileName = Path.ChangeExtension(filename, ".pdf"); + var pdfFileBytes = await _viewer.GetPdfAsync(fileCredentials); + + return FileResult(pdfFileBytes, pdfFileName, "application/pdf"); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_DESCRIPTION_ACTION_NAME)] + public async Task LoadDocumentDescription([FromBody] LoadDocumentDescriptionRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var documentDescription = + await _viewer.GetDocumentInfoAsync(fileCredentials); + + var pageNumbers = GetPageNumbers(documentDescription.Pages.Count()); + var pagesData = await _viewer.GetPagesAsync(fileCredentials, pageNumbers); + + var pages = new List(); + foreach (PageInfo pageInfo in documentDescription.Pages) + { + var pageData = pagesData.FirstOrDefault(p => p.PageNumber == pageInfo.Number); + var pageDescription = new PageDescription + { + Width = pageInfo.Width, + Height = pageInfo.Height, + Number = pageInfo.Number, + SheetName = pageInfo.Name, + Data = pageData?.GetContent() + }; + + pages.Add(pageDescription); + } + + var result = new LoadDocumentDescriptionResponse + { + Guid = request.Guid, + FileType = documentDescription.FileType, + PrintAllowed = documentDescription.PrintAllowed, + Pages = pages + }; + + return OkJsonResult(result); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + private int[] GetPageNumbers(int totalPageCount) + { + if (_config.PreloadPageCount == 0) + return Enumerable.Range(1, totalPageCount).ToArray(); + + var pageCount = + Math.Min(totalPageCount, _config.PreloadPageCount); + + return Enumerable.Range(1, pageCount).ToArray(); + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_PAGES_ACTION_NAME)] + public async Task LoadDocumentPages([FromBody] LoadDocumentPagesRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var pages = await _viewer.GetPagesAsync(fileCredentials, request.Pages); + var pageContents = pages + .Select(page => new PageContent { Number = page.PageNumber, Data = page.GetContent() }) + .ToList(); + + return OkJsonResult(pageContents); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + [HttpPost] + [Route(Constants.LOAD_DOCUMENT_PAGE_ACTION_NAME)] + public async Task LoadDocumentPage([FromBody] LoadDocumentPageRequest request) + { + try + { + var fileCredentials = + new FileCredentials(request.Guid, request.FileType, request.Password); + var page = await _viewer.GetPageAsync(fileCredentials, request.Page); + var pageContent = new PageContent { Number = page.PageNumber, Data = page.GetContent() }; + + return OkJsonResult(pageContent); + } + catch (Exception ex) + { + if (ex.Message.Contains("password")) + { + var message = string.IsNullOrEmpty(request.Password) + ? "Password Required" + : "Incorrect Password"; + + return ForbiddenJsonResult(message); + } + + return ErrorJsonResult(ex.Message); + } + } + + private Task<(string, byte[])> ReadOrDownloadFile(string url) + { + return string.IsNullOrEmpty(url) + ? ReadFileFromRequest() + : DownloadFileAsync(url); + } + + private async Task<(string, byte[])> ReadFileFromRequest() + { + var provider = await Request.Content.ReadAsMultipartAsync(); + var firstFile = provider.Contents.First(); + + var bytes = await firstFile.ReadAsByteArrayAsync(); + var fileName = PathUtils.RemoveInvalidFileNameChars( + firstFile.Headers.ContentDisposition.FileName); + + return (fileName, bytes); + } + + private async Task<(string, byte[])> DownloadFileAsync(string url) + { + using (HttpClient httpClient = new HttpClient()) + { + httpClient.DefaultRequestHeaders.Add("User-Agent", "Other"); + + Uri uri = new Uri(url); + string fileName = Path.GetFileName(uri.LocalPath); + byte[] bytes = await httpClient.GetByteArrayAsync(uri); + + return (fileName, bytes); + } + } + + private IHttpActionResult ErrorJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.InternalServerError + }; + + private IHttpActionResult ForbiddenJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.Forbidden + }; + + private IHttpActionResult NotFoundJsonResult(string message) => + new JsonActionResult(new ErrorResponse(message), Request) + { + StatusCode = HttpStatusCode.NotFound + }; + + private IHttpActionResult OkJsonResult(object result) => + new JsonActionResult(result, Request); + + private IHttpActionResult FileResult(byte[] data, string fileName) => + new FileActionResult(data, fileName, "application/octet-stream", Request); + + private IHttpActionResult FileResult(byte[] data, string fileName, string contentType) => + new FileActionResult(data, fileName, contentType, Request); + + private IHttpActionResult ResourceFileResult(byte[] data, string contentType) => + new ResourceActionResult(data, contentType, Request); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/AsyncDuplicateLock.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/AsyncDuplicateLock.cs new file mode 100644 index 000000000..4ad88214b --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/AsyncDuplicateLock.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + public sealed class AsyncDuplicateLock : IAsyncLock + { + private sealed class RefCounted + { + public RefCounted(T value) + { + RefCount = 1; + Value = value; + } + + public int RefCount { get; set; } + public T Value { get; private set; } + } + + private static readonly Dictionary> SemaphoreSlims + = new Dictionary>(); + + private SemaphoreSlim GetOrCreate(object key) + { + RefCounted item; + lock (SemaphoreSlims) + { + if (SemaphoreSlims.TryGetValue(key, out item)) + { + ++item.RefCount; + } + else + { + item = new RefCounted(new SemaphoreSlim(1, 1)); + SemaphoreSlims[key] = item; + } + } + return item.Value; + } + + public IDisposable Lock(object key) + { + GetOrCreate(key).Wait(); + return new Releaser { Key = key }; + } + + public async Task LockAsync(object key) + { + await GetOrCreate(key).WaitAsync().ConfigureAwait(false); + return new Releaser { Key = key }; + } + + private sealed class Releaser : IDisposable + { + public object Key { get; set; } + + public void Dispose() + { + RefCounted item; + lock (SemaphoreSlims) + { + item = SemaphoreSlims[Key]; + --item.RefCount; + if (item.RefCount == 0) + SemaphoreSlims.Remove(Key); + } + item.Value.Release(); + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/CacheKeys.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/CacheKeys.cs new file mode 100644 index 000000000..7d2d2da0a --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/CacheKeys.cs @@ -0,0 +1,14 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + public static class CacheKeys + { + public const string FILE_INFO_CACHE_KEY = "info.json"; + public const string PDF_FILE_CACHE_KEY = "file.pdf"; + + public static string GetHtmlPageResourceCacheKey(int pageNumber, string resourceName) + => $"p{pageNumber}_{resourceName}"; + + public static string GetPageCacheKey(int pageNumber, string extension) => + $"p{pageNumber}{extension}"; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/CachedPage.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/CachedPage.cs new file mode 100644 index 000000000..914bd5982 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/CachedPage.cs @@ -0,0 +1,21 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + internal class CachedPage + { + /// + /// The page number. + /// + public int PageNumber { get; } + + /// + /// The data. Can be null. + /// + public byte[] Data { get; } + + public CachedPage(int pageNumber, byte[] data) + { + PageNumber = pageNumber; + Data = data; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/CachingViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/CachingViewer.cs new file mode 100644 index 000000000..ce8620e70 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/CachingViewer.cs @@ -0,0 +1,204 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.Extensions; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + public class CachingViewer : IViewer + { + private readonly IViewer _viewer; + private readonly IFileCache _fileCache; + private readonly IAsyncLock _asyncLock; + + public string PageExtension => + _viewer.PageExtension; + + public Page CreatePage(int pageNumber, byte[] data) => + _viewer.CreatePage(pageNumber, data); + + public CachingViewer(IViewer viewer, IFileCache fileCache, IAsyncLock asyncLock) + { + _viewer = viewer; + _fileCache = fileCache; + _asyncLock = asyncLock; + } + + public async Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers) + { + var pagesOrNulls = GetPagesOrNullsFromCache(fileCredentials.FilePath, pageNumbers); + var missingPageNumbers = GetMissingPageNumbers(pagesOrNulls); + + if (missingPageNumbers.Length == 0) + return ToPages(pagesOrNulls); + + var createdPages = await CreatePages(fileCredentials, missingPageNumbers); + + var pages = Combine(pagesOrNulls, createdPages); + + return pages; + } + + public async Task GetPageAsync(FileCredentials fileCredentials, int pageNumber) + { + var cacheKey = CacheKeys.GetPageCacheKey(pageNumber, PageExtension); + var bytes = await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + var newPage = await _viewer.GetPageAsync(fileCredentials, pageNumber); + + await SaveResourcesAsync(fileCredentials.FilePath, newPage.PageNumber, newPage.Resources); + + return newPage.Data; + }); + } + }); + + var page = CreatePage(pageNumber, bytes); + return page; + } + + public Task GetDocumentInfoAsync(FileCredentials fileCredentials) + { + var cacheKey = CacheKeys.FILE_INFO_CACHE_KEY; + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetDocumentInfoAsync(fileCredentials)); + } + }); + } + + public Task GetPdfAsync(FileCredentials fileCredentials) + { + var cacheKey = CacheKeys.PDF_FILE_CACHE_KEY; + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetPdfAsync(fileCredentials)); + } + }); + } + + public Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, + string resourceName) + { + var cacheKey = CacheKeys.GetHtmlPageResourceCacheKey(pageNumber, resourceName); + return _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, + async () => + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + return await _fileCache.GetValueAsync(cacheKey, fileCredentials.FilePath, () => + _viewer.GetPageResourceAsync(fileCredentials, pageNumber, resourceName)); + } + }); + } + + private async Task SaveResourcesAsync(string filePath, int pageNumber, IEnumerable pageResources) + { + var tasks = pageResources.Select(resource => + { + var resourceCacheKey = + CacheKeys.GetHtmlPageResourceCacheKey(pageNumber, resource.ResourceName); + + return _fileCache.SetAsync(resourceCacheKey, filePath, resource.Data); + }); + + await Task.WhenAll(tasks); + } + + private async Task CreatePages(FileCredentials fileCredentials, int[] pageNumbers) + { + using (await _asyncLock.LockAsync(fileCredentials.FilePath)) + { + var pagesOrNulls = GetPagesOrNullsFromCache(fileCredentials.FilePath, pageNumbers); + var missingPageNumbers = GetMissingPageNumbers(pagesOrNulls); + + if (missingPageNumbers.Length == 0) + return ToPages(pagesOrNulls); + + var createdPages = await _viewer.GetPagesAsync(fileCredentials, missingPageNumbers); + + await SaveToCache(fileCredentials.FilePath, createdPages); + + var pages = Combine(pagesOrNulls, createdPages); + + return pages; + } + } + + private Pages Combine(List dst, Pages missing) + { + var pages = dst + .Select(pageOrNull => + { + if (pageOrNull.Data == null) + { + var page = missing + .Where(p => p.PageNumber == pageOrNull.PageNumber) + .Select(p => p) + .FirstOrDefault(); + + return page; + } + + return CreatePage(pageOrNull.PageNumber, pageOrNull.Data); + }).ToList(); + + return new Pages(pages); + } + + private Task SaveToCache(string filePath, Pages createdPages) + { + var tasks = createdPages + .SelectMany(page => + { + var cacheKey = CacheKeys.GetPageCacheKey(page.PageNumber, _viewer.PageExtension); + + var savePageTask = _fileCache.SetAsync(cacheKey, filePath, page.Data); + var saveResourcesTask = SaveResourcesAsync(filePath, page.PageNumber, page.Resources); + + return new[] {savePageTask, saveResourcesTask}; + }); + + return Task.WhenAll(tasks); + } + + private Pages ToPages(List pagesOrNulls) + { + var pages = pagesOrNulls + .Select(p => CreatePage(p.PageNumber, p.Data)) + .ToList(); + + var result = new Pages(pages); + return result; + } + + private int[] GetMissingPageNumbers(List pagesOrNulls) + { + return pagesOrNulls + .Where(p => p.Data == null) + .Select(p => p.PageNumber) + .ToArray(); + } + + private List GetPagesOrNullsFromCache(string filePath, int[] pageNumbers) + { + return pageNumbers + .Select(pageNumber => + (pageNumber, cacheKey: CacheKeys.GetPageCacheKey(pageNumber, PageExtension))) + .Select(page => + new CachedPage(page.pageNumber, _fileCache.TryGetValue(page.cacheKey, filePath))) + .ToList(); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/LocalFileCache.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/LocalFileCache.cs new file mode 100644 index 000000000..6429c681f --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/LocalFileCache.cs @@ -0,0 +1,277 @@ +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + public class LocalFileCache : IFileCache + { + /// + /// The Relative or absolute path to the cache folder. + /// + private string CachePath { get; } + + private readonly TimeSpan _waitTimeout = TimeSpan.FromMilliseconds(100); + + /// + /// Creates new instance of class. + /// + /// Relative or absolute path where document cache will be stored. + /// Thrown when is null. + public LocalFileCache(string cachePath) + { + if (cachePath == null) + throw new ArgumentNullException(nameof(cachePath)); + + CachePath = cachePath; + } + + /// + /// Deserializes data associated with this key if present. + /// + /// A key identifying the requested entry. + /// The relative or absolute filepath. + /// True if the key was found. + public TEntry TryGetValue(string cacheKey, string filePath) + { + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (File.Exists(cacheFilePath)) + { + if (typeof(TEntry) == typeof(byte[])) + return (TEntry)ReadBytes(cacheFilePath); + + if (typeof(TEntry) == typeof(Stream)) + return (TEntry)ReadStream(cacheFilePath); + + return Deserialize(cacheFilePath); + } + + return default(TEntry); + } + + /// + /// Deserializes data associated with this key if present. + /// + /// A key identifying the requested entry. + /// The relative or absolute filepath. + /// True if the key was found. + public async Task TryGetValueAsync(string cacheKey, string filePath) + { + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (File.Exists(cacheFilePath)) + { + if (typeof(TEntry) == typeof(byte[])) + return (TEntry)ReadBytes(cacheFilePath); + + if (typeof(TEntry) == typeof(Stream)) + return (TEntry)ReadStream(cacheFilePath); + + return await DeserializeAsync(cacheFilePath); + } + + return default(TEntry); + } + + /// + /// Serializes data to the local disk. + /// + /// An unique identifier for the cache entry. + /// The relative or absolute filepath. + /// The object to serialize. + public void Set(string cacheKey, string filePath, TEntry value) + { + if (value == null) + return; + + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (value is byte[] data) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + dst.Write(data, 0, data.Length); + } + } + else if (value is Stream src) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + if (src.CanSeek) + src.Position = 0; + src.CopyTo(dst); + } + } + else + { + var json = JsonConvert.SerializeObject(value, Formatting.Indented); + var bytes = Encoding.UTF8.GetBytes(json); + + using (FileStream stream = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + stream.Write(bytes, 0, bytes.Length); + } + } + } + + /// + /// Serializes data to the local disk. + /// + /// An unique identifier for the cache entry. + /// The relative or absolute filepath. + /// The object to serialize. + public async Task SetAsync(string cacheKey, string filePath, TEntry value) + { + if (value == null) + return; + + string cacheFilePath = GetCacheFilePath(cacheKey, filePath); + + if (value is byte[] data) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + await dst.WriteAsync(data, 0, data.Length); + } + } + else if (value is Stream src) + { + using (FileStream dst = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + if (src.CanSeek) + src.Position = 0; + + await src.CopyToAsync(dst); + } + } + else + { + var json = JsonConvert.SerializeObject(value, Formatting.Indented); + var bytes = Encoding.UTF8.GetBytes(json); + + using (FileStream stream = GetStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + await stream.WriteAsync(bytes, 0, bytes.Length); + } + } + } + + private object ReadStream(string cacheFilePath) + => GetStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); + + private object ReadBytes(string cacheFilePath) + => GetBytes(cacheFilePath); + + private TEntry Deserialize(string cachePath) + { + object data; + try + { + var bytes = GetBytes(cachePath); + var json = Encoding.UTF8.GetString(bytes); + + data = JsonConvert.DeserializeObject(json); + } + catch (SerializationException) + { + data = default(TEntry); + } + + return (TEntry)data; + } + + private async Task DeserializeAsync(string cachePath) + { + object data; + try + { + using (var stream = GetStream(cachePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + var memory = new MemoryStream(); + await stream.CopyToAsync(memory); + var json = Encoding.UTF8.GetString(memory.ToArray()); + + data = JsonConvert.DeserializeObject(json); + } + } + catch (SerializationException) + { + data = default(TEntry); + } + + return (TEntry)data; + } + + private string GetCacheFilePath(string cacheKey, string filePath) + { + string cacheSubFolder = string.Join("_", filePath.Split(Path.GetInvalidPathChars())) + .Replace(".", "_"); + string cacheDirPath = Path.Combine(CachePath, cacheSubFolder); + string cacheFilePath = Path.Combine(cacheDirPath, cacheKey); + + if (!Directory.Exists(cacheDirPath)) + Directory.CreateDirectory(cacheDirPath); + + return cacheFilePath; + } + + private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) + { + FileStream stream = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (stream == null) + { + try + { + stream = File.Open(path, mode, access, share); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return stream; + } + + private byte[] GetBytes(string path) + { + byte[] bytes = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (bytes == null) + { + try + { + bytes = File.ReadAllBytes(path); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return bytes; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Caching/NoopFileCache.cs b/Demos/ASP.NET Web Forms/src/Core/Caching/NoopFileCache.cs new file mode 100644 index 000000000..afba6d538 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Caching/NoopFileCache.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Caching +{ + internal class NoopFileCache : IFileCache + { + public TEntry TryGetValue(string cacheKey, string filePath) => + default(TEntry); + + public Task TryGetValueAsync(string cacheKey, string filePath) => + Task.FromResult(default(TEntry)); + + public void Set(string cacheKey, string filePath, TEntry entry) { } + + public Task SetAsync(string cacheKey, string filePath, TEntry entry) => + Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Configuration/Language.cs b/Demos/ASP.NET Web Forms/src/Core/Configuration/Language.cs new file mode 100644 index 000000000..92c0d9db4 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Configuration/Language.cs @@ -0,0 +1,43 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Configuration +{ + public class Language + { + public static readonly Language Arabic = new Language("ar"); + public static readonly Language Catalan = new Language("ca"); + public static readonly Language Czech = new Language("cs"); + public static readonly Language Danish = new Language("da"); + public static readonly Language German = new Language("de"); + public static readonly Language Greek = new Language("el"); + public static readonly Language English = new Language("en"); + public static readonly Language Spanish = new Language("es"); + public static readonly Language Filipino = new Language("fil"); + public static readonly Language French = new Language("fr"); + public static readonly Language Hebrew = new Language("he"); + public static readonly Language Hindi = new Language("hi"); + public static readonly Language Indonesian = new Language("id"); + public static readonly Language Italian = new Language("it"); + public static readonly Language Japanese = new Language("ja"); + public static readonly Language Kazakh = new Language("kk"); + public static readonly Language Korean = new Language("ko"); + public static readonly Language Malay = new Language("ms"); + public static readonly Language Dutch = new Language("nl"); + public static readonly Language Polish = new Language("pl"); + public static readonly Language Portuguese = new Language("pt"); + public static readonly Language Romanian = new Language("ro"); + public static readonly Language Russian = new Language("ru"); + public static readonly Language Swedish = new Language("sv"); + public static readonly Language Vietnamese = new Language("vi"); + public static readonly Language Thai = new Language("th"); + public static readonly Language Turkish = new Language("tr"); + public static readonly Language Ukrainian = new Language("uk"); + public static readonly Language ChineseSimplified = new Language("zh-hans"); + public static readonly Language ChineseTraditional = new Language("zh-hant"); + + public string Code { get; } + + public Language(string code) + { + Code = code; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Configuration/UIConfig.cs b/Demos/ASP.NET Web Forms/src/Core/Configuration/UIConfig.cs new file mode 100644 index 000000000..72afdebe8 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Configuration/UIConfig.cs @@ -0,0 +1,238 @@ +using System.Linq; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Configuration +{ + public class UIConfig + { + public static readonly UIConfig Instance = new UIConfig(); + + internal string DefaultDocument { get; private set; } = string.Empty; + internal int PreloadPageCount { get; private set; } = 3; + internal bool PageSelector { get; private set; } = true; + internal bool Thumbnails { get; private set; } = true; + internal bool Zoom { get; private set; } = true; + internal bool Search { get; private set; } = true; + internal bool EnableRightClick { get; private set; } = true; + internal bool Download { get; private set; } = true; + internal bool Upload { get; private set; } = true; + internal bool Rewrite { get; private set; } = false; + internal bool Print { get; private set; } = true; + internal bool Browse { get; private set; } = true; + internal bool PrintAllowed { get; private set; } = true; + internal bool HtmlMode { get; private set; } = true; + internal bool ShowLanguageMenu { get; private set; } = true; + internal string DefaultLanguage { get; private set; } = "en"; + internal string[] SupportedLanguages { get; private set; } = new string[] + { + "ar", // ar - العربية + "ca", // ca-ES - Català + "cs", // cs-CZ - Čeština + "da", // da-DK - Dansk + "de", // de-DE - Deutsch + "el", // el-GR - Ελληνικά + "en", // en-US - English + "es", // es-ES - Español + "fil", // fil-PH - Filipino + "fr", // fr-FR - Français + "he", // he-IL - עברית + "hi", // hi-IN - हिन्दी + "id", // id-ID - Indonesia + "it", // it-IT - Italiano + "ja", // ja-JP - 日本語 + "kk", // kk-KZ - Қазақ Тілі + "ko", // ko-KR - 한국어 + "ms", // ms-MY - Melayu + "nl", // nl-NL - Nederlands + "pl", // pl-PL - Polski + "pt", // pt-PT - Português + "ro", // ro-RO - Română + "ru", // ru-RU - Русский + "sv", // sv-SE - Svenska + "vi", // vi-VN - Tiếng Việt + "th", // th-TH - ไทย + "tr", // tr-TR - Türkçe + "uk", // uk-UA - Українська + "zh-hans", // zh-Hans - 中文(简体) + "zh-hant", // zh-Hant" - 中文(繁體) + }; + + internal bool Rotate { get; private set; } = false; + internal bool SaveRotateState { get; private set; } = false; + internal ViewerType ViewerType { get; private set; } + + public UIConfig SetViewerType(ViewerType viewerType) + { + ViewerType = viewerType; + HtmlMode = viewerType == ViewerType.HtmlWithExternalResources || + viewerType == ViewerType.HtmlWithEmbeddedResources; + return this; + } + + public UIConfig SetPreloadPageCount(int countPages) + { + PreloadPageCount = countPages; + return this; + } + + public UIConfig SetDefaultDocument(string filePath) + { + DefaultDocument = filePath; + return this; + } + + public UIConfig HidePageSelectorControl() + { + PageSelector = false; + return this; + } + + public UIConfig HideThumbnailsControl() + { + Thumbnails = false; + return this; + } + + public UIConfig DisableFileDownload() + { + Download = false; + return this; + } + + public UIConfig DisableFileUpload() + { + Upload = false; + return this; + } + + public UIConfig RewriteFilesOnUpload() + { + Rewrite = true; + return this; + } + + public UIConfig DisablePrint() + { + Print = false; + PrintAllowed = false; + return this; + } + + public UIConfig DisableFileBrowsing() + { + Browse = false; + return this; + } + + public UIConfig HideZoomButton() + { + Zoom = false; + return this; + } + + public UIConfig HideSearchControl() + { + Search = false; + return this; + } + + public UIConfig HidePageRotationControl() + { + Rotate = false; + return this; + } + + public UIConfig DisableRightClick() + { + EnableRightClick = false; + return this; + } + + public UIConfig HideLanguageMenu() + { + ShowLanguageMenu = false; + return this; + } + + /// + /// Sets default language out of supported: + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// + /// + /// Default language e.g. . + /// This UIConfig instance. + public UIConfig SetDefaultLanguage(Language language) + { + DefaultLanguage = language.Code; + return this; + } + + /// + /// Set supported UI languages. The following languages are supported: + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// , + /// + /// + /// Supported languages. + /// This UIConfig instance. + public UIConfig SetSupportedLanguages(params Language[] languages) + { + SupportedLanguages = languages.Select(l => l.Code).ToArray(); + return this; + } + } +} diff --git a/Demos/ASP.NET Web Forms/src/Core/Configuration/ViewerConfig.cs b/Demos/ASP.NET Web Forms/src/Core/Configuration/ViewerConfig.cs new file mode 100644 index 000000000..98946d4f4 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Configuration/ViewerConfig.cs @@ -0,0 +1,48 @@ +using System; +using GroupDocs.Viewer.Options; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Configuration +{ + public class ViewerConfig + { + public static ViewerConfig Instance = new ViewerConfig(); + + internal string LicensePath = string.Empty; + internal readonly HtmlViewOptions HtmlViewOptions = HtmlViewOptions.ForEmbeddedResources(); + internal readonly PngViewOptions PngViewOptions = new PngViewOptions(); + internal readonly JpgViewOptions JpgViewOptions = new JpgViewOptions(); + internal readonly PdfViewOptions PdfViewOptions = new PdfViewOptions(); + + private ViewerConfig() { } + + public ViewerConfig SetLicensePath(string licensePath) + { + LicensePath = licensePath; + return this; + } + + public ViewerConfig ConfigureHtmlViewOptions(Action setupOptions) + { + setupOptions?.Invoke(HtmlViewOptions); + return this; + } + + public ViewerConfig ConfigurePngViewOptions(Action setupOptions) + { + setupOptions?.Invoke(PngViewOptions); + return this; + } + + public ViewerConfig ConfigureJpgViewOptions(Action setupOptions) + { + setupOptions?.Invoke(JpgViewOptions); + return this; + } + + public ViewerConfig ConfigurePdfViewOptions(Action setupOptions) + { + setupOptions?.Invoke(PdfViewOptions); + return this; + } + } +} diff --git a/Demos/ASP.NET Web Forms/src/Core/Constants.cs b/Demos/ASP.NET Web Forms/src/Core/Constants.cs new file mode 100644 index 000000000..5b5c38fc9 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Constants.cs @@ -0,0 +1,16 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public class Constants + { + public const string API_PATH = "viewer-api"; + public const string LOAD_CONFIG_ACTION_NAME = "LoadConfig"; + public const string LOAD_FILE_TREE_ACTION_NAME = "LoadFileTree"; + public const string DOWNLOAD_DOCUMENT_ACTION_NAME = "DownloadDocument"; + public const string LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME = "LoadDocumentPageResource"; + public const string UPLOAD_DOCUMENT_ACTION_NAME = "UploadDocument"; + public const string LOAD_DOCUMENT_DESCRIPTION_ACTION_NAME = "LoadDocumentDescription"; + public const string LOAD_DOCUMENT_PAGES_ACTION_NAME = "LoadDocumentPages"; + public const string LOAD_DOCUMENT_PAGE_ACTION_NAME = "LoadDocumentPage"; + public const string PRINT_PDF_ACTION_NAME = "PrintPdf"; + } +} diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/DocumentInfo.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/DocumentInfo.cs new file mode 100644 index 000000000..2696c6b80 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/DocumentInfo.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class DocumentInfo + { + public string FileType { get; set; } + + public bool PrintAllowed { get; set; } + + public IEnumerable Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/FileCredentials.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/FileCredentials.cs new file mode 100644 index 000000000..3e061c268 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/FileCredentials.cs @@ -0,0 +1,16 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class FileCredentials + { + public string FilePath { get; } + public string FileType { get; } + public string Password { get; } + + public FileCredentials(string filePath, string fileType, string password) + { + FilePath = filePath; + FileType = fileType; + Password = password; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/FileSystemEntry.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/FileSystemEntry.cs new file mode 100644 index 000000000..0c12f9540 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/FileSystemEntry.cs @@ -0,0 +1,33 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class FileSystemEntry + { + public string FileName { get; private set; } + + public string FilePath { get; private set; } + + public bool IsDirectory { get; private set; } + + public long Size { get; private set; } + + private FileSystemEntry () { } + + public static FileSystemEntry Directory(string name, string path, long size) => + new FileSystemEntry + { + FileName = name, + FilePath = path, + IsDirectory = true, + Size = size + }; + + public static FileSystemEntry File(string name, string path, long size) => + new FileSystemEntry + { + FileName = name, + FilePath = path, + IsDirectory = false, + Size = size + }; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/HtmlPage.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/HtmlPage.cs new file mode 100644 index 000000000..b9ea961b0 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/HtmlPage.cs @@ -0,0 +1,22 @@ +using System.Text; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class HtmlPage : Page + { + public static string Extension => ".html"; + + public override string GetContent() => + Encoding.UTF8.GetString(Data); + + public override void SetContent(string contents) + { + Data = Encoding.UTF8.GetBytes(contents); + } + + public HtmlPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/JpgPage.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/JpgPage.cs new file mode 100644 index 000000000..cd9ab047f --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/JpgPage.cs @@ -0,0 +1,30 @@ +using System; +using System.Text; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class JpgPage : Page + { + const string DATA_IMAGE = "data:image/jpeg;base64,"; + + public static string Extension => ".jpeg"; + + public override string GetContent() + { + return DATA_IMAGE + Convert.ToBase64String(Data); + } + + public override void SetContent(string content) + { + this.Data = content.StartsWith(DATA_IMAGE) + ? Encoding.UTF8.GetBytes(content) + : Encoding.UTF8.GetBytes(content.Substring(DATA_IMAGE.Length - 1)); + } + + public JpgPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/Page.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/Page.cs new file mode 100644 index 000000000..94453a619 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/Page.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public abstract class Page + { + private readonly List _resources = new List(); + + protected Page(int pageNumber, byte[] data) + { + PageNumber = pageNumber; + Data = data; + } + + protected Page(int pageNumber, byte[] data, IEnumerable resources) + { + PageNumber = pageNumber; + Data = data; + _resources.AddRange(resources); + } + + public IEnumerable Resources => _resources; + + public int PageNumber { get; } + + public byte[] Data { get; protected set; } + + public abstract string GetContent(); + + public abstract void SetContent(string content); + + public void AddResource(PageResource pageResource) + { + _resources.Add(pageResource); + } + + public PageResource GetResource(string resourceName) => + _resources.First(resource => + resource.ResourceName.Equals(resourceName, StringComparison.InvariantCulture)); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/PageInfo.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/PageInfo.cs new file mode 100644 index 000000000..a119b14a1 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/PageInfo.cs @@ -0,0 +1,10 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class PageInfo + { + public int Width { get; set; } + public int Height { get; set; } + public int Number { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/PageResource.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/PageResource.cs new file mode 100644 index 000000000..0da699cd3 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/PageResource.cs @@ -0,0 +1,15 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class PageResource + { + public PageResource(string resourceName, byte[] data) + { + ResourceName = resourceName; + Data = data; + } + + public string ResourceName { get; } + + public byte[] Data { get; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/Pages.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/Pages.cs new file mode 100644 index 000000000..8cd687720 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/Pages.cs @@ -0,0 +1,35 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class Pages : IEnumerable + { + readonly List _pages; + + public Pages() + { + _pages = new List(); + } + + public Pages(IEnumerable pages) + { + _pages = pages.ToList(); + } + + public void Add(Page page) => _pages.Add(page); + + public Page this[int index] + { + get => _pages[index]; + set => _pages.Insert(index, value); + } + + public IEnumerator GetEnumerator() + => _pages.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Entities/PngPage.cs b/Demos/ASP.NET Web Forms/src/Core/Entities/PngPage.cs new file mode 100644 index 000000000..2bf1ea6b0 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Entities/PngPage.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Entities +{ + public class PngPage : Page + { + const string DATA_IMAGE = "data:image/png;base64,"; + + public static string Extension => ".png"; + + public override string GetContent() => + DATA_IMAGE + Convert.ToBase64String(Data); + + public override void SetContent(string content) + { + this.Data = content.StartsWith(DATA_IMAGE) + ? Encoding.UTF8.GetBytes(content) + : Encoding.UTF8.GetBytes(content.Substring(DATA_IMAGE.Length - 1)); + } + + public PngPage(int pageNumber, byte[] data) + : base(pageNumber, data) + { + + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Extensions/FileCacheExtensions.cs b/Demos/ASP.NET Web Forms/src/Core/Extensions/FileCacheExtensions.cs new file mode 100644 index 000000000..402db253f --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Extensions/FileCacheExtensions.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Extensions +{ + public static class FileCacheExtensions + { + /// + /// Gets the entry associated with this key if present or acquires and sets the entry if not present. + /// + /// Type of entry. + /// The cache. + /// A key identifying the requested entry. + /// The source file relative file path. + /// The method which returns entry. + /// The entry associated with this key if present or acquires and sets the entry if not present. + public static async Task GetValueAsync(this IFileCache cache, string cacheKey, string filePath, Func> acquire) + { + var entry = await cache.TryGetValueAsync(cacheKey, filePath); + if (entry == null) + { + entry = await acquire(); + await cache.SetAsync(cacheKey, filePath, entry); + } + + return entry; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Extensions/MediaTypeExtensions.cs b/Demos/ASP.NET Web Forms/src/Core/Extensions/MediaTypeExtensions.cs new file mode 100644 index 000000000..2ffc09d8f --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Extensions/MediaTypeExtensions.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Extensions +{ + public static class ContentTypeExtensions + { + public static string ContentTypeFromFileName(this string filename) + { + var extension = Path.GetExtension(filename); + + switch (extension) + { + case ".css": return "text/css"; + case ".woff": return "font/woff"; + case ".png": return "image/png"; + case ".jpg": + case ".jpeg": return "image/jpeg"; + case ".svg": return "image/svg+xml"; + default: + return "application/octet-stream"; + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs b/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs new file mode 100644 index 000000000..7e484253f --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/FileExtensionFileTypeResolver.cs @@ -0,0 +1,16 @@ +using System.IO; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution +{ + public class FileExtensionFileTypeResolver : IFileTypeResolver + { + public Task ResolveFileTypeAsync(string filePath) + { + string extension = Path.GetExtension(filePath); + FileType fileType = FileType.FromExtension(extension); + + return Task.FromResult(fileType); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/IFileTypeResolver.cs b/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/IFileTypeResolver.cs new file mode 100644 index 000000000..88b29d35c --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/FileTypeResolution/IFileTypeResolver.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution +{ + public interface IFileTypeResolver + { + Task ResolveFileTypeAsync(string filePath); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/IAsyncLock.cs b/Demos/ASP.NET Web Forms/src/Core/IAsyncLock.cs new file mode 100644 index 000000000..c9086efef --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/IAsyncLock.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public interface IAsyncLock + { + Task LockAsync(object key); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/IFileCache.cs b/Demos/ASP.NET Web Forms/src/Core/IFileCache.cs new file mode 100644 index 000000000..b9f52d6b1 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/IFileCache.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; + +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public interface IFileCache + { + TEntry TryGetValue(string cacheKey, string filePath); + + Task TryGetValueAsync(string cacheKey, string filePath); + + void Set(string cacheKey, string filePath, TEntry entry); + + Task SetAsync(string cacheKey, string filePath, TEntry entry); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/IFileStorage.cs b/Demos/ASP.NET Web Forms/src/Core/IFileStorage.cs new file mode 100644 index 000000000..2055883df --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/IFileStorage.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; + +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public interface IFileStorage + { + Task> ListDirsAndFilesAsync(string dirPath); + + Task ReadFileAsync(string filePath); + + Task WriteFileAsync(string fileName, byte[] bytes, bool rewrite); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/IPageFormatter.cs b/Demos/ASP.NET Web Forms/src/Core/IPageFormatter.cs new file mode 100644 index 000000000..8e9c1d31e --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/IPageFormatter.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; + +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public interface IPageFormatter + { + Task FormatAsync(FileCredentials fileCredentials, Page page); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/IViewer.cs b/Demos/ASP.NET Web Forms/src/Core/IViewer.cs new file mode 100644 index 000000000..9e473105e --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/IViewer.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; + +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public interface IViewer + { + string PageExtension { get; } + Page CreatePage(int pageNumber, byte[] data); + Task GetDocumentInfoAsync(FileCredentials fileCredentials); + Task GetPageAsync(FileCredentials fileCredentials, int pageNumber); + Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers); + Task GetPdfAsync(FileCredentials fileCredentials); + Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, string resourceName); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Licensing/IViewerLicenser.cs b/Demos/ASP.NET Web Forms/src/Core/Licensing/IViewerLicenser.cs new file mode 100644 index 000000000..8d88f1ba6 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Licensing/IViewerLicenser.cs @@ -0,0 +1,7 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core.Licensing +{ + internal interface IViewerLicenser + { + void SetLicense(); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Licensing/LicenseFileViewerLicenser.cs b/Demos/ASP.NET Web Forms/src/Core/Licensing/LicenseFileViewerLicenser.cs new file mode 100644 index 000000000..c7969ec08 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Licensing/LicenseFileViewerLicenser.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Licensing +{ + internal class LicenseFileViewerLicenser : IViewerLicenser + { + private readonly ViewerConfig _config; + private readonly object _lock = new object(); + private bool _licenseSet; + + public LicenseFileViewerLicenser(ViewerConfig config) + { + _config = config; + } + + public void SetLicense() + { + if (_licenseSet) + return; + + if (File.Exists(_config.LicensePath)) + SetLicense(_config.LicensePath); + + string licensePath = Environment.GetEnvironmentVariable("GROUPDOCS_LIC_PATH"); + if (!string.IsNullOrEmpty(licensePath)) + SetLicense(licensePath); + } + + private void SetLicense(string licensePath) + { + lock (_lock) + { + if (!_licenseSet) + { + License license = new License(); + license.SetLicense(licensePath); + + _licenseSet = true; + } + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/PageFormatting/NoopPageFormatter.cs b/Demos/ASP.NET Web Forms/src/Core/PageFormatting/NoopPageFormatter.cs new file mode 100644 index 000000000..70a3893a2 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/PageFormatting/NoopPageFormatter.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.PageFormatting +{ + public class NoopPageFormatter : IPageFormatter + { + public Task FormatAsync(FileCredentials fileCredentials, Page page) => + Task.FromResult(page); + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Storage/LocalFileStorage.cs b/Demos/ASP.NET Web Forms/src/Core/Storage/LocalFileStorage.cs new file mode 100644 index 000000000..ebf186820 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Storage/LocalFileStorage.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.Utils; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Storage +{ + public class LocalFileStorage : IFileStorage + { + private readonly string _storagePath; + private readonly TimeSpan _waitTimeout = TimeSpan.FromMilliseconds(100); + + public LocalFileStorage(string storagePath) + { + _storagePath = storagePath; + } + + private IEnumerable ListFiles(string folderPath) + { + var folderFullPath = string.IsNullOrEmpty(folderPath) + ? _storagePath + : Path.Combine(_storagePath, folderPath); + + var dirs = Directory.GetDirectories(folderFullPath) + .Select(file => new FileInfo(file)) + .Where(fileInfo => !fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + .OrderBy(fileInfo => fileInfo.Name) + .ThenByDescending(fileInfo => fileInfo.CreationTime) + .Select(directory => + FileSystemEntry.Directory(directory.Name, PathUtils.GetRelativePath(_storagePath, directory.FullName), 0L)); + + var files = Directory + .GetFiles(folderFullPath) + .Select(file => new FileInfo(file)) + .Where(fileInfo => !fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + .OrderBy(fileInfo => fileInfo.Name) + .ThenByDescending(fileInfo => fileInfo.CreationTime) + .Select(file => + FileSystemEntry.File(file.Name, PathUtils.GetRelativePath(_storagePath, file.FullName), file.Length)); + + var dirsAndFiles = dirs.Concat(files); + return dirsAndFiles; + } + + public Task> ListDirsAndFilesAsync(string dirPath) => + Task.FromResult(ListFiles(dirPath)); + + public async Task ReadFileAsync(string filePath) + { + var fullPath = Path.Combine(_storagePath, filePath); + using (FileStream fs = GetStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + var memoryStream = new MemoryStream(); + await fs.CopyToAsync(memoryStream); + + return memoryStream.ToArray(); + } + } + + public async Task WriteFileAsync(string fileName, byte[] bytes, bool rewrite) + { + var newFileName = rewrite ? fileName : GetFreeFileName(fileName); + var fullPath = Path.Combine(_storagePath, newFileName); + var fileMode = rewrite ? FileMode.Create : FileMode.CreateNew; + + using (FileStream fs = GetStream(fullPath, fileMode, FileAccess.Write, FileShare.None)) + { + await fs.WriteAsync(bytes, 0, bytes.Length); + } + + return newFileName; + } + + private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) + { + FileStream stream = null; + TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); + TimeSpan totalTime = new TimeSpan(); + + while (stream == null) + { + try + { + stream = File.Open(path, mode, access, share); + } + catch (IOException) + { + Thread.Sleep(interval); + totalTime += interval; + + if (_waitTimeout.Ticks != 0 && totalTime > _waitTimeout) + { + throw; + } + } + } + + return stream; + } + + private string GetFreeFileName(string fileName) + { + var fullPath = Path.Combine(_storagePath, fileName); + + if (!File.Exists(fullPath)) + return fileName; + + List dirFiles = Directory.GetFiles(_storagePath) + .Select(filePath => Path.GetFileName(filePath)) + .ToList(); + + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); + var number = 1; + string fileNameCandidate; + do + { + string newFileName = $"{fileNameWithoutExtension} ({number})"; + fileNameCandidate = fileName.Replace(fileNameWithoutExtension, newFileName); + number++; + } while (dirFiles.Contains(fileNameCandidate)); + + return fileNameCandidate; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Utils/PathUtils.cs b/Demos/ASP.NET Web Forms/src/Core/Utils/PathUtils.cs new file mode 100644 index 000000000..f2a1b2341 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Utils/PathUtils.cs @@ -0,0 +1,54 @@ +using System; +using System.IO; +using System.Linq; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Utils +{ + public static class PathUtils + { + public static string GetRelativePath(string relativeTo, string path) + { + if (string.IsNullOrEmpty(relativeTo)) + throw new ArgumentNullException(nameof(relativeTo)); + + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException("path"); + + Uri fromUri = new Uri(AppendDirectorySeparatorChar(relativeTo)); + Uri toUri = new Uri(AppendDirectorySeparatorChar(path)); + + if (fromUri.Scheme != toUri.Scheme) + return path; + + Uri relativeUri = fromUri.MakeRelativeUri(toUri); + string relativePath = Uri.UnescapeDataString(relativeUri.ToString()); + + if (string.Equals(toUri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase)) + relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + + return relativePath; + } + + private static string AppendDirectorySeparatorChar(string path) + { + // Append a slash only if the path is a directory and does not have a slash. + if (!Path.HasExtension(path) && + !path.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + return path + Path.DirectorySeparatorChar; + } + + return path; + } + + public static string RemoveInvalidFileNameChars(string path) + { + Path.GetInvalidFileNameChars().ToList().ForEach(ch => + { + path = path.Replace(ch.ToString(), string.Empty); + }); + + return path; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/ViewerType.cs b/Demos/ASP.NET Web Forms/src/Core/ViewerType.cs new file mode 100644 index 000000000..b7e7ac83e --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/ViewerType.cs @@ -0,0 +1,10 @@ +namespace GroupDocs.Viewer.AspNetWebForms.Core +{ + public enum ViewerType + { + HtmlWithEmbeddedResources, + HtmlWithExternalResources, + Png, + Jpg, + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/BaseViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/BaseViewer.cs new file mode 100644 index 000000000..cafcc5aef --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/BaseViewer.cs @@ -0,0 +1,175 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using GroupDocs.Viewer.Results; +using Page = GroupDocs.Viewer.AspNetWebForms.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers +{ + internal abstract class BaseViewer : IViewer, IDisposable + { + private readonly ViewerConfig _config; + private readonly IViewerLicenser _viewerLicenser; + private readonly IFileStorage _fileStorage; + private readonly IFileTypeResolver _fileTypeResolver; + private readonly IPageFormatter _pageFormatter; + private Viewer _viewer; + + protected BaseViewer(ViewerConfig config, + IViewerLicenser viewerLicenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + { + _config = config; + _viewerLicenser = viewerLicenser; + _fileStorage = fileStorage; + _fileTypeResolver = fileTypeResolver; + _pageFormatter = pageFormatter; + } + + public abstract string PageExtension { get; } + + public abstract Page CreatePage(int pageNumber, byte[] data); + + protected abstract Page RenderPage(Viewer viewer, string filePath, int pageNumber); + + protected abstract ViewInfoOptions CreateViewInfoOptions(); + + public async Task GetDocumentInfoAsync(FileCredentials fileCredentials) + { + var viewer = await InitViewerAsync(fileCredentials); + var viewInfoOptions = CreateViewInfoOptions(); + var viewInfo = viewer.GetViewInfo(viewInfoOptions); + + var documentInfo = ToDocumentInfo(viewInfo); + return documentInfo; + } + + public async Task GetPageAsync(FileCredentials fileCredentials, int pageNumber) + { + var viewer = await InitViewerAsync(fileCredentials); + var page = await RenderPageInternalAsync(viewer, fileCredentials, pageNumber); + + return page; + } + + public async Task GetPagesAsync(FileCredentials fileCredentials, int[] pageNumbers) + { + var viewer = await InitViewerAsync(fileCredentials); + + var pages = new Pages(); + + foreach (var pageNumber in pageNumbers) + { + var page = await RenderPageInternalAsync(viewer, fileCredentials, pageNumber); + pages.Add(page); + } + + return pages; + } + + public async Task GetPdfAsync(FileCredentials fileCredentials) + { + var pdfStream = new MemoryStream(); + var viewOptions = CreatePdfViewOptions(pdfStream); + + var viewer = await InitViewerAsync(fileCredentials); + viewer.View(viewOptions); + + return pdfStream.ToArray(); + } + + public abstract Task GetPageResourceAsync(FileCredentials fileCredentials, int pageNumber, string resourceName); + + private PdfViewOptions CreatePdfViewOptions(MemoryStream pdfStream) + { + var viewOptions = new PdfViewOptions(() => pdfStream, _ => { /* NOTE: nothing to do here */ }); + + viewOptions.CopyViewOptions(_config.PdfViewOptions); + + return viewOptions; + } + + private async Task InitViewerAsync(FileCredentials fileCredentials) + { + if (_viewer == null) + { + _viewerLicenser.SetLicense(); + + var fileStream = await GetFileStreamAsync(fileCredentials.FilePath); + var loadOptions = await CreateLoadOptionsAsync(fileCredentials); + _viewer = new Viewer(fileStream, loadOptions); + } + + return _viewer; + } + + private async Task GetFileStreamAsync(string filePath) + { + byte[] bytes = await _fileStorage.ReadFileAsync(filePath); + MemoryStream memoryStream = new MemoryStream(bytes); + return memoryStream; + } + + private async Task CreateLoadOptionsAsync(FileCredentials fileCredentials) + { + FileType loadFileType = FileType.FromExtension(fileCredentials.FileType); + if(loadFileType == FileType.Unknown) + loadFileType = await _fileTypeResolver.ResolveFileTypeAsync(fileCredentials.FilePath); + + LoadOptions loadOptions = new LoadOptions + { + FileType = FileType.FromExtension(loadFileType.Extension), + Password = fileCredentials.Password, + ResourceLoadingTimeout = TimeSpan.FromSeconds(3) + }; + return loadOptions; + } + + private async Task RenderPageInternalAsync( + Viewer viewer, FileCredentials fileCredentials, int pageNumber) + { + var page = RenderPage(viewer, fileCredentials.FilePath, pageNumber); + page = await _pageFormatter.FormatAsync(fileCredentials, page); + + return page; + } + + private static DocumentInfo ToDocumentInfo(ViewInfo viewInfo) + { + var printAllowed = true; + if (viewInfo is PdfViewInfo info) + printAllowed = info.PrintingAllowed; + + var fileType = viewInfo.FileType.Extension + .Replace(".", string.Empty); + + return new DocumentInfo + { + FileType = fileType, + PrintAllowed = printAllowed, + Pages = viewInfo.Pages.Select(page => new PageInfo + { + Number = page.Number, + Width = page.Width, + Height = page.Height, + Name = page.Name + }) + }; + } + + public void Dispose() + { + _viewer?.Dispose(); + _viewer = null; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs new file mode 100644 index 000000000..b9727f39b --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/Extensions/ViewOptionsExtensions.cs @@ -0,0 +1,90 @@ +using GroupDocs.Viewer.Options; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions +{ + internal static class ViewOptionsExtensions + { + public static void CopyViewOptions(this HtmlViewOptions dst, HtmlViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyHtmlViewOptions(src); + } + + public static void CopyViewOptions(this PdfViewOptions dst, PdfViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyPdfViewOptions(src); + } + + public static void CopyViewOptions(this PngViewOptions dst, PngViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyPngViewOptions(src); + } + + public static void CopyViewOptions(this JpgViewOptions dst, JpgViewOptions src) + { + dst.CopyBaseViewOptions(src); + dst.CopyJpgViewOptions(src); + } + + private static void CopyBaseViewOptions(this BaseViewOptions dst, BaseViewOptions src) + { + dst.RenderComments = src.RenderComments; + dst.RenderNotes = src.RenderNotes; + dst.RenderHiddenPages = src.RenderHiddenPages; + dst.DefaultFontName = src.DefaultFontName; + dst.ArchiveOptions = src.ArchiveOptions; + dst.CadOptions = src.CadOptions; + dst.EmailOptions = src.EmailOptions; + dst.OutlookOptions = src.OutlookOptions; + dst.PdfOptions = src.PdfOptions; + dst.ProjectManagementOptions = src.ProjectManagementOptions; + dst.SpreadsheetOptions = src.SpreadsheetOptions; + dst.WordProcessingOptions = src.WordProcessingOptions; + } + + private static void CopyHtmlViewOptions(this HtmlViewOptions dst, HtmlViewOptions src) + { + dst.RenderResponsive = src.RenderResponsive; + dst.Minify = src.Minify; + dst.RenderToSinglePage = src.RenderToSinglePage; + dst.ImageMaxWidth = src.ImageMaxWidth; + dst.ImageMaxHeight = src.ImageMaxHeight; + dst.ImageWidth = src.ImageWidth; + dst.ImageHeight = src.ImageHeight; + dst.ForPrinting = src.ForPrinting; + dst.ExcludeFonts = src.ExcludeFonts; + dst.FontsToExclude = src.FontsToExclude; + dst.FontsToExclude = src.FontsToExclude; + } + + private static void CopyPdfViewOptions(this PdfViewOptions dst, PdfViewOptions src) + { + dst.JpgQuality = src.JpgQuality; + dst.Security = src.Security; + dst.ImageMaxWidth = src.ImageMaxWidth; + dst.ImageMaxHeight = src.ImageMaxHeight; + dst.ImageWidth = src.ImageWidth; + dst.ImageHeight = src.ImageHeight; + } + + private static void CopyPngViewOptions(this PngViewOptions dst, PngViewOptions src) + { + dst.ExtractText = src.ExtractText; + dst.Width = src.Width; + dst.Height = src.Height; + dst.MaxWidth = src.MaxWidth; + dst.MaxHeight = src.MaxHeight; + } + private static void CopyJpgViewOptions(this JpgViewOptions dst, JpgViewOptions src) + { + dst.Quality = src.Quality; + dst.ExtractText = src.ExtractText; + dst.Width = src.Width; + dst.Height = src.Height; + dst.MaxWidth = src.MaxWidth; + dst.MaxHeight = src.MaxHeight; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs new file mode 100644 index 000000000..df59ee39b --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithEmbeddedResourcesViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetWebForms.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers +{ + internal class HtmlWithEmbeddedResourcesViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public HtmlWithEmbeddedResourcesViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => HtmlPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) + => new HtmlPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(HtmlWithEmbeddedResourcesViewer)} does not support retrieving external HTML resources."); + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromHtmlViewOptions(_config.HtmlViewOptions); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + private HtmlViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = HtmlViewOptions.ForEmbeddedResources(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.HtmlViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs new file mode 100644 index 000000000..ab93775e0 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/HtmlWithExternalResourcesViewer.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions; +using GroupDocs.Viewer.Interfaces; +using GroupDocs.Viewer.Options; +using GroupDocs.Viewer.Results; +using Page = GroupDocs.Viewer.AspNetWebForms.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers +{ + internal class HtmlWithExternalResourcesViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public HtmlWithExternalResourcesViewer( + ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => HtmlPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) + => new HtmlPage(pageNumber, data); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var basePath = Constants.API_PATH; + var actionName = Constants.LOAD_DOCUMENT_PAGE_RESOURCE_ACTION_NAME; + + var streamFactory = new MemoryPageStreamFactory(basePath, actionName, filePath); + var viewOptions = HtmlViewOptions.ForExternalResources(streamFactory, streamFactory); + viewOptions.CopyViewOptions(_config.HtmlViewOptions); + viewer.View(viewOptions, pageNumber); + + var pageContents = streamFactory.GetPageContents(); + var page = CreatePage(pageNumber, pageContents.GetPageData()); + foreach (var resource in pageContents.Resources) + { + var pageResource = new PageResource(resource.Key, resource.Value.ToArray()); + page.AddResource(pageResource); + } + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromHtmlViewOptions(_config.HtmlViewOptions); + + public override async Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) + { + var page = await GetPageAsync(fileCredentials, pageNumber); + var resource = page.GetResource(resourceName); + + return resource.Data; + } + + private class MemoryPageStreamFactory : IPageStreamFactory, IResourceStreamFactory + { + private readonly string _basePath; + private readonly string _actionName; + private readonly string _filePath; + private readonly PageContents _pageContents; + + public MemoryPageStreamFactory(string basePath, string actionName, string filePath) + { + _basePath = basePath; + _actionName = actionName; + _filePath = WebUtility.UrlEncode(filePath); + _pageContents = new PageContents(); + } + + public PageContents GetPageContents() => + _pageContents; + + public Stream CreatePageStream(int pageNumber) => + _pageContents.GetPageStream(); + + public void ReleasePageStream(int pageNumber, Stream pageStream) { } + + public Stream CreateResourceStream(int pageNumber, Resource resource) => + _pageContents.GetResourceStream(resource.FileName); + + public string CreateResourceUrl(int pageNumber, Resource resource) => + $"/{_basePath}/{_actionName}?guid={_filePath}&pageNumber={pageNumber}&resourceName={resource.FileName}"; + + public void ReleaseResourceStream(int pageNumber, Resource resource, Stream resourceStream) { } + } + + private class PageContents + { + private MemoryStream PageStream { get; } = new MemoryStream(); + + public Dictionary Resources { get; } = new Dictionary(); + + public byte[] GetPageData() => PageStream.ToArray(); + + public Stream GetPageStream() => PageStream; + + public Stream GetResourceStream(string fileName) + { + var resourceStream = new MemoryStream(); + Resources.Add(fileName, resourceStream); + return resourceStream; + } + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/JpgViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/JpgViewer.cs new file mode 100644 index 000000000..e60cb22f2 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/JpgViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetWebForms.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers +{ + internal class JpgViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public JpgViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => JpgPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) => + new JpgPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(JpgViewer)} does not support retrieving external HTML resources."); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromJpgViewOptions(_config.JpgViewOptions); + + private JpgViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = new JpgViewOptions(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.JpgViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Core/Viewers/PngViewer.cs b/Demos/ASP.NET Web Forms/src/Core/Viewers/PngViewer.cs new file mode 100644 index 000000000..e5d24cbe1 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Core/Viewers/PngViewer.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Threading.Tasks; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.Entities; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers.Extensions; +using GroupDocs.Viewer.Options; +using Page = GroupDocs.Viewer.AspNetWebForms.Core.Entities.Page; + +namespace GroupDocs.Viewer.AspNetWebForms.Core.Viewers +{ + internal class PngViewer : BaseViewer + { + private readonly ViewerConfig _config; + + public PngViewer(ViewerConfig config, + IViewerLicenser licenser, + IFileStorage fileStorage, + IFileTypeResolver fileTypeResolver, + IPageFormatter pageFormatter) + : base(config, licenser, fileStorage, fileTypeResolver, pageFormatter) + { + _config = config; + } + + public override string PageExtension => PngPage.Extension; + + public override Page CreatePage(int pageNumber, byte[] data) => + new PngPage(pageNumber, data); + + public override Task GetPageResourceAsync( + FileCredentials fileCredentials, int pageNumber, string resourceName) => + throw new System.NotImplementedException( + $"{nameof(PngViewer)} does not support retrieving external HTML resources."); + + protected override Page RenderPage(Viewer viewer, string filePath, int pageNumber) + { + var pageStream = new MemoryStream(); + var viewOptions = CreateViewOptions(pageStream); + + viewer.View(viewOptions, pageNumber); + + var bytes = pageStream.ToArray(); + var page = CreatePage(pageNumber, bytes); + + return page; + } + + protected override ViewInfoOptions CreateViewInfoOptions() => + ViewInfoOptions.FromJpgViewOptions(_config.JpgViewOptions); + + private PngViewOptions CreateViewOptions(MemoryStream pageStream) + { + var viewOptions = new PngViewOptions(_ => pageStream, + (_, __) => { /*NOTE: Do nothing here*/ }); + + viewOptions.CopyViewOptions(_config.PngViewOptions); + + return viewOptions; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Default.aspx b/Demos/ASP.NET Web Forms/src/Default.aspx new file mode 100644 index 000000000..04bfda6ce --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Default.aspx @@ -0,0 +1,21 @@ +<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GroupDocs.Viewer.AspNetWebForms._Default" %> +<%@ Import Namespace="GroupDocs.Viewer.AspNetWebForms.Core" %> + + + + + + + GroupDocs.Viewer for .NET ASP.NET Web Forms Demo + + + + + + + + + \ No newline at end of file diff --git a/Demos/WebForms/src/Viewer.aspx.cs b/Demos/ASP.NET Web Forms/src/Default.aspx.cs similarity index 52% rename from Demos/WebForms/src/Viewer.aspx.cs rename to Demos/ASP.NET Web Forms/src/Default.aspx.cs index 942130936..cfceb1837 100644 --- a/Demos/WebForms/src/Viewer.aspx.cs +++ b/Demos/ASP.NET Web Forms/src/Default.aspx.cs @@ -1,11 +1,13 @@ using System; +using System.Web.UI; -namespace GroupDocs.Viewer.WebForms +namespace GroupDocs.Viewer.AspNetWebForms { - public partial class Viewer : System.Web.UI.Page + public partial class _Default : Page { protected void Page_Load(object sender, EventArgs e) { + } } } \ No newline at end of file diff --git a/Demos/WebForms/src/Viewer.aspx.designer.cs b/Demos/ASP.NET Web Forms/src/Default.aspx.designer.cs similarity index 74% rename from Demos/WebForms/src/Viewer.aspx.designer.cs rename to Demos/ASP.NET Web Forms/src/Default.aspx.designer.cs index 5aae4f254..8f7abe8e4 100644 --- a/Demos/WebForms/src/Viewer.aspx.designer.cs +++ b/Demos/ASP.NET Web Forms/src/Default.aspx.designer.cs @@ -3,13 +3,15 @@ // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// the code is regenerated. // //------------------------------------------------------------------------------ -namespace GroupDocs.Viewer.WebForms { - - - public partial class Viewer { +namespace GroupDocs.Viewer.AspNetWebForms +{ + + + public partial class _Default + { } } diff --git a/Demos/WebForms/src/Global.asax b/Demos/ASP.NET Web Forms/src/Global.asax similarity index 56% rename from Demos/WebForms/src/Global.asax rename to Demos/ASP.NET Web Forms/src/Global.asax index 64dcf44f2..139f4c71b 100644 --- a/Demos/WebForms/src/Global.asax +++ b/Demos/ASP.NET Web Forms/src/Global.asax @@ -1 +1 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="GroupDocs.Viewer.WebForms.Global" Language="C#" %> +<%@ Application Codebehind="Global.asax.cs" Inherits="GroupDocs.Viewer.AspNetWebForms.Global" Language="C#" %> diff --git a/Demos/ASP.NET Web Forms/src/Global.asax.cs b/Demos/ASP.NET Web Forms/src/Global.asax.cs new file mode 100644 index 000000000..d25aa1273 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Global.asax.cs @@ -0,0 +1,79 @@ +using System; +using System.Web; +using System.Web.Http; +using Unity.WebApi; +using Unity; +using GroupDocs.Viewer.AspNetWebForms.Core.Caching; +using GroupDocs.Viewer.AspNetWebForms.Core.Configuration; +using GroupDocs.Viewer.AspNetWebForms.Core.FileTypeResolution; +using GroupDocs.Viewer.AspNetWebForms.Core.Licensing; +using GroupDocs.Viewer.AspNetWebForms.Core.PageFormatting; +using GroupDocs.Viewer.AspNetWebForms.Core.Storage; +using GroupDocs.Viewer.AspNetWebForms.Core.Viewers; +using GroupDocs.Viewer.AspNetWebForms.Core; + +namespace GroupDocs.Viewer.AspNetWebForms +{ + public class Global : HttpApplication + { + void Application_Start(object sender, EventArgs e) + { + UnityContainer container = new UnityContainer(); + ConfigureServices(container); + + GlobalConfiguration.Configuration.DependencyResolver = + new UnityDependencyResolver(container); + + GlobalConfiguration.Configure(WebApiConfig.Register); + } + + private void ConfigureServices(UnityContainer container) + { + var viewerType = ViewerType.HtmlWithEmbeddedResources; + + //Temporary license can be requested at https://purchase.groupdocs.com/temporary-license + var licensePath = Server.MapPath("~/GroupDocs.Viewer.lic"); + var filesPath = Server.MapPath("~/Storage/Files"); + var cachePath = Server.MapPath("~/Storage/Cache"); + + var uiConfig = UIConfig.Instance + .SetViewerType(viewerType); + var viewerConfig = ViewerConfig.Instance + .SetLicensePath(licensePath); + + container.RegisterFactory(c => viewerConfig); + container.RegisterFactory(c => uiConfig); + container.RegisterFactory(c => new LocalFileStorage(filesPath)); + container.RegisterFactory(c => new LocalFileCache(cachePath)); + container.RegisterType(); + container.RegisterType(); + container.RegisterType(); + container.RegisterType(); + + container.RegisterFactory(c => + { + IViewer viewer; + switch (uiConfig.ViewerType) + { + case ViewerType.HtmlWithExternalResources: + viewer = c.Resolve(); + break; + case ViewerType.Jpg: + viewer = c.Resolve(); + break; + case ViewerType.Png: + viewer = c.Resolve(); + break; + default: + viewer = c.Resolve(); + break; + } + + var fileCache = c.Resolve(); + var asyncLock = c.Resolve(); + + return new CachingViewer(viewer, fileCache, asyncLock); + }); + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.csproj b/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.csproj new file mode 100644 index 000000000..aca54e276 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.csproj @@ -0,0 +1,275 @@ + + + + + Debug + AnyCPU + + + 2.0 + {2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + GroupDocs.Viewer.AspNetWebForms + GroupDocs.Viewer.AspNetWebForms + v4.8 + true + + 44349 + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + packages\GroupDocs.Viewer.22.9.0\lib\net40\GroupDocs.Viewer.dll + + + packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + + + packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + packages\Microsoft.AspNet.Cors.5.2.9\lib\net45\System.Web.Cors.dll + + + + packages\Microsoft.AspNet.WebApi.Cors.5.2.9\lib\net45\System.Web.Http.Cors.dll + + + + + + + + + + + + + True + packages\Microsoft.Web.Infrastructure.2.0.1\lib\net40\Microsoft.Web.Infrastructure.dll + + + packages\Unity.5.11.9\lib\net48\Unity.Abstractions.dll + + + packages\Unity.5.11.9\lib\net48\Unity.Container.dll + + + packages\Unity.WebAPI.5.4.0\lib\net45\Unity.WebApi.dll + + + + + packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + + + packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll + + + packages\Microsoft.AspNet.WebApi.Core.5.2.9\lib\net45\System.Web.Http.dll + + + packages\Microsoft.AspNet.WebApi.WebHost.5.2.9\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default.aspx + ASPXCodeBehind + + + Default.aspx + + + Global.asax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 8080 + / + https://localhost:44391/ + False + False + + + False + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.sln b/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.sln new file mode 100644 index 000000000..9f0ce77e7 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/GroupDocs.Viewer.AspNetWebForms.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32922.545 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.AspNetWebForms", "GroupDocs.Viewer.AspNetWebForms.csproj", "{2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DF2BE92-E5E8-49FC-A73F-6FA0098CCC1E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {02912FFE-6C67-4F40-8BC6-B9B4B9118495} + EndGlobalSection +EndGlobal diff --git a/Demos/ASP.NET Web Forms/src/Models/ErrorResponse.cs b/Demos/ASP.NET Web Forms/src/Models/ErrorResponse.cs new file mode 100644 index 000000000..84552c9a0 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/ErrorResponse.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class ErrorResponse + { + /// + /// The error message. + /// + [JsonProperty("message")] + public string Message { get; set; } + + public ErrorResponse(string message) + { + this.Message = message; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/FileDescription.cs b/Demos/ASP.NET Web Forms/src/Models/FileDescription.cs new file mode 100644 index 000000000..082aa667e --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/FileDescription.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class FileDescription + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; } + + /// + /// File file name. + /// + [JsonProperty("name")] + public string Name { get; } + + /// + /// True when it is a directory. + /// + [JsonProperty("isDirectory")] + public bool IsDirectory { get; } + + /// + /// Size in bytes. + /// + [JsonProperty("size")] + public long Size { get; } + + /// + /// .ctor + /// + public FileDescription(string guid, string name, bool isDirectory, long size) + { + Guid = guid; + Name = name; + IsDirectory = isDirectory; + Size = size; + } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadConfigResponse.cs b/Demos/ASP.NET Web Forms/src/Models/LoadConfigResponse.cs new file mode 100644 index 000000000..00044efe1 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadConfigResponse.cs @@ -0,0 +1,121 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadConfigResponse + { + /// + /// Enables page selector control. + /// + [JsonProperty("pageSelector")] + public bool PageSelector { get; set; } + + /// + /// Enables download button. + /// + [JsonProperty("download")] + public bool Download { get; set; } + + /// + /// Enables upload. + /// + [JsonProperty("upload")] + public bool Upload { get; set; } + + /// + /// Enables printing. + /// + [JsonProperty("print")] + public bool Print { get; set; } + + /// + /// Enables file browser. + /// + [JsonProperty("browse")] + public bool Browse { get; set; } + + /// + /// Enables file rewrite. + /// + [JsonProperty("rewrite")] + public bool Rewrite { get; set; } + + /// + /// Enables right click. + /// + [JsonProperty("enableRightClick")] + public bool EnableRightClick { get; set; } + + /// + /// The default document to view. + /// + [JsonProperty("defaultDocument")] + public string DefaultDocument { get; set; } + + /// + /// Count pages to preload. + /// + [JsonProperty("preloadPageCount")] + public int PreloadPageCount { get; set; } + + /// + /// Enables zoom. + /// + [JsonProperty("zoom")] + public bool Zoom { get; set; } + + /// + /// Enables searching. + /// + [JsonProperty("search")] + public bool Search { get; set; } + + /// + /// Enables thumbnails. + /// + [JsonProperty("thumbnails")] + public bool Thumbnails { get; set; } + + /// + /// Image or HTML mode. + /// + [JsonProperty("htmlMode")] + public bool HtmlMode { get; set; } + + /// + /// Enables printing + /// + [JsonProperty("printAllowed")] + public bool PrintAllowed { get; set; } + + /// + /// Enables rotation + /// + [JsonProperty("rotate")] + public bool Rotate { get; set; } + + /// + /// Enables saving of rotation state + /// + [JsonProperty("saveRotateState")] + public bool SaveRotateState { get; set; } + + /// + /// Default language e.g. "en". + /// + [JsonProperty("defaultLanguage")] + public string DefaultLanguage { get; set; } + + /// + /// Supported languages e.g. [ "en", "fr", "de" ] + /// + [JsonProperty("supportedLanguages")] + public string[] SupportedLanguages { get; set; } + + /// + /// Enables language menu. + /// + [JsonProperty("showLanguageMenu")] + public bool ShowLanguageMenu { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionRequest.cs b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionRequest.cs new file mode 100644 index 000000000..893ce618d --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionRequest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadDocumentDescriptionRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionResponse.cs b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionResponse.cs new file mode 100644 index 000000000..27626a8a3 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentDescriptionResponse.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadDocumentDescriptionResponse + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// Indicates if printing of the document is allowed. + /// + [JsonProperty("printAllowed")] + public bool PrintAllowed { get; set; } + + /// + /// Document pages. + /// + [JsonProperty("pages")] + public List Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPageRequest.cs b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPageRequest.cs new file mode 100644 index 000000000..dd3cf8a9b --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPageRequest.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadDocumentPageRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + + /// + /// The page to return. + /// + [JsonProperty("page")] + public int Page { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPagesRequest.cs b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPagesRequest.cs new file mode 100644 index 000000000..bc37f5573 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadDocumentPagesRequest.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadDocumentPagesRequest + { + /// + /// File unique ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g. "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// The password to open a document. + /// + [JsonProperty("password")] + public string Password { get; set; } + + /// + /// The pages to return. + /// + [JsonProperty("pages")] + public int[] Pages { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/LoadFileTreeRequest.cs b/Demos/ASP.NET Web Forms/src/Models/LoadFileTreeRequest.cs new file mode 100644 index 000000000..8cc1b9954 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/LoadFileTreeRequest.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class LoadFileTreeRequest + { + /// + /// Folder path. + /// + [JsonProperty("path")] + public string Path { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/PageContent.cs b/Demos/ASP.NET Web Forms/src/Models/PageContent.cs new file mode 100644 index 000000000..765920399 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/PageContent.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class PageContent + { + /// + /// Page number. + /// + [JsonProperty("number")] + public int Number { get; set; } + + /// + /// Page contents. It can be HTML or base64-encoded image. + /// + [JsonProperty("data")] + public string Data { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/PageDescription.cs b/Demos/ASP.NET Web Forms/src/Models/PageDescription.cs new file mode 100644 index 000000000..f2e3bbadc --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/PageDescription.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class PageDescription : PageContent + { + /// + /// Page with in pixels. + /// + [JsonProperty("width")] + public int Width { get; set; } + + /// + /// Page height in pixels. + /// + [JsonProperty("height")] + public int Height { get; set; } + + /// + /// Worksheet name for spreadsheets. + /// + [JsonProperty("sheetName")] + public string SheetName { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/PrintPdfRequest.cs b/Demos/ASP.NET Web Forms/src/Models/PrintPdfRequest.cs new file mode 100644 index 000000000..e79eb85c3 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/PrintPdfRequest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class PrintPdfRequest + { + /// + /// Unique file ID. + /// + [JsonProperty("guid")] + public string Guid { get; set; } + + /// + /// File type e.g. "docx". + /// + [JsonProperty("fileType")] + public string FileType { get; set; } + + /// + /// Password to open the document. + /// + [JsonProperty("password")] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Models/UploadFileResponse.cs b/Demos/ASP.NET Web Forms/src/Models/UploadFileResponse.cs new file mode 100644 index 000000000..8b8825011 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Models/UploadFileResponse.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace GroupDocs.Viewer.AspNetWebForms.Models +{ + public class UploadFileResponse + { + /// + /// Unique file ID. + /// + [JsonProperty("guid")] + public string Guid { get; } + + /// + /// .ctor + /// + public UploadFileResponse(string filePath) + { + Guid = filePath; + } + } +} \ No newline at end of file diff --git a/Demos/WebForms/src/Properties/AssemblyInfo.cs b/Demos/ASP.NET Web Forms/src/Properties/AssemblyInfo.cs similarity index 74% rename from Demos/WebForms/src/Properties/AssemblyInfo.cs rename to Demos/ASP.NET Web Forms/src/Properties/AssemblyInfo.cs index 476a99245..c4213f040 100644 --- a/Demos/WebForms/src/Properties/AssemblyInfo.cs +++ b/Demos/ASP.NET Web Forms/src/Properties/AssemblyInfo.cs @@ -5,12 +5,12 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("GroupDocs.Viewer.WebForms")] +[assembly: AssemblyTitle("GroupDocs.Viewer.AspNetWebForms")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Aspose Pty Ltd")] -[assembly: AssemblyProduct("GroupDocs.Viewer.WebForms")] -[assembly: AssemblyCopyright("2001-2018 Aspose Pty Ltd")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("GroupDocs.Viewer.AspNetWebForms")] +[assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +20,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7b296703-ac7b-4fa6-bd42-bec76d0c6ddc")] +[assembly: Guid("2df2be92-e5e8-49fc-a73f-6fa0098ccc1e")] // Version information for an assembly consists of the following four values: // @@ -31,5 +31,5 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.19.0.0")] -[assembly: AssemblyFileVersion("1.19.0.0")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demos/MVC/src/client/apps/viewer/src/assets/.gitkeep b/Demos/ASP.NET Web Forms/src/Storage/Cache/.gitkeep similarity index 100% rename from Demos/MVC/src/client/apps/viewer/src/assets/.gitkeep rename to Demos/ASP.NET Web Forms/src/Storage/Cache/.gitkeep diff --git a/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/info.json b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/info.json new file mode 100644 index 000000000..110918da5 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/info.json @@ -0,0 +1,18 @@ +{ + "FileType": "vsdx", + "PrintAllowed": true, + "Pages": [ + { + "Width": 1056, + "Height": 816, + "Number": 1, + "Name": "Page-1" + }, + { + "Width": 1056, + "Height": 816, + "Number": 2, + "Name": "VBackground-1" + } + ] +} \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p1.html b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p1.html new file mode 100644 index 000000000..fc762f6d9 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p1.html @@ -0,0 +1,239 @@ + + + + + + Page-1 + + +
+ + + + + + + + + + + + + Solid + + + + + + + + + + + + Rounded Rectangle + + + + + + + + + + + + + + + + + + Branch 1 + + + + Rounded Rectangle.5 + + + + + + + + + + + + + + + + + + Branch 2 + + + + Rounded Rectangle.6 + + + + + + + + + + + + + + + + + + Branch 3 + + + + Rounded Rectangle.8 + + + + + + + + + + + + + + + + + + Development branch + + + + Rounded Rectangle.9 + + + + + + + + + + + + + + + + + + Main branch + + + + Rounded Rectangle.10 + + + + + + + + + + + + + + + + + + Staging server + + + + Rounded Rectangle.11 + + + + + + + + + + + + + + + + + + Production server + + + + Dynamic connector + + + + + Dynamic connector.13 + + + + + Dynamic connector.14 + + + + Merge + + + + Dynamic connector.15 + + + + + Merge + + + + Dynamic connector.16 + + + + + Deploy + + + + Dynamic connector.17 + + + + + Deploy + + + + + + + +
+ + \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p2.html b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p2.html new file mode 100644 index 000000000..3b894fa75 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Storage/Cache/flowchart_vsdx/p2.html @@ -0,0 +1,37 @@ + + + + + + Page-2 + + +
+ + + + + + + + + + + + + Solid + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/flowchart.vsdx b/Demos/ASP.NET Web Forms/src/Storage/Files/flowchart.vsdx new file mode 100644 index 000000000..12db7e009 Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/flowchart.vsdx differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/groupdocs.pptx b/Demos/ASP.NET Web Forms/src/Storage/Files/groupdocs.pptx new file mode 100644 index 000000000..d94d696dd Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/groupdocs.pptx differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/house-plan.dwg b/Demos/ASP.NET Web Forms/src/Storage/Files/house-plan.dwg new file mode 100644 index 000000000..ff07697b5 Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/house-plan.dwg differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/invoice.xlsx b/Demos/ASP.NET Web Forms/src/Storage/Files/invoice.xlsx new file mode 100644 index 000000000..f223175b2 Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/invoice.xlsx differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/resume.docx b/Demos/ASP.NET Web Forms/src/Storage/Files/resume.docx new file mode 100644 index 000000000..1d9f67edb Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/resume.docx differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/resume.pdf b/Demos/ASP.NET Web Forms/src/Storage/Files/resume.pdf new file mode 100644 index 000000000..ef4cae4db Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/resume.pdf differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/software-development-plan.mpp b/Demos/ASP.NET Web Forms/src/Storage/Files/software-development-plan.mpp new file mode 100644 index 000000000..5e48341a2 Binary files /dev/null and b/Demos/ASP.NET Web Forms/src/Storage/Files/software-development-plan.mpp differ diff --git a/Demos/ASP.NET Web Forms/src/Storage/Files/vector-image.svg b/Demos/ASP.NET Web Forms/src/Storage/Files/vector-image.svg new file mode 100644 index 000000000..6df8640de --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/Storage/Files/vector-image.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/WebForms/src/Web.Debug.config b/Demos/ASP.NET Web Forms/src/Web.Debug.config similarity index 95% rename from Demos/WebForms/src/Web.Debug.config rename to Demos/ASP.NET Web Forms/src/Web.Debug.config index 2e302f9f9..fae9cfefa 100644 --- a/Demos/WebForms/src/Web.Debug.config +++ b/Demos/ASP.NET Web Forms/src/Web.Debug.config @@ -1,6 +1,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/ASP.NET Web Forms/src/packages.config b/Demos/ASP.NET Web Forms/src/packages.config new file mode 100644 index 000000000..bd0d2bab6 --- /dev/null +++ b/Demos/ASP.NET Web Forms/src/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/MVC/GroupDocs.Viewer MVC.sln b/Demos/MVC/GroupDocs.Viewer MVC.sln deleted file mode 100644 index 86ea44e8e..000000000 --- a/Demos/MVC/GroupDocs.Viewer MVC.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2050 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.MVC", "src\GroupDocs.Viewer.MVC.csproj", "{A33CA8B0-A193-40A3-A86A-90FF444EE878}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.MVC.Test", "tests\GroupDocs.Viewer.MVC.Test\GroupDocs.Viewer.MVC.Test.csproj", "{C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A33CA8B0-A193-40A3-A86A-90FF444EE878}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A33CA8B0-A193-40A3-A86A-90FF444EE878}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A33CA8B0-A193-40A3-A86A-90FF444EE878}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A33CA8B0-A193-40A3-A86A-90FF444EE878}.Release|Any CPU.Build.0 = Release|Any CPU - {C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {FD28B4B3-0EF5-4398-BA1B-B9E8B7416368} - EndGlobalSection -EndGlobal diff --git a/Demos/MVC/README.md b/Demos/MVC/README.md deleted file mode 100644 index 8e19ca911..000000000 --- a/Demos/MVC/README.md +++ /dev/null @@ -1,150 +0,0 @@ -![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") -# GroupDocs.Viewer for .NET MVC Example -###### version 1.20.0 - -[![GitHub license](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC.svg)](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/blob/master/Demos/MVC/LICENSE) - -## System Requirements -- .NET Framework 4.5 -- Visual Studio 2015 - -## Document Viewer API for .NET MVC - -[GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) API allows you to view over 170 document formats including **DOCX**, **PDF**, **PPT**, **XLS**, among many others without any additional dependencies. Thanks to its flexible configuration it can be configured to **view documents as images or as HTML5**. - - -In order to demonstrate GroupDocs.Viewer for Java reach and powerful features we prepared a modern **document viewer** front-end web UI example. Which can be used as a standalone application or easily integrated into your project. - - -**Note:** without a license application will run in trial mode, purchase [GroupDocs.Viewer for .NET license](https://purchase.groupdocs.com/order-online-step-1-of-8.aspx) or request [GroupDocs.Viewer for .NET temporary license](https://purchase.groupdocs.com/temporary-license). - - -## Supported document Formats - -| Family | Formats | -| --------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------- | -| Archive formats | `ZIP`, `TAR`, `BZ2`, `RAR`, `GZIP` | -| Apple formats | `Numbers` | -| PDF formats | `PDF`, `XPS`, `OXPS`, `TEX` | -| CAD formats | `DXF`, `DWG` , `DWT`, `STL`, `IFC`,`DWF` , `DWFX`, `DGN`, `PLT`,`CF2`,`OBJ`, `HPG`, `IGS` | -| Microsoft Word | `DOC`, `DOCM` , `DOCX`, `DOT`, `DOTM`, `DOTX`,`RTF` | -| Microsoft Excel | `XLS`, `XLSB`, `XLSM`, `XLSX`, `XLT`, `XLTM`, `XLTX`,`Excel 2003 XML`,`XLAM` | -| Microsoft PowerPoint | `PPT`, `POT`, `POTM`, `POTX`, `PPS`, `PPSM`, `PPSX`, `PPTM`, `PPTX` | -| Microsoft Visio | `VSD`,`VSDX`,`VSDM`,`VDW`, `VDX`, `VSDX`, `VSS`,`VSSX`,`VSSM`,`VST`,`VSTX`, `VSX`, `VTX`,`VSTM` | -| Microsoft Project | `MPP`, `MPT`,`MPX` | -| Help files | `CHM` | -| Email formats | `EML`, `EMLX`, `MSG`, `NSF`, `MBOX`, `PST`,`OST`, `VCF` | -| OpenDocument Formats | `ODT`, `ODP`,`FODP`, `ODS`,`FODS`, `OTT`,`OTS`,`ODG`,`FODG`,`OTG`,`OTP`,`SXC` | -| Plain Text File | `TXT`,`TSV` | -| Comma-Separated Values | `CSV` | -| HyperText Markup Language | `HTML`, `MHT`, `MHTML`, `SVG`,`SVGZ` | -| Extensible Markup Language | `XML`,`XML`, `XPS` | -| AutoCAD Drawing File Format | `DGN`, `DWG`, `DXF` | -| Image files | `BMP`, `CAL`, `DCX`,`CGM`,`PCL`,`PSB`, `DIB`, `EMF`,`EMZ`,`WEBP`,`DNG`,`CDR`,`CMX`, `GIF`,
`JP2`, `JPG`,`JPF`,`JPM`,`J2C`,`J2K`,`JPC`,`JPX`,`MIL`, `MIL`, `PCD`, `PCT`, `PCX`, `PNG`,
`Animated PNG`, `PSD`,`PS`, `RAS`, `TGA`,`TIFF`,`WMF`,`WMZ`,`EPS`, `AI` | -| Electronic publication | `EPUB`,`MOBI`,`DJVU` | -| Windows Icon | `ICO` | -| Medical image files | `DCM` | -| Programming Language Formats | `AS`, `AS3`, `ASM`, `BAT`, `C`, `CC`, `CMAKE`, `CPP`, `CS`,`VB`, `CSS`, `CXX`, `DIFF`, `ERB`,
`GROOVY`, `H`,`HAML`, `HH`, `JAVA`, `JS`, `JSON`, `LESS`, `LOG`, `M`, `MAKE`, `MD`, `ML`,
`MM`, `PHP`, `PL`, `PROPERTIES`, `PY`, `RB`, `RST`, `SASS`, `SCALA`, `SCM`, `SCRIPT`,
`SH`, `SML`, `SQL`, `VIM`, `YAML`| | - -## Demo Video - -

- - - -

- - -## Features -- Clean, modern and intuitive design -- Easily switchable colour theme (create your own colour theme in 5 minutes) -- Responsive design -- Mobile support (open application on any mobile device) -- Support over 50 documents and image formats including **DOCX**, **PDF**, **PPT**, **XLS** -- HTML and image modes -- Fully customizable navigation panel -- Open password protected documents -- Text searching & highlighting -- Download documents -- Upload documents -- Print document -- Rotate pages -- Zoom in/out documents without quality loss in HTML mode -- Thumbnails -- Smooth page navigation -- Smooth document scrolling -- Preload pages for faster document rendering -- Multi-language support for displaying errors -- Display two or more pages side by side (when zooming out) -- Cross-browser support (Safari, Chrome, Opera, Firefox) -- Cross-platform support (Windows, Linux, MacOS) - - -## How to run - -You can run this sample by one of following methods - -#### Build from source - -Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC/archive/master.zip) from github or clone this repository. - -```bash -git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC -``` - -Open solution in the VisualStudio. -Update common parameters in `web.config` and example related properties in the `configuration.yml` to meet your requirements. - -Open http://localhost:8080/Viewer in your favorite browser - -#### Docker image -Use [docker](https://www.docker.com/) image. - -```bash -mkdir DocumentSamples -mkdir Licenses -docker run -p 8080:8080 --env application.hostAddress=localhost -v `pwd`/DocumentSamples:/home/groupdocs/app/DocumentSamples -v `pwd`/Licenses:/home/groupdocs/app/Licenses groupdocs/Viewer -## Open http://localhost:8080/Viewer in your favorite browser. -``` - -### Configuration -For all methods above you can adjust settings in `configuration.yml`. By default in this sample will lookup for license file in `./Licenses` folder, so you can simply put your license file in that folder or specify relative/absolute path by setting `licensePath` value in `configuration.yml`. - -#### Viewer configuration options - -| Option | Type | Default value | Description | -| ---------------------- | ------- |:-----------------:|:-------------------------------------------------------------------------------------------------------------------------------------------- | -| **`filesDirectory`** | String | `DocumentSamples` | Files directory path. Indicates where uploaded and predefined files are stored. It can be absolute or relative path | -| **`fontsDirectory`** | String | | Path to custom fonts directory. | -| **`defaultDocument`** | String | | Absolute path to default document that will be loaded automaticaly. | -| **`preloadPageCount`** | Integer | `0` | Indicate how many pages from a document should be loaded, remaining pages will be loaded on page scrolling.Set `0` to load all pages at once | -| **`htmlMode`** | Boolean | `true` | HTML rendering mode. Set `false` to view documents in image mode. Set `true` to view documents in HTML mode | -| **`zoom`** | Boolean | `true` | Enable or disable Document zoom | -| **`search`** | Boolean | `true` | Enable or disable document search | -| **`thumbnails`** | Boolean | `true` | Enable thumbnails preview | -| **`rotate`** | Boolean | `true` | Enable individual page rotation functionality | -| **`cache`** | Boolean | `true` | Set true to enable cache | -| **`saveRotateState`** | Boolean | `true` | If enabled it will save chages made by rotating individual pages to same file. | -| **`watermarkText`** | String | | Text which will be used as a watermark | - -## Troubleshooting -### How to set custom baseURL -BaseURL is fetched from address bar however you can set custom baseURL by adding *forRoot* parameter at [app.module.ts](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC/blob/master/src/client/apps/viewer/src/app/app.module.ts#L10) - -**Example:** -```js -ViewerModule.forRoot("http://localhost:8080") -``` - -## License -The MIT License (MIT). - -Please have a look at the LICENSE.md for more details - -## GroupDocs Document Viewer on other platforms/frameworks - -- JAVA DropWizard [Document Viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Dropwizard) -- JAVA Spring boot [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Spring) -- .NET WebForms [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms) - -[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/family) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/MVC/appveyor.yml b/Demos/MVC/appveyor.yml deleted file mode 100644 index 7b3b7926e..000000000 --- a/Demos/MVC/appveyor.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: 1.0.{build} -pull_requests: - do_not_increment_build_number: true -before_build: -- cmd: nuget restore -build: - verbosity: minimal \ No newline at end of file diff --git a/Demos/MVC/src/AppDomainGenerator/DomainGenerator.cs b/Demos/MVC/src/AppDomainGenerator/DomainGenerator.cs deleted file mode 100644 index c2efb7252..000000000 --- a/Demos/MVC/src/AppDomainGenerator/DomainGenerator.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.IO; -using System.Reflection; - -namespace GroupDocs.Viewer.MVC.AppDomainGenerator -{ - public class DomainGenerator - { - private readonly Products.Common.Config.GlobalConfiguration globalConfiguration; - private readonly Type CurrentType; - - /// - /// Initializes a new instance of the class. - /// - public DomainGenerator(string assemblyName, string className) - { - this.globalConfiguration = new Products.Common.Config.GlobalConfiguration(); - - // Get assembly path - string assemblyPath = GetAssemblyPath(assemblyName); - - // Initiate GroupDocs license class - this.CurrentType = this.CreateDomain(assemblyName + "Domain", assemblyPath, className); - } - - /// - /// Get assembly full path by its name. - /// - /// string. - /// - private static string GetAssemblyPath(string assemblyName) - { - string path = string.Empty; - - // Get path of the executable - string codeBase = Assembly.GetExecutingAssembly().CodeBase; - UriBuilder uri = new UriBuilder(codeBase); - string uriPath = Uri.UnescapeDataString(uri.Path); - - // Get path of the assembly - path = Path.Combine(Path.GetDirectoryName(uriPath), assemblyName); - return path; - } - - /// - /// Create AppDomain for the assembly. - /// - /// string. - /// string. - /// string. - /// - private Type CreateDomain(string domainName, string assemblyPath, string className) - { - // Create domain - AppDomain dom = AppDomain.CreateDomain(domainName); - AssemblyName assemblyName = new AssemblyName { CodeBase = assemblyPath }; - - // Load assembly into the domain - Assembly assembly = dom.Load(assemblyName); - - // Initiate class from the loaded assembly - Type type = assembly.GetType(className); - return type; - } - - /// - /// Set GroupDocs.Viewer license. - /// - /// Type. - public void SetViewerLicense() - { - // Initiate license class - var obj = (GroupDocs.Viewer.License)Activator.CreateInstance(this.CurrentType); - - // Set license - this.SetLicense(obj); - } - - private void SetLicense(dynamic obj) - { - if (!string.IsNullOrEmpty(this.globalConfiguration.Application.LicensePath)) - { - obj.SetLicense(this.globalConfiguration.Application.LicensePath); - } - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/App_Start/FilterConfig.cs b/Demos/MVC/src/App_Start/FilterConfig.cs deleted file mode 100644 index affdb2657..000000000 --- a/Demos/MVC/src/App_Start/FilterConfig.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Web.Mvc; - -namespace GroupDocs.Viewer.MVC -{ - public class FilterConfig - { - public static void RegisterGlobalFilters(GlobalFilterCollection filters) - { - filters.Add(new HandleErrorAttribute()); - } - } -} diff --git a/Demos/MVC/src/Controllers/ViewerController.cs b/Demos/MVC/src/Controllers/ViewerController.cs deleted file mode 100644 index d96f6fa2a..000000000 --- a/Demos/MVC/src/Controllers/ViewerController.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Web.Mvc; - -namespace GroupDocs.Viewer.MVC.Controllers -{ - /// - /// Viewer Web page controller. - /// - public class ViewerController : Controller - { - public ActionResult Index() - { - return this.View(); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Global.asax.cs b/Demos/MVC/src/Global.asax.cs deleted file mode 100644 index d699397e5..000000000 --- a/Demos/MVC/src/Global.asax.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Web.Http; -using System.Web.Mvc; -using System.Web.Routing; -using GroupDocs.Viewer.MVC.AppDomainGenerator; - -namespace GroupDocs.Viewer.MVC -{ - public class WebApiApplication : System.Web.HttpApplication - { - protected void Application_Start() - { - // Fix required to use several GroupDocs products in one project. - // Set GroupDocs products assemblies names - string viewerAssemblyName = "GroupDocs.Viewer.dll"; - - // set GroupDocs.Metadata license - DomainGenerator viewerDomainGenerator = new DomainGenerator(viewerAssemblyName, "GroupDocs.Viewer.License"); - viewerDomainGenerator.SetViewerLicense(); - - AreaRegistration.RegisterAllAreas(); - GlobalConfiguration.Configure(WebApiConfig.Register); - FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); - RouteConfig.RegisterRoutes(RouteTable.Routes); - } - } -} diff --git a/Demos/MVC/src/GroupDocs.Viewer.MVC.csproj b/Demos/MVC/src/GroupDocs.Viewer.MVC.csproj deleted file mode 100644 index 818b750a7..000000000 --- a/Demos/MVC/src/GroupDocs.Viewer.MVC.csproj +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - - Debug - AnyCPU - - - 2.0 - {A33CA8B0-A193-40A3-A86A-90FF444EE878} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - GroupDocs.Viewer.MVC - GroupDocs.Viewer.MVC - v4.5 - false - true - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\GroupDocs.Viewer.22.7.0\lib\net40\GroupDocs.Viewer.dll - True - - - ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - True - - - - - - - - ..\packages\Microsoft.AspNet.WebApi.Client.5.2.5\lib\net45\System.Net.Http.Formatting.dll - True - - - ..\packages\Microsoft.AspNet.Cors.5.2.5\lib\net45\System.Web.Cors.dll - True - - - - - - - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.5\lib\net45\System.Web.Http.dll - True - - - ..\packages\Microsoft.AspNet.WebApi.Cors.5.2.5\lib\net45\System.Web.Http.Cors.dll - True - - - - - - - - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - - - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - True - ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - - - ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - True - ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll - - - True - ..\packages\WebGrease.1.5.2\lib\WebGrease.dll - - - True - ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - ..\packages\YamlDotNet.5.2.1\lib\net45\YamlDotNet.dll - - - - - - - - - - - - - - - - - - - - - Global.asax - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - - - - True - True - 50289 - / - http://localhost:8080/viewer - False - False - - - False - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Config/ApplicationConfiguration.cs b/Demos/MVC/src/Products/Common/Config/ApplicationConfiguration.cs deleted file mode 100644 index 277907236..000000000 --- a/Demos/MVC/src/Products/Common/Config/ApplicationConfiguration.cs +++ /dev/null @@ -1,58 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Common.Util.Parser; -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; - -namespace GroupDocs.Viewer.MVC.Products.Common.Config -{ - /// - /// Application configuration. - /// - public class ApplicationConfiguration - { - /// - /// Get license path from the application configuration section of the web.config. - /// - public ApplicationConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("application"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - string license = valuesGetter.GetStringPropertyValue("licensePath"); - if (string.IsNullOrEmpty(license)) - { - string[] files = System.IO.Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.LicensePath), "*.lic"); - this.LicensePath = Path.Combine(this.LicensePath, files[0]); - } - else - { - if (!IsFullPath(license)) - { - license = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, license); - if (!Directory.Exists(Path.GetDirectoryName(license))) - { - Directory.CreateDirectory(Path.GetDirectoryName(license)); - } - } - - this.LicensePath = license; - if (!File.Exists(this.LicensePath)) - { - Debug.WriteLine("License file path is incorrect, launched in trial mode"); - this.LicensePath = string.Empty; - } - } - } - - public string LicensePath { get; set; } = "Licenses"; - - private static bool IsFullPath(string path) - { - return !string.IsNullOrWhiteSpace(path) - && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1 - && Path.IsPathRooted(path) - && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Config/CommonConfiguration.cs b/Demos/MVC/src/Products/Common/Config/CommonConfiguration.cs deleted file mode 100644 index 44306dab4..000000000 --- a/Demos/MVC/src/Products/Common/Config/CommonConfiguration.cs +++ /dev/null @@ -1,54 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Common.Util.Parser; -using Newtonsoft.Json; -using System; -using System.Collections.Specialized; -using System.Configuration; - -namespace GroupDocs.Viewer.MVC.Products.Common.Config -{ - /// - /// CommonConfiguration. - /// - public class CommonConfiguration : ConfigurationSection - { - [JsonProperty] - public bool pageSelector { get; set; } - - [JsonProperty] - public bool download { get; set; } - - [JsonProperty] - public bool upload { get; set; } - - [JsonProperty] - public bool print { get; set; } - - [JsonProperty] - public bool browse { get; set; } - - [JsonProperty] - public bool rewrite { get; set; } - - [JsonProperty] - public bool enableRightClick { get; set; } - - private NameValueCollection commonConfiguration = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("commonConfiguration"); - - /// - /// Constructor. - /// - public CommonConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("common"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - pageSelector = valuesGetter.GetBooleanPropertyValue("pageSelector", Convert.ToBoolean(commonConfiguration["isPageSelector"])); - download = valuesGetter.GetBooleanPropertyValue("download", Convert.ToBoolean(commonConfiguration["isDownload"])); - upload = valuesGetter.GetBooleanPropertyValue("upload", Convert.ToBoolean(commonConfiguration["isUpload"])); - print = valuesGetter.GetBooleanPropertyValue("print", Convert.ToBoolean(commonConfiguration["isPrint"])); - browse = valuesGetter.GetBooleanPropertyValue("browse", Convert.ToBoolean(commonConfiguration["isBrowse"])); - rewrite = valuesGetter.GetBooleanPropertyValue("rewrite", Convert.ToBoolean(commonConfiguration["isRewrite"])); - enableRightClick = valuesGetter.GetBooleanPropertyValue("enableRightClick", Convert.ToBoolean(commonConfiguration["enableRightClick"])); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Config/ConfigurationValuesGetter.cs b/Demos/MVC/src/Products/Common/Config/ConfigurationValuesGetter.cs deleted file mode 100644 index 8094b6f8d..000000000 --- a/Demos/MVC/src/Products/Common/Config/ConfigurationValuesGetter.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; - -namespace GroupDocs.Viewer.MVC.Products.Common.Config -{ - public class ConfigurationValuesGetter - { - private readonly dynamic configuration; - - public ConfigurationValuesGetter(dynamic configuration) - { - this.configuration = configuration; - } - - public string GetStringPropertyValue(string propertyName) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - this.configuration[propertyName].ToString() : - null; - } - - public string GetStringPropertyValue(string propertyName, string defaultValue) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - this.configuration[propertyName].ToString() : - defaultValue; - } - - public string[] GetStringArrayPropertyValue(string propertyName, string[] defaultValue) - { - if (this.configuration != null && this.configuration[propertyName] != null) - { - var array = this.configuration[propertyName] as Newtonsoft.Json.Linq.JArray; - if (array != null) - return array.ToObject(); - } - - return defaultValue; - } - - public int GetIntegerPropertyValue(string propertyName, int defaultValue) - { - int value; - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName]) : - defaultValue; - return value; - } - - public int GetIntegerPropertyValue(string propertyName, int defaultValue, string innerPropertyName) - { - int value; - if (!string.IsNullOrEmpty(innerPropertyName)) - { - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName][innerPropertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName][innerPropertyName]) : - defaultValue; - } - else - { - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName]) : - defaultValue; - } - - return value; - } - - public bool GetBooleanPropertyValue(string propertyName, bool defaultValue) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? Convert.ToBoolean(this.configuration[propertyName]) : defaultValue; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Config/GlobalConfiguration.cs b/Demos/MVC/src/Products/Common/Config/GlobalConfiguration.cs deleted file mode 100644 index 2bf7f6158..000000000 --- a/Demos/MVC/src/Products/Common/Config/GlobalConfiguration.cs +++ /dev/null @@ -1,26 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Viewer.Config; - -namespace GroupDocs.Viewer.MVC.Products.Common.Config -{ - /// - /// Global configuration. - /// - public class GlobalConfiguration - { - public ServerConfiguration Server { get; set; } - public ApplicationConfiguration Application { get; set; } - public CommonConfiguration Common { get; set; } - public ViewerConfiguration Viewer { get; set; } - - /// - /// Get all configurations. - /// - public GlobalConfiguration() - { - this.Server = new ServerConfiguration(); - this.Application = new ApplicationConfiguration(); - this.Viewer = new ViewerConfiguration(); - this.Common = new CommonConfiguration(); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Config/ServerConfiguration.cs b/Demos/MVC/src/Products/Common/Config/ServerConfiguration.cs deleted file mode 100644 index ce541c5bc..000000000 --- a/Demos/MVC/src/Products/Common/Config/ServerConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Common.Util.Parser; -using System; -using System.Collections.Specialized; -using System.Configuration; - -namespace GroupDocs.Viewer.MVC.Products.Common.Config -{ - /// - /// Server configuration. - /// - public class ServerConfiguration : ConfigurationSection - { - private readonly NameValueCollection serverConfiguration = (NameValueCollection)ConfigurationManager.GetSection("serverConfiguration"); - - public int HttpPort { get; set; } = 8080; - public string HostAddress { get; set; } = "localhost"; - - /// - /// Get server configuration section of the web.config. - /// - public ServerConfiguration() { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("server"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - int defaultPort = Convert.ToInt32(this.serverConfiguration["httpPort"]); - this.HttpPort = valuesGetter.GetIntegerPropertyValue("connector", defaultPort, "port"); - this.HostAddress = valuesGetter.GetStringPropertyValue("hostAddress", this.HostAddress); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/ExceptionEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/ExceptionEntity.cs deleted file mode 100644 index 24de7bee1..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/ExceptionEntity.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents exception entity. - /// - public class ExceptionEntity - { - /// - /// Exception message. - /// - public string message { get; set; } - - /// - /// Exception object. - /// - public System.Exception exception { get; set; } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/FileDescriptionEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/FileDescriptionEntity.cs deleted file mode 100644 index f510f7da6..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/FileDescriptionEntity.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents file or directory. - /// - public class FileDescriptionEntity - { - /// - /// Absolute path to the file/directory. - /// - public string guid{ get; set; } - - /// - /// Name of the file/directory. - /// - public string name{ get; set; } - - /// - /// File or directory flag. - /// - public bool isDirectory{ get; set; } - - /// - /// File size. - /// - public long size{ get; set; } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/LoadDocumentEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/LoadDocumentEntity.cs deleted file mode 100644 index bebe74a1b..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/LoadDocumentEntity.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Newtonsoft.Json; -using System.Collections.Generic; - -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents document properties and its pages collection. - /// - public class LoadDocumentEntity - { - /// - /// Document absolute path. - /// - [JsonProperty] - private string guid; - - /// - /// Collection of the document pages with their data. - /// - [JsonProperty] - private List pages = new List(); - - /// - /// Document print allowed flag. - /// - [JsonProperty] - private bool printAllowed = true; - - /// - /// Document show grid lines flag (for Excel files). - /// - [JsonProperty] - private bool showGridLines = true; - - public void SetPrintAllowed(bool allowed) - { - this.printAllowed = allowed; - } - - public bool GetPrintAllowed() - { - return this.printAllowed; - } - - public void SetShowGridLines(bool show) - { - this.showGridLines = show; - } - - public bool GetShowGridLines() - { - return this.showGridLines; - } - - public void SetGuid(string guid) - { - this.guid = guid; - } - - public string GetGuid() - { - return this.guid; - } - - public void SetPages(PageDescriptionEntity page) - { - this.pages.Add(page); - } - - public List GetPages() - { - return this.pages; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/PageDescriptionEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/PageDescriptionEntity.cs deleted file mode 100644 index ad98048fd..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/PageDescriptionEntity.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Newtonsoft.Json; - -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents document page data, dimensions and rotation angle. - /// - public class PageDescriptionEntity - { - /// - /// Page width. - /// - public double width{ get; set; } - - /// - /// Page height. - /// - public double height{ get; set; } - - /// - /// Page number. - /// - public int number{ get; set; } - - /// - /// Page rotation angle. - /// - public int angle { get; set; } - - /// - /// Page content data. - /// - [JsonProperty] - private string data; - - /// - /// Sheet name. - /// - public string sheetName { get; set; } - - public void SetData(string data) - { - this.data = data; - } - - public string GetData() - { - return this.data; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/PostedDataEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/PostedDataEntity.cs deleted file mode 100644 index 1308da0b6..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/PostedDataEntity.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; - -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, representes document with its pages - /// posted from the front-end. - /// - public class PostedDataEntity - { - /// - /// Absolute path to the document. - /// - public string guid { get; set; } - - /// - /// Document password. - /// - public string password { get; set; } - - /// - /// Page number. - /// - public int page { get; set; } - - /// - /// Page rotation angle. - /// - public int angle { get; set; } - - /// - /// Collection of the document pages with their data. - /// - public List pages { get; set; } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs b/Demos/MVC/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs deleted file mode 100644 index 7728e8493..000000000 --- a/Demos/MVC/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GroupDocs.Viewer.MVC.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents uploaded document by its absolute path. - /// - public class UploadedDocumentEntity - { - /// - /// Absolute path to the uploaded document. - /// - public string guid { get; set; } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Resources/Resources.cs b/Demos/MVC/src/Products/Common/Resources/Resources.cs deleted file mode 100644 index 6539e76e8..000000000 --- a/Demos/MVC/src/Products/Common/Resources/Resources.cs +++ /dev/null @@ -1,90 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Common.Entity.Web; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Common.Resources -{ - /// - /// Provides methods for generating uploaded files names and exception entities. - /// - public static class Resources - { - /// - /// Get free file name for uploaded file if such file already exists - /// - /// Directory where to search files - /// Uploaded file name - /// - public static string GetFreeFileName(string directory, string fileName) - { - string resultFileName = ""; - try - { - // get all files from the directory - string[] listOfFiles = Directory.GetFiles(directory); - for (int i = 0; i < listOfFiles.Length; i++) - { - // check if file with current name already exists - int number = i + 1; - string newFileName = Path.GetFileNameWithoutExtension(fileName) + "-Copy(" + number + ")." + Path.GetExtension(fileName); - resultFileName = Path.Combine(directory, newFileName); - if (File.Exists(resultFileName)) - { - continue; - } - else - { - break; - } - } - } - catch (System.Exception e) - { - throw e; - } - return resultFileName; - } - - /// - /// Generate exception - /// - /// Exception - /// ExceptionEntity - public static ExceptionEntity GenerateException(System.Exception ex) - { - // Initiate Exception entity - ExceptionEntity exceptionEntity = new ExceptionEntity(); - // set exception data - exceptionEntity.message = ex.Message; - exceptionEntity.exception = ex; - return exceptionEntity; - } - - /// - /// Generate exception for password error - /// - /// Exception - /// string - /// ExceptionEntity - public static ExceptionEntity GenerateException(System.Exception ex, string password) - { - // Initiate exception - ExceptionEntity exceptionEntity = new ExceptionEntity(); - // Check if exception message contains password and password is empty - if (ex.Message.Contains("password") && string.IsNullOrEmpty(password)) - { - exceptionEntity.message = "Password Required"; - } - // Check if exception contains password and password is set - else if (ex.Message.Contains("password") && !string.IsNullOrEmpty(password)) - { - exceptionEntity.message = "Incorrect password"; - } - else - { - exceptionEntity.message = ex.Message; - exceptionEntity.exception = ex; - } - return exceptionEntity; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Util/Comparator/FileDateComparator.cs b/Demos/MVC/src/Products/Common/Util/Comparator/FileDateComparator.cs deleted file mode 100644 index fe01eb62e..000000000 --- a/Demos/MVC/src/Products/Common/Util/Comparator/FileDateComparator.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Common.Util.Comparator -{ - /// - /// FileDateComparator. - /// - public class FileDateComparator : IComparer - { - /// - /// Compare file creation dates. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = File.GetCreationTime(x).ToString(CultureInfo.InvariantCulture); - string strExt2 = File.GetCreationTime(y).ToString(CultureInfo.InvariantCulture); - - if (string.Equals(strExt1, strExt2, StringComparison.Ordinal)) - { - return string.Compare(x, y, false, CultureInfo.InvariantCulture); - } - else - { - return string.Compare(strExt1, strExt2, false, CultureInfo.InvariantCulture); - } - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Util/Comparator/FileNameComparator.cs b/Demos/MVC/src/Products/Common/Util/Comparator/FileNameComparator.cs deleted file mode 100644 index f37c7120b..000000000 --- a/Demos/MVC/src/Products/Common/Util/Comparator/FileNameComparator.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Common.Util.Comparator -{ - /// - /// FileNameComparator. - /// - public class FileNameComparator : IComparer - { - /// - /// Compare file names. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = Path.GetFileName(x); - string strExt2 = Path.GetFileName(y); - - if (string.Equals(strExt1, strExt2, StringComparison.Ordinal)) - { - return string.Compare(x, y, false, CultureInfo.InvariantCulture); - } - else - { - return string.Compare(strExt1, strExt2, false, CultureInfo.InvariantCulture); - } - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Util/Comparator/FileTypeComparator.cs b/Demos/MVC/src/Products/Common/Util/Comparator/FileTypeComparator.cs deleted file mode 100644 index 4be21cdc6..000000000 --- a/Demos/MVC/src/Products/Common/Util/Comparator/FileTypeComparator.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Common.Util.Comparator -{ - /// - /// FileTypeComparator. - /// - public class FileTypeComparator : IComparer - { - /// - /// Compare file types. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = Path.GetExtension(x); - string strExt2 = Path.GetExtension(y); - - if (string.Equals(strExt1, strExt2, StringComparison.Ordinal)) - { - return string.Compare(x, y, false, CultureInfo.InvariantCulture); - } - else - { - return string.Compare(strExt1, strExt2, false, CultureInfo.InvariantCulture); - } - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Util/Directory/IDirectoryUtils.cs b/Demos/MVC/src/Products/Common/Util/Directory/IDirectoryUtils.cs deleted file mode 100644 index 8a71aa9a7..000000000 --- a/Demos/MVC/src/Products/Common/Util/Directory/IDirectoryUtils.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace GroupDocs.Viewer.MVC.Products.Common.Util.Directory -{ - /// - /// IDirectoryUtils. - /// - public interface IDirectoryUtils - { - string GetPath(); - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Common/Util/Parser/YamlParser.cs b/Demos/MVC/src/Products/Common/Util/Parser/YamlParser.cs deleted file mode 100644 index 90d1cb3fe..000000000 --- a/Demos/MVC/src/Products/Common/Util/Parser/YamlParser.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Specialized; -using System.IO; -using System.Reflection; -using YamlDotNet.Serialization; - -namespace GroupDocs.Viewer.MVC.Products.Common.Util.Parser -{ - public class YamlParser - { - private static string YamlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "configuration.yml"); - private readonly dynamic ConfiguationData; - - public YamlParser() - { - if (File.Exists(YamlPath)) - { - using (var reader = new StringReader(File.ReadAllText(YamlPath))) - { - var deserializer = new DeserializerBuilder().Build(); - var yamlObject = deserializer.Deserialize(reader); - - var serializer = new SerializerBuilder() - .JsonCompatible() - .Build(); - - this.ConfiguationData = serializer.Serialize(yamlObject); - } - } - } - - public dynamic GetConfiguration(string configurationSectionName) { - dynamic productConfiguration = null; - if (this.ConfiguationData != null) - { - productConfiguration = JsonConvert.DeserializeObject(this.ConfiguationData)[configurationSectionName]; - } - - return productConfiguration; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/CacheExtensions.cs b/Demos/MVC/src/Products/Viewer/Cache/CacheExtensions.cs deleted file mode 100644 index 23b0959cb..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/CacheExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - /// - /// CacheExtensions. - /// - internal static class CacheExtensions - { - /// - /// Gets the entry associated with this key if present or acquires and sets the entry if not present. - /// - /// Type of entry. - /// The cache. - /// A key identifying the requested entry. - /// The method which returns entry. - /// The entry associated with this key if present or acquires and sets the entry if not present. - public static TEntry GetValue(this IViewerCache cache, string key, Func acquire) - { - TEntry entry; - if (!cache.TryGetValue(key, out entry)) - { - entry = acquire(); - cache.Set(key, entry); - } - - return entry; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/CrossProcessLock.cs b/Demos/MVC/src/Products/Viewer/Cache/CrossProcessLock.cs deleted file mode 100644 index 87abec5a3..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/CrossProcessLock.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Security.AccessControl; -using System.Security.Principal; -using System.Threading; -using GroupDocs.Viewer.Exceptions; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - sealed class CrossProcessLock : IDisposable - { - private const int MaxMutexIdLength = 260; - private readonly Mutex mutex; - private readonly bool isMutexOwner; - - /// - /// Initializes a new instance of the class. - /// - /// The file path. - public CrossProcessLock(string path) - { - string mutexId = this.GetMutexId(path); - MutexSecurity mutexSecurity = this.GetMutexSecurity(); - try - { - bool createdNew; - this.mutex = new Mutex(false, mutexId, out createdNew, mutexSecurity); - - try - { - this.isMutexOwner = this.mutex.WaitOne(10 * 60 * 1000); - } - catch (AbandonedMutexException) - { - // NOTE: Log the fact the mutex was abandoned in another process, it will still get acquired - } - } - catch (WaitHandleCannotBeOpenedException ex) - { - // the mutex cannot be opened, probably because a Win32 object of a different - // type with the same name already exists. - throw new GroupDocsViewerException("Mutex can't be opened: " + ex.Message); - } - catch (UnauthorizedAccessException ex) - { - // the mutex exists, but the current process or thread token does not - // have permission to open the mutex with SYNCHRONIZE | MUTEX_MODIFY rights. - throw new GroupDocsViewerException("Current process does not have permission to open the mutex: " + ex.Message); - } - } - - /// - /// Releases mutex. - /// - public void Dispose() - { - if (this.mutex != null) - { - if (this.isMutexOwner) - { - this.mutex.ReleaseMutex(); - } - - this.mutex.Close(); - } - } - - private MutexSecurity GetMutexSecurity() - { - SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null); - MutexAccessRule allowEveryone = new MutexAccessRule(everyone, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); - MutexSecurity mutexSecurity = new MutexSecurity(); - mutexSecurity.AddAccessRule(allowEveryone); - - return mutexSecurity; - } - - private string GetMutexId(string path) - { - string normalized = path.Replace("\\", "_"); - - string mutexId = normalized; - if (mutexId.Length < MaxMutexIdLength) - { - return mutexId; - } - - int maxPathLength = MaxMutexIdLength; - - string trimmedPath = normalized.Length > maxPathLength - ? normalized.Substring(normalized.Length - maxPathLength) - : normalized; - - return trimmedPath; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/FileViewerCache.cs b/Demos/MVC/src/Products/Viewer/Cache/FileViewerCache.cs deleted file mode 100644 index 79d6a9d7c..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/FileViewerCache.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.Threading; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - internal class FileViewerCache : IViewerCache - { - private readonly TimeSpan waitTimeout = TimeSpan.FromMilliseconds(100); - - /// - /// Gets the Relative or absolute path to the cache folder. - /// - public string CachePath { get; } - - /// - /// Gets the sub-folder to append to the . - /// - public string CacheSubFolder { get; } - - /// - /// Initializes a new instance of the class. - /// - /// Relative or absolute path where document cache will be stored. - /// The sub-folder to append to . - /// Thrown when is null. - /// Thrown when is null. - public FileViewerCache(string cachePath, string cacheSubFolder) - { - if (cachePath == null) - { - throw new ArgumentNullException(nameof(cachePath)); - } - - if (cacheSubFolder == null) - { - throw new ArgumentNullException(nameof(cacheSubFolder)); - } - - this.CachePath = cachePath; - this.CacheSubFolder = cacheSubFolder; - } - - /// - /// Serializes data to the local disk. - /// - /// An unique identifier for the cache entry. - /// The object to serialize. - public void Set(string key, object value) - { - if (value == null) - { - return; - } - - string filePath = this.GetCacheFilePath(key); - - Stream src = value as Stream; - if (src != null) - { - using (FileStream dst = this.GetStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - src.Position = 0; - this.CopyStream(src, dst); - } - } - else - { - using (FileStream stream = this.GetStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Serialize(stream, value); - } - } - } - - /// - /// Deserializes data associated with this key if present. - /// - /// A key identifying the requested entry. - /// True if the key was found. - public T GetValue(string key) - { - string cacheFilePath = this.GetCacheFilePath(key); - T value = typeof(T) == typeof(Stream) - ? (T)this.ReadStream(cacheFilePath) - : (T)this.Deserialize(cacheFilePath); - - return value; - } - - /// - /// Deserializes data associated with this key if present. - /// - /// A key identifying the requested entry. - /// The located value or null. - /// True if the key was found. - public bool TryGetValue(string key, out T value) - { - string cacheFilePath = this.GetCacheFilePath(key); - - if (File.Exists(cacheFilePath)) - { - value = typeof(T) == typeof(Stream) - ? (T)this.ReadStream(cacheFilePath) - : (T)this.Deserialize(cacheFilePath); - - return true; - } - - value = default(T); - return false; - } - - private object ReadStream(string cacheFilePath) - { - return this.GetStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); - } - - private object Deserialize(string cachePath) - { - object data; - using (FileStream stream = this.GetStream(cachePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Binder = new IgnoreAssemblyVersionSerializationBinder(); - - try - { - data = formatter.Deserialize(stream); - } - catch (SerializationException) - { - data = null; - } - } - - return data; - } - - public string GetCacheFilePath(string key) - { - string folderPath = Path.Combine(this.CachePath, this.CacheSubFolder); - string filePath = Path.Combine(folderPath, key); - - if (!Directory.Exists(folderPath)) - { - Directory.CreateDirectory(folderPath); - } - - return filePath; - } - - public bool Contains(string key) - { - string file = Path.Combine(this.CachePath, this.CacheSubFolder, key); - return File.Exists(file); - } - - private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) - { - FileStream stream = null; - TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); - TimeSpan totalTime = new TimeSpan(); - - while (stream == null) - { - try - { - stream = File.Open(path, mode, access, share); - } - catch (IOException) - { - Thread.Sleep(interval); - totalTime += interval; - - if (this.waitTimeout.Ticks != 0 && totalTime > this.waitTimeout) - { - throw; - } - } - } - - return stream; - } - - private void CopyStream(Stream src, Stream dst) - { - const int bufferSize = 81920; //NOTE: taken from System.IO - byte[] buffer = new byte[bufferSize]; - int read; - while ((read = src.Read(buffer, 0, buffer.Length)) != 0) - { - dst.Write(buffer, 0, read); - } - } - - private class IgnoreAssemblyVersionSerializationBinder : SerializationBinder - { - public override Type BindToType(string assemblyName, string typeName) - { - string assembly = Assembly.GetAssembly(typeof(GroupDocs.Viewer.Viewer)).FullName; - Type type = Type.GetType($"{typeName}, {assembly}"); - - return type; - } - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/HtmlViewer.cs b/Demos/MVC/src/Products/Viewer/Cache/HtmlViewer.cs deleted file mode 100644 index 722ad9bef..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/HtmlViewer.cs +++ /dev/null @@ -1,207 +0,0 @@ -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using System; -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - class HtmlViewer : IDisposable, ICustomViewer - { - private readonly string filePath; - private readonly IViewerCache cache; - - private readonly GroupDocs.Viewer.Viewer viewer; - private readonly HtmlViewOptions htmlViewOptions; - private readonly PdfViewOptions pdfViewOptions; - private readonly ViewInfoOptions viewInfoOptions; - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - public HtmlViewer(string filePath, IViewerCache cache, LoadOptions loadOptions, int pageNumber = -1, int newAngle = 0) - { - this.cache = cache; - this.filePath = filePath; - this.viewer = new GroupDocs.Viewer.Viewer(filePath, loadOptions); - this.htmlViewOptions = this.CreateHtmlViewOptions(pageNumber, newAngle); - this.pdfViewOptions = this.CreatePdfViewOptions(); - this.viewInfoOptions = ViewInfoOptions.FromHtmlViewOptions(this.htmlViewOptions); - } - - public GroupDocs.Viewer.Viewer GetViewer() - { - return this.viewer; - } - - private HtmlViewOptions CreateHtmlViewOptions(int passedPageNumber = -1, int newAngle = 0) - { - HtmlViewOptions htmlViewOptions = HtmlViewOptions.ForExternalResources( - pageNumber => - { - string fileName = $"p{pageNumber}.html"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }, - (pageNumber, resource) => - { - string fileName = $"p{pageNumber}_{resource.FileName}"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }, - (pageNumber, resource) => - { - var urlPrefix = "/viewer/resources/" + Path.GetFileName(this.filePath).Replace(".", "_"); - return $"{urlPrefix}/p{ pageNumber}_{ resource.FileName}"; - }); - - htmlViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - htmlViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - htmlViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - htmlViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(htmlViewOptions); - - if (passedPageNumber >= 0 && newAngle != 0) - { - Rotation rotationAngle = GetRotationByAngle(newAngle); - htmlViewOptions.RotatePage(passedPageNumber, rotationAngle); - } - - return htmlViewOptions; - } - - private PdfViewOptions CreatePdfViewOptions() - { - PdfViewOptions pdfViewOptions = new PdfViewOptions( - () => - { - string fileName = "f.pdf"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - pdfViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - pdfViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - pdfViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - pdfViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(pdfViewOptions); - - return pdfViewOptions; - } - - private static Rotation GetRotationByAngle(int newAngle) - { - switch (newAngle) - { - case 90: - return Rotation.On90Degree; - case 180: - return Rotation.On180Degree; - case 270: - return Rotation.On270Degree; - default: - return Rotation.On90Degree; - } - } - - public void CreateCache() - { - ViewInfo viewInfo = this.GetViewInfo(); - - using (new CrossProcessLock(this.filePath)) - { - int[] missingPages = this.GetPagesMissingFromCache(viewInfo.Pages); - - if (missingPages.Length > 0) - { - this.viewer.View(this.htmlViewOptions, missingPages); - } - } - } - - public Stream GetPdf() - { - string cacheKey = "f.pdf"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - this.viewer.View(this.pdfViewOptions); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - public void Dispose() - { - this.viewer?.Dispose(); - } - - private static void SetWatermarkOptions(ViewOptions options) - { - Watermark watermark = null; - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetWatermarkText())) - { - // Set watermark properties - watermark = new Watermark(globalConfiguration.Viewer.GetWatermarkText()) - { - Color = System.Drawing.Color.Blue, - Position = Position.Diagonal, - }; - } - - if (watermark != null) - { - options.Watermark = watermark; - } - } - - public ViewInfo GetViewInfo() - { - string cacheKey = "view_info.dat"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - return this.cache.GetValue(cacheKey, () => this.ReadViewInfo()); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - private ViewInfo ReadViewInfo() - { - ViewInfo viewInfo = this.viewer.GetViewInfo(this.viewInfoOptions); - return viewInfo; - } - - private int[] GetPagesMissingFromCache(IList pages) - { - List missingPages = new List(); - foreach (Page page in pages) - { - string pageKey = $"p{page.Number}.html"; - if (!this.cache.Contains(pageKey)) - { - missingPages.Add(page.Number); - } - } - - return missingPages.ToArray(); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/ICustomViewer.cs b/Demos/MVC/src/Products/Viewer/Cache/ICustomViewer.cs deleted file mode 100644 index dbb09fab5..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/ICustomViewer.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.IO; -using GroupDocs.Viewer.Results; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - interface ICustomViewer - { - GroupDocs.Viewer.Viewer GetViewer(); - - void CreateCache(); - - Stream GetPdf(); - - ViewInfo GetViewInfo(); - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/IViewerCache.cs b/Demos/MVC/src/Products/Viewer/Cache/IViewerCache.cs deleted file mode 100644 index 6fd22ce52..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/IViewerCache.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - /// - /// Defines methods required for storing rendered document and document resources сache. - /// - interface IViewerCache - { - /// - /// The Relative or absolute path to the cache folder. - /// - string CachePath { get; } - - /// - /// The sub-folder to append to the . - /// - string CacheSubFolder { get; } - - /// - /// Inserts a cache entry into the cache. - /// - /// A unique identifier for the cache entry. - /// The object to insert. - void Set(string key, object value); - - - T GetValue(string key); - - /// - /// Gets the entry associated with this key if present. - /// - /// Type of entry. - /// A key identifying the requested entry. - /// The located value or null. - /// True if the key was found. - bool TryGetValue(string key, out TEntry value); - - /// - /// Gets cache file path;. - /// - /// The cache file key. - /// Cache file path. - string GetCacheFilePath(string key); - - bool Contains(string key); - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Cache/PngViewer.cs b/Demos/MVC/src/Products/Viewer/Cache/PngViewer.cs deleted file mode 100644 index 9a253ea0e..000000000 --- a/Demos/MVC/src/Products/Viewer/Cache/PngViewer.cs +++ /dev/null @@ -1,191 +0,0 @@ -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using System; -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Cache -{ - class PngViewer : IDisposable, ICustomViewer - { - private readonly string filePath; - private readonly IViewerCache cache; - - private readonly GroupDocs.Viewer.Viewer viewer; - private readonly PngViewOptions pngViewOptions; - private readonly PdfViewOptions pdfViewOptions; - private readonly ViewInfoOptions viewInfoOptions; - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - public PngViewer(string filePath, IViewerCache cache, LoadOptions loadOptions, int pageNumber = -1, int newAngle = 0) - { - this.cache = cache; - this.filePath = filePath; - this.viewer = new GroupDocs.Viewer.Viewer(filePath, loadOptions); - this.pngViewOptions = this.CreatePngViewOptions(pageNumber, newAngle); - this.pdfViewOptions = this.CreatePdfViewOptions(); - this.viewInfoOptions = ViewInfoOptions.FromPngViewOptions(this.pngViewOptions); - } - - public GroupDocs.Viewer.Viewer GetViewer() - { - return this.viewer; - } - - private PngViewOptions CreatePngViewOptions(int passedPageNumber = -1, int newAngle = 0) - { - PngViewOptions createdPngViewOptions = new PngViewOptions(pageNumber => - { - string fileName = $"p{pageNumber}.png"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - if (passedPageNumber >= 0 && newAngle != 0) - { - Rotation rotationAngle = GetRotationByAngle(newAngle); - createdPngViewOptions.RotatePage(passedPageNumber, rotationAngle); - } - - createdPngViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(createdPngViewOptions); - - return createdPngViewOptions; - } - - private PdfViewOptions CreatePdfViewOptions() - { - PdfViewOptions pdfViewOptions = new PdfViewOptions( - () => - { - string fileName = "f.pdf"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - pdfViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - pdfViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - pdfViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - pdfViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(pdfViewOptions); - - return pdfViewOptions; - } - - private static Rotation GetRotationByAngle(int newAngle) - { - switch (newAngle) - { - case 90: - return Rotation.On90Degree; - case 180: - return Rotation.On180Degree; - case 270: - return Rotation.On270Degree; - default: - return Rotation.On90Degree; - } - } - - public void CreateCache() - { - ViewInfo viewInfo = this.GetViewInfo(); - - using (new CrossProcessLock(this.filePath)) - { - int[] missingPages = this.GetPagesMissingFromCache(viewInfo.Pages); - - if (missingPages.Length > 0) - { - this.viewer.View(this.pngViewOptions, missingPages); - } - } - } - - public Stream GetPdf() - { - string cacheKey = "f.pdf"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - this.viewer.View(this.pdfViewOptions); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - public void Dispose() - { - this.viewer?.Dispose(); - } - - private static void SetWatermarkOptions(ViewOptions options) - { - Watermark watermark = null; - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetWatermarkText())) - { - // Set watermark properties - watermark = new Watermark(globalConfiguration.Viewer.GetWatermarkText()) - { - Color = System.Drawing.Color.Blue, - Position = Position.Diagonal, - }; - } - - if (watermark != null) - { - options.Watermark = watermark; - } - } - - public ViewInfo GetViewInfo() - { - string cacheKey = "view_info.dat"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - return this.cache.GetValue(cacheKey, () => this.ReadViewInfo()); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - private ViewInfo ReadViewInfo() - { - ViewInfo viewInfo = this.viewer.GetViewInfo(this.viewInfoOptions); - return viewInfo; - } - - private int[] GetPagesMissingFromCache(IList pages) - { - List missingPages = new List(); - foreach (Page page in pages) - { - string pageKey = $"p{page.Number}.png"; - if (!this.cache.Contains(pageKey)) - { - missingPages.Add(page.Number); - } - } - - return missingPages.ToArray(); - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Config/ViewerConfiguration.cs b/Demos/MVC/src/Products/Viewer/Config/ViewerConfiguration.cs deleted file mode 100644 index 746473777..000000000 --- a/Demos/MVC/src/Products/Viewer/Config/ViewerConfiguration.cs +++ /dev/null @@ -1,337 +0,0 @@ -using GroupDocs.Viewer.MVC.Products.Common.Config; -using GroupDocs.Viewer.MVC.Products.Common.Util.Parser; -using Newtonsoft.Json; -using System; -using System.IO; -using System.Linq; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Config -{ - /// - /// ViewerConfiguration. - /// - public class ViewerConfiguration : CommonConfiguration - { - [JsonProperty] - private string filesDirectory = "DocumentSamples/Viewer"; - - [JsonProperty] - private string fontsDirectory = string.Empty; - - [JsonProperty] - private string defaultDocument = string.Empty; - - [JsonProperty] - private string watermarkText = string.Empty; - - [JsonProperty] - private int preloadPageCount; - - [JsonProperty] - private bool zoom = true; - - [JsonProperty] - private bool search = true; - - [JsonProperty] - private bool thumbnails = true; - - [JsonProperty] - private bool rotate = true; - - [JsonProperty] - private bool htmlMode = true; - - [JsonProperty] - private bool cache = true; - - [JsonProperty] - private bool saveRotateState = true; - - [JsonProperty] - private bool printAllowed = true; - - [JsonProperty] - private bool showGridLines = true; - - [JsonProperty] - private string cacheFolderName = "cache"; - - [JsonProperty] - private bool showLanguageMenu = true; - - [JsonProperty] - private string defaultLanguage = "en"; - - [JsonProperty] - private string[] supportedLanguages = new string[] - { - "ar", // العربية - "ca", // Català - "cs", // Čeština - "da", // Dansk - "de", // Deutsch - "el", // Ελληνικά - "en", // English - "es", // Español - "fil", // Filipino - "fr", // Français - "he", // עברית - "hi", // हिन्दी - "id", // Indonesia - "it", // Italiano - "ja", // 日本語 - "kk", // Қазақ Тілі - "ko", // 한국어 - "ms", // Melayu - "nl", // Nederlands - "pl", // Polski - "pt", // Português - "ro", // Română - "ru", // Русский - "sv", // Svenska - "vi", // Tiếng Việt - "th", // ไทย - "tr", // Türkçe - "uk", // Українська - "zh-hans", // 中文 - "zh-hant", // 中文 - }; - - /// - /// Initializes a new instance of the class. - /// - public ViewerConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("viewer"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - - // get Viewer configuration section from the web.config - this.filesDirectory = valuesGetter.GetStringPropertyValue("filesDirectory", this.filesDirectory); - if (!IsFullPath(this.filesDirectory)) - { - this.filesDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.filesDirectory); - if (!Directory.Exists(this.filesDirectory)) - { - Directory.CreateDirectory(this.filesDirectory); - } - } - - this.cacheFolderName = valuesGetter.GetStringPropertyValue("cacheFolderName", this.cacheFolderName); - if (!IsFullPath(this.cacheFolderName)) - { - var cacheDirectory = Path.Combine(this.filesDirectory, this.cacheFolderName); - if (!Directory.Exists(cacheDirectory)) - { - Directory.CreateDirectory(cacheDirectory); - } - } - - this.fontsDirectory = valuesGetter.GetStringPropertyValue("fontsDirectory", this.fontsDirectory); - this.defaultDocument = valuesGetter.GetStringPropertyValue("defaultDocument", this.defaultDocument); - this.preloadPageCount = valuesGetter.GetIntegerPropertyValue("preloadPageCount", this.preloadPageCount); - this.zoom = valuesGetter.GetBooleanPropertyValue("zoom", this.zoom); - this.search = valuesGetter.GetBooleanPropertyValue("search", this.search); - this.thumbnails = valuesGetter.GetBooleanPropertyValue("thumbnails", this.thumbnails); - this.rotate = valuesGetter.GetBooleanPropertyValue("rotate", this.rotate); - this.htmlMode = valuesGetter.GetBooleanPropertyValue("htmlMode", this.htmlMode); - this.cache = valuesGetter.GetBooleanPropertyValue("cache", this.cache); - this.saveRotateState = valuesGetter.GetBooleanPropertyValue("saveRotateState", this.saveRotateState); - this.watermarkText = valuesGetter.GetStringPropertyValue("watermarkText", this.watermarkText); - this.printAllowed = valuesGetter.GetBooleanPropertyValue("printAllowed", this.printAllowed); - this.showGridLines = valuesGetter.GetBooleanPropertyValue("showGridLines", this.showGridLines); - this.showLanguageMenu = valuesGetter.GetBooleanPropertyValue("showLanguageMenu", this.showLanguageMenu); - this.defaultLanguage = valuesGetter.GetStringPropertyValue("defaultLanguage", this.defaultLanguage); - this.supportedLanguages = valuesGetter.GetStringArrayPropertyValue("supportedLanguages", this.supportedLanguages); - } - - private static bool IsFullPath(string path) - { - return !string.IsNullOrWhiteSpace(path) - && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1 - && Path.IsPathRooted(path) - && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal); - } - - public void SetFilesDirectory(string filesDirectory) - { - this.filesDirectory = filesDirectory; - } - - public string GetFilesDirectory() - { - return this.filesDirectory; - } - - public void SetCacheFolderName(string cacheFolderName) - { - this.cacheFolderName = cacheFolderName; - } - - public string GetCacheFolderName() - { - return this.cacheFolderName; - } - - public void SetFontsDirectory(string fontsDirectory) - { - this.fontsDirectory = fontsDirectory; - } - - public string GetFontsDirectory() - { - return this.fontsDirectory; - } - - public void SetDefaultDocument(string defaultDocument) - { - this.defaultDocument = defaultDocument; - } - - public string GetDefaultDocument() - { - return this.defaultDocument; - } - - public void SetPreloadPageCount(int preloadPageCount) - { - this.preloadPageCount = preloadPageCount; - } - - public int GetPreloadPageCount() - { - return this.preloadPageCount; - } - - public void SetIsZoom(bool isZoom) - { - this.zoom = isZoom; - } - - public bool GetIsZoom() - { - return this.zoom; - } - - public void SetIsSearch(bool isSearch) - { - this.search = isSearch; - } - - public bool GetIsSearch() - { - return this.search; - } - - public void SetIsThumbnails(bool isThumbnails) - { - this.thumbnails = isThumbnails; - } - - public bool GetIsThumbnails() - { - return this.thumbnails; - } - - public void SetIsRotate(bool isRotate) - { - this.rotate = isRotate; - } - - public bool GetIsRotate() - { - return this.rotate; - } - - public void SetIsHtmlMode(bool isHtmlMode) - { - this.htmlMode = isHtmlMode; - } - - public bool GetIsHtmlMode() - { - return this.htmlMode; - } - - public void SetCache(bool Cache) - { - this.cache = Cache; - } - - public bool GetCache() - { - return this.cache; - } - - public void SetSaveRotateState(bool saveRotateState) - { - this.saveRotateState = saveRotateState; - } - - public bool GetSaveRotateState() - { - return this.saveRotateState; - } - - public void SetWatermarkText(string watermarkText) - { - this.watermarkText = watermarkText; - } - - public string GetWatermarkText() - { - return this.watermarkText; - } - - public void SetPrintAllowed(bool printAllowed) - { - this.printAllowed = printAllowed; - } - - public bool GetPrintAllowed() - { - return this.printAllowed; - } - - public void SetShowGridLines(bool showGridLines) - { - this.showGridLines = showGridLines; - } - - public bool GetShowGridLines() - { - return this.showGridLines; - } - - public void SetShowLanguageMenu(bool showLanguageMenu) - { - this.showLanguageMenu = showLanguageMenu; - } - - public bool GetShowLanguageMenu() - { - return this.showLanguageMenu; - } - - public void SetDefaultLanguage(string defaultLanguage) - { - this.defaultLanguage = defaultLanguage; - } - - public string GetDefaultLanguage() - { - return this.defaultLanguage; - } - - public void SetSupportedLanguages(string[] supportedLanguages) - { - this.supportedLanguages = supportedLanguages; - } - - public string[] GetSupportedLanguages() - { - return this.supportedLanguages; - } - } -} diff --git a/Demos/MVC/src/Products/Viewer/Controllers/ViewerApiController.cs b/Demos/MVC/src/Products/Viewer/Controllers/ViewerApiController.cs deleted file mode 100644 index d29208fa5..000000000 --- a/Demos/MVC/src/Products/Viewer/Controllers/ViewerApiController.cs +++ /dev/null @@ -1,736 +0,0 @@ -using GroupDocs.Viewer.Exceptions; -using GroupDocs.Viewer.MVC.Products.Common.Entity.Web; -using GroupDocs.Viewer.MVC.Products.Common.Resources; -using GroupDocs.Viewer.MVC.Products.Common.Util.Comparator; -using GroupDocs.Viewer.MVC.Products.Viewer.Cache; -using GroupDocs.Viewer.MVC.Products.Viewer.Config; -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Drawing; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Web; -using System.Web.Http; -using System.Web.Http.Cors; -using System.Xml.Linq; -using WebGrease.Css.Extensions; -using LoadOptions = GroupDocs.Viewer.Options.LoadOptions; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Controllers -{ - /// - /// ViewerApiController. - /// - [EnableCors(origins: "*", headers: "*", methods: "*")] - public class ViewerApiController : ApiController - { - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - private static readonly string cachePath = Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), globalConfiguration.Viewer.GetCacheFolderName()); - - /// - /// Initializes a new instance of the class. - /// - public ViewerApiController() - { - List fontsDirectory = new List(); - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetFontsDirectory())) - { - fontsDirectory.Add(globalConfiguration.Viewer.GetFontsDirectory()); - } - } - - /// - /// Loads Viewer configuration. - /// - /// Viewer configuration. - [HttpGet] - [Route("loadConfig")] - public ViewerConfiguration LoadConfig() - { - return globalConfiguration.Viewer; - } - - /// - /// Gets all files and directories from sample directory: - /// src/DocumentSamples/Viewer/. - /// - /// List of files and directories. - [HttpPost] - [Route("loadFileTree")] - public HttpResponseMessage GetFileTree() - { - try - { - List filesList = new List(); - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetFilesDirectory())) - { - var currentPath = globalConfiguration.Viewer.GetFilesDirectory(); - List allFiles = new List(Directory.GetFiles(currentPath)); - allFiles.AddRange(Directory.GetDirectories(currentPath)); - - string cacheFolderName = globalConfiguration.Viewer.GetCacheFolderName(); - - allFiles.Sort(new FileNameComparator()); - allFiles.Sort(new FileDateComparator()); - - foreach (string file in allFiles) - { - System.IO.FileInfo fileInfo = new System.IO.FileInfo(file); - - // check if current file/folder is hidden - if (!(cacheFolderName.Equals(Path.GetFileName(file)) || - Path.GetFileName(file).StartsWith(".") || - fileInfo.Attributes.HasFlag(FileAttributes.Hidden) || - Path.GetFileName(file).Equals(Path.GetFileName(globalConfiguration.Viewer.GetFilesDirectory())))) - { - FileDescriptionEntity fileDescription = new FileDescriptionEntity - { - guid = Path.GetFullPath(file), - name = Path.GetFileName(file), - - // set is directory true/false - isDirectory = fileInfo.Attributes.HasFlag(FileAttributes.Directory), - }; - - // set file size - if (!fileDescription.isDirectory) - { - fileDescription.size = fileInfo.Length; - } - - // add object to array list - filesList.Add(fileDescription); - } - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, filesList); - } - catch (Exception ex) - { - return this.Request.CreateResponse(HttpStatusCode.OK, Resources.GenerateException(ex)); - } - } - - /// - /// Gets document pages data, dimensions and angles. - /// - /// Posted data with document guid. - /// Document pages data, dimensions and angles. - [HttpPost] - [Route("loadDocumentDescription")] - public HttpResponseMessage GetDocumentData(PostedDataEntity postedData) - { - try - { - LoadDocumentEntity loadDocumentEntity = GetDocumentPages(postedData, globalConfiguration.Viewer.GetPreloadPageCount() == 0); - - // return document description - return this.Request.CreateResponse(HttpStatusCode.OK, loadDocumentEntity); - } - catch (PasswordRequiredException ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.Forbidden, Resources.GenerateException(ex, postedData.password)); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, postedData.password)); - } - } - - /// - /// Gets document page info. - /// - /// Posted data with page number. - /// Document page info. - [HttpPost] - [Route("loadDocumentPage")] - public HttpResponseMessage GetDocumentPage(PostedDataEntity postedData) - { - string password = string.Empty; - try - { - string documentGuid = GetFilePath(postedData.guid); - int pageNumber = postedData.page; - password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - - PageDescriptionEntity page; - if (globalConfiguration.Viewer.GetIsHtmlMode()) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password))) - { - page = this.GetPageDescritpionEntity(htmlViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password))) - { - page = this.GetPageDescritpionEntity(pngViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, page); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.Forbidden, Resources.GenerateException(ex, password)); - } - } - - /// - /// Rotates specific page(s) of the document. - /// - /// Document page number to rotate and rotation angle. - /// Rotated document page object. - [HttpPost] - [Route("rotateDocumentPages")] - public HttpResponseMessage RotateDocumentPages(PostedDataEntity postedData) - { - try - { - var documentGuid = GetFilePath(postedData.guid); - var pageNumber = postedData.pages[0]; - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - // Delete page cache-files before regenerating with another angle. - var cacheFiles = Directory.GetFiles(fileCacheSubFolder).Where(f => Path.GetFileName(f).StartsWith($"p{pageNumber}")); - cacheFiles.ForEach(f => File.Delete(f)); - - // Getting new rotation angle value. - var currentAngle = GetCurrentAngle(pageNumber, Path.Combine(fileCacheSubFolder, "PagesInfo.xml")); - int newAngle = GetNewAngleValue(currentAngle, postedData.angle); - SaveChangedAngleInCache(fileCacheSubFolder, pageNumber, newAngle); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - PageDescriptionEntity page; - if (globalConfiguration.Viewer.GetIsHtmlMode()) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password), pageNumber, newAngle)) - { - page = this.GetPageDescritpionEntity(htmlViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password), pageNumber, newAngle)) - { - page = this.GetPageDescritpionEntity(pngViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, page); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex)); - } - } - - /// - /// Downloads curerntly viewed document. - /// - /// Path of the document to download. - /// Document stream as attachement. - [HttpGet] - [Route("downloadDocument")] - public HttpResponseMessage DownloadDocument(string path) - { - if (!string.IsNullOrEmpty(path)) - { - path = GetFilePath(path); - - if (File.Exists(path)) - { - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - var fileStream = new FileStream(path, FileMode.Open); - response.Content = new StreamContent(fileStream); - response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); - response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(path); - return response; - } - } - - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - - /// - /// Downloads requested resource file. - /// - /// Name of the file containing resource. - /// Name of the resource file. - /// Document stream as attachement. - [HttpGet] - [Route("resources/{guid}/{resourceName}")] - public HttpResponseMessage GetResource(string guid, string resourceName) - { - if (!string.IsNullOrEmpty(guid)) - { - var path = Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), globalConfiguration.Viewer.GetCacheFolderName()); - path = Path.Combine(path, guid); - path = Path.Combine(path, resourceName); - - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - response.Content = new StreamContent(fileStream); - var fileName = Path.GetFileName(path); - response.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(fileName)); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline"); - response.Content.Headers.ContentDisposition.FileName = fileName; - return response; - } - - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - - /// - /// Uploads document. - /// - /// Uploaded document object. - [HttpPost] - [Route("uploadDocument")] - public HttpResponseMessage UploadDocument() - { - try - { - string url = HttpContext.Current.Request.Form["url"]; - - // get documents storage path - string documentStoragePath = globalConfiguration.Viewer.GetFilesDirectory(); - bool rewrite = bool.Parse(HttpContext.Current.Request.Form["rewrite"]); - string fileSavePath = string.Empty; - if (string.IsNullOrEmpty(url)) - { - if (HttpContext.Current.Request.Files.AllKeys != null) - { - // Get the uploaded document from the Files collection - var httpPostedFile = HttpContext.Current.Request.Files["file"]; - if (httpPostedFile != null) - { - if (rewrite) - { - // Get the complete file path - fileSavePath = Path.Combine(documentStoragePath, httpPostedFile.FileName); - } - else - { - fileSavePath = Resources.GetFreeFileName(documentStoragePath, httpPostedFile.FileName); - } - - // Save the uploaded file to "UploadedFiles" folder - httpPostedFile.SaveAs(fileSavePath); - } - } - } - else - { - using (WebClient client = new WebClient()) - { - // get file name from the URL - Uri uri = new Uri(url); - string fileName = Path.GetFileName(uri.LocalPath); - if (rewrite) - { - // Get the complete file path - fileSavePath = Path.Combine(documentStoragePath, fileName); - } - else - { - fileSavePath = Resources.GetFreeFileName(documentStoragePath, fileName); - } - - // Download the Web resource and save it into the current filesystem folder. - client.DownloadFile(url, fileSavePath); - } - } - - UploadedDocumentEntity uploadedDocument = new UploadedDocumentEntity - { - guid = fileSavePath, - }; - - return this.Request.CreateResponse(HttpStatusCode.OK, uploadedDocument); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex)); - } - } - - /// - /// Loads document pages thumbnails. - /// - /// Posted data with document guid. - /// Data of all document pages. - [HttpPost] - [Route("loadThumbnails")] - public LoadDocumentEntity GetPagesThumbnails(PostedDataEntity loadDocumentRequest) - { - return GetDocumentPages(loadDocumentRequest, true); - } - - /// - /// Loads print version. - /// - /// PostedDataEntity. - /// Data of all document pages. - [HttpPost] - [Route("loadPrint")] - public HttpResponseMessage GetPrintVersion(PostedDataEntity loadDocumentRequest) - { - try - { - LoadDocumentEntity loadPrintDocument = GetDocumentPages(loadDocumentRequest, true, true); - - // return document description - return this.Request.CreateResponse(HttpStatusCode.OK, loadPrintDocument); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, loadDocumentRequest.password)); - } - } - - /// - /// Loads PDF document. - /// - /// PostedDataEntity. - /// Data of all document pages. - [HttpPost] - [Route("printPdf")] - public HttpResponseMessage PrintPdf(PostedDataEntity loadDocumentRequest) - { - try - { - Stream pdfStream = GetPdf(loadDocumentRequest); - string fileName = Path.GetFileName(loadDocumentRequest.guid); - string pdfFileName = Path.ChangeExtension(fileName, ".pdf"); - - // return document description - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - - response.Content = new StreamContent(pdfStream); - response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); - response.Content.Headers.ContentDisposition.FileName = pdfFileName; - return response; - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, loadDocumentRequest.password)); - } - } - - /// - /// Gets page dimensions and rotation angle. - /// - /// Page object. - /// Path to file with pages rotation angles data. - /// Page dimensions and rotation angle. - private static PageDescriptionEntity GetPageInfo(Page page, string pagesInfoPath) - { - int currentAngle = GetCurrentAngle(page.Number, pagesInfoPath); - - PageDescriptionEntity pageDescriptionEntity = new PageDescriptionEntity - { - number = page.Number, - - // we intentionally use the 0 here because we plan to rotate only the page background using height/width - angle = 0, - height = currentAngle == 0 || currentAngle == 180 ? page.Height : page.Width, - width = currentAngle == 0 || currentAngle == 180 ? page.Width : page.Height, - sheetName = page.Name, - }; - - return pageDescriptionEntity; - } - - /// - /// Gets page content as a string. - /// - /// Page number. - /// Document path. - /// Cache path. - /// Page content as a string. - private static string GetPageContent(int pageNumber, string documentGuid, string cachePath, bool printVersion) - { - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - - if (globalConfiguration.Viewer.GetIsHtmlMode() && !printVersion) - { - string htmlFilePath = $"{cachePath}/{fileFolderName}/p{pageNumber}.html"; - return File.ReadAllText(htmlFilePath); - } - else - { - string pngFilePath = $"{cachePath}/{fileFolderName}/p{pageNumber}.png"; - - byte[] imageBytes = null; - using (Image image = Image.FromFile(pngFilePath)) - { - using (MemoryStream m = new MemoryStream()) - { - image.Save(m, image.RawFormat); - imageBytes = m.ToArray(); - } - } - - return Convert.ToBase64String(imageBytes); - } - } - - /// - /// Gets current rotation angle of the page. - /// - /// Page number. - /// Path to file with pages rotation angles data. - /// Current rotation angle of the page. - private static int GetCurrentAngle(int pageNumber, string pagesInfoPath) - { - XDocument xdoc = XDocument.Load(pagesInfoPath); - var pageData = xdoc.Descendants()?.Elements("Number")?.Where(x => int.Parse(x.Value) == pageNumber)?.Ancestors("PageData"); - var angle = pageData?.Elements("Angle").FirstOrDefault(); - - if (angle != null) - { - return int.Parse(angle.Value); - } - - return 0; - } - - /// - /// Gets document load options used in Viewer object constructor. - /// - /// Document password. - /// Load options object. - private static LoadOptions GetLoadOptions(string password) - { - Options.LoadOptions loadOptions = new Options.LoadOptions - { - Password = password, - }; - - return loadOptions; - } - - /// - /// Saves changed page rotation angle in cache. - /// - /// Cache files path. - /// Page number. - /// New angle value. - private static void SaveChangedAngleInCache(string fileCacheSubFolder, int pageNumber, int newAngle) - { - var pagesInfoPath = Path.Combine(fileCacheSubFolder, "PagesInfo.xml"); - - if (File.Exists(pagesInfoPath)) - { - XDocument xdoc = XDocument.Load(pagesInfoPath); - var pageData = xdoc.Descendants()?.Elements("Number")?.Where(x => int.Parse(x.Value) == pageNumber)?.Ancestors("PageData"); - var angle = pageData?.Elements("Angle").FirstOrDefault(); - - if (angle != null) - { - angle.Value = newAngle.ToString(CultureInfo.InvariantCulture); - } - - xdoc.Save(pagesInfoPath); - } - } - - /// - /// Calculates new page rotation angle value. - /// - /// Current page rotation angle value. - /// Posted page rotation angle value. - /// New page rotation angle value. - private static int GetNewAngleValue(int currentAngle, int postedAngle) - { - switch (currentAngle) - { - case 0: - return postedAngle == 90 ? 90 : 270; - case 90: - return postedAngle == 90 ? 180 : 0; - case 180: - return postedAngle == 90 ? 270 : 90; - case 270: - return postedAngle == 90 ? 0 : 180; - default: - return 0; - } - } - - /// - /// Gets document pages data, dimensions and rotation angles. - /// - /// Posted data with document guid. - /// Flag to load all pages. - /// Document pages data, dimensions and rotation angles. - private LoadDocumentEntity GetDocumentPages(PostedDataEntity postedData, bool loadAllPages, bool printVersion = false) - { - // get/set parameters - string documentGuid = GetFilePath(postedData.guid); - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - if (!File.Exists(documentGuid)) - { - throw new GroupDocsViewerException("File not found."); - } - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - - LoadDocumentEntity loadDocumentEntity; - if (globalConfiguration.Viewer.GetIsHtmlMode() && !printVersion) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password))) - { - loadDocumentEntity = GetLoadDocumentEntity(loadAllPages, documentGuid, fileCacheSubFolder, htmlViewer, printVersion); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password))) - { - loadDocumentEntity = GetLoadDocumentEntity(loadAllPages, documentGuid, fileCacheSubFolder, pngViewer, printVersion); - } - } - - return loadDocumentEntity; - } - - private string GetFilePath(string filename) - { - if (Path.IsPathRooted(filename)) - return filename; - - return Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), filename); - } - - /// - /// Gets PDF data - /// - /// Posted data with document guid. - /// Document pages data, dimensions and rotation angles. - private Stream GetPdf(PostedDataEntity postedData) - { - string documentGuid = GetFilePath(postedData.guid); - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - if (!File.Exists(documentGuid)) - throw new GroupDocsViewerException("File not found."); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - LoadOptions loadOptions = GetLoadOptions(password); - - ICustomViewer viewer = globalConfiguration.Viewer.GetIsHtmlMode() - ? (ICustomViewer)new HtmlViewer(documentGuid, cache, loadOptions) - : (ICustomViewer)new PngViewer(documentGuid, cache, loadOptions); - - Stream pdfStream = viewer.GetPdf(); - return pdfStream; - } - - private static LoadDocumentEntity GetLoadDocumentEntity(bool loadAllPages, string documentGuid, string fileCacheSubFolder, ICustomViewer customViewer, bool printVersion) - { - if (loadAllPages) - { - customViewer.CreateCache(); - } - - dynamic viewInfo = customViewer.GetViewInfo(); - LoadDocumentEntity loadDocumentEntity = new LoadDocumentEntity(); - - if (!Directory.Exists(cachePath)) - { - Directory.CreateDirectory(cachePath); - } - - string pagesInfoPath; - TryCreatePagesInfoXml(fileCacheSubFolder, viewInfo, out pagesInfoPath); - - foreach (Page page in viewInfo.Pages) - { - PageDescriptionEntity pageData = GetPageInfo(page, pagesInfoPath); - if (loadAllPages) - { - pageData.SetData(GetPageContent(page.Number, documentGuid, cachePath, printVersion)); - } - - loadDocumentEntity.SetPages(pageData); - } - - loadDocumentEntity.SetGuid(documentGuid); - return loadDocumentEntity; - } - - private static void TryCreatePagesInfoXml(string fileCacheSubFolder, dynamic viewInfo, out string pagesInfoPath) - { - if (!Directory.Exists(fileCacheSubFolder)) - { - Directory.CreateDirectory(fileCacheSubFolder); - } - - pagesInfoPath = Path.Combine(fileCacheSubFolder, "PagesInfo.xml"); - - if (!File.Exists(pagesInfoPath)) - { - var xdoc = new XDocument(new XElement("Pages")); - - foreach (var page in viewInfo.Pages) - { - xdoc.Element("Pages") - .Add(new XElement( - "PageData", - new XElement("Number", page.Number), - new XElement("Angle", 0))); - } - - xdoc.Save(pagesInfoPath); - } - } - - private PageDescriptionEntity GetPageDescritpionEntity(ICustomViewer customViewer, string documentGuid, int pageNumber, string fileCacheSubFolder) - { - PageDescriptionEntity page; - customViewer.CreateCache(); - - var viewInfo = customViewer.GetViewer().GetViewInfo(ViewInfoOptions.ForHtmlView()); - page = GetPageInfo(viewInfo.Pages[pageNumber - 1], Path.Combine(fileCacheSubFolder, "PagesInfo.xml")); - page.SetData(GetPageContent(pageNumber, documentGuid, cachePath, false)); - - return page; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs b/Demos/MVC/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs deleted file mode 100644 index 6d7678d81..000000000 --- a/Demos/MVC/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs +++ /dev/null @@ -1,36 +0,0 @@ - -using Newtonsoft.Json; - -namespace GroupDocs.Viewer.MVC.Products.Viewer.Entity.Web -{ - /// - /// RotatedPageEntity. - /// - public class RotatedPageEntity - { - [JsonProperty] - private int pageNumber; - - [JsonProperty] - private string angle; - - public void SetPageNumber(int number) { - this.pageNumber = number; - } - - public int GetPageNumber() - { - return this.pageNumber; - } - - public void SetAngle(string angle) - { - this.angle = angle; - } - - public string GetAngle() - { - return this.angle; - } - } -} \ No newline at end of file diff --git a/Demos/MVC/src/Views/Viewer/Index.cshtml b/Demos/MVC/src/Views/Viewer/Index.cshtml deleted file mode 100644 index 3c3474ce6..000000000 --- a/Demos/MVC/src/Views/Viewer/Index.cshtml +++ /dev/null @@ -1,25 +0,0 @@ -@{ - GroupDocs.Viewer.MVC.Products.Common.Config.GlobalConfiguration config = new GroupDocs.Viewer.MVC.Products.Common.Config.GlobalConfiguration(); -} - - - - - - Viewer for .NET MVC - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/MVC/src/client/.editorconfig b/Demos/MVC/src/client/.editorconfig deleted file mode 100644 index 6e87a003d..000000000 --- a/Demos/MVC/src/client/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Editor configuration, see http://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/Demos/MVC/src/client/.prettierignore b/Demos/MVC/src/client/.prettierignore deleted file mode 100644 index 931aad992..000000000 --- a/Demos/MVC/src/client/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -# Add files here to ignore them from prettier formatting diff --git a/Demos/MVC/src/client/.prettierrc b/Demos/MVC/src/client/.prettierrc deleted file mode 100644 index 544138be4..000000000 --- a/Demos/MVC/src/client/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "singleQuote": true -} diff --git a/Demos/MVC/src/client/README.md b/Demos/MVC/src/client/README.md deleted file mode 100644 index b148586e6..000000000 --- a/Demos/MVC/src/client/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Client - -This project was generated using [Nx](https://nx.dev). - -

- -🔎 **Nx is a set of Angular CLI power-ups for modern development.** - -## Quick Start & Documentation - -[Nx Documentation](https://nx.dev) - -[30-minute video showing all Nx features](https://nx.dev/getting-started/what-is-nx) - -[Interactive Tutorial](https://nx.dev/tutorial/01-create-application) - -## Adding capabilities to your workspace - -Nx supports many plugins which add capabilities for developing different types of applications and different tools. - -These capabilities include generating applications, libraries, .etc as well as the devtools to test, and build projects as well. - -Below are some plugins which you can add to your workspace: - -- [Angular](https://angular.io) - - `ng add @nrwl/angular` -- [React](https://reactjs.org) - - `ng add @nrwl/react` -- Web (no framework frontends) - - `ng add @nrwl/web` -- [Nest](https://nestjs.com) - - `ng add @nrwl/nest` -- [Express](https://expressjs.com) - - `ng add @nrwl/express` -- [Node](https://nodejs.org) - - `ng add @nrwl/node` - -## Generate an application - -Run `ng g @nrwl/angular:app my-app` to generate an application. - -> You can use any of the plugins above to generate applications as well. - -When using Nx, you can create multiple applications and libraries in the same workspace. - -## Generate a library - -Run `ng g @nrwl/angular:lib my-lib` to generate a library. - -> You can also use any of the plugins above to generate libraries as well. - -Libraries are sharable across libraries and applications. They can be imported from `@client/mylib`. - -## Development server - -Run `ng serve my-app` for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files. - -## Code scaffolding - -Run `ng g component my-component --project=my-app` to generate a new component. - -## Build - -Run `ng build my-app` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. - -## Running unit tests - -Run `ng test my-app` to execute the unit tests via [Jest](https://jestjs.io). - -Run `npm run affected:test` to execute the unit tests affected by a change. - -## Running end-to-end tests - -Run `ng e2e my-app` to execute the end-to-end tests via [Cypress](https://www.cypress.io). - -Run `npm run affected:e2e` to execute the end-to-end tests affected by a change. - -## Understand your workspace - -Run `npm run dep-graph` to see a diagram of the dependencies of your projects. - -## Further help - -Visit the [Nx Documentation](https://nx.dev) to learn more. diff --git a/Demos/MVC/src/client/angular.json b/Demos/MVC/src/client/angular.json deleted file mode 100644 index b25917fa2..000000000 --- a/Demos/MVC/src/client/angular.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "", - "projects": { - "viewer": { - "projectType": "application", - "schematics": { - "@nrwl/workspace:component": { - "style": "less" - } - }, - "root": "apps/viewer", - "sourceRoot": "apps/viewer/src", - "prefix": "client", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "../resources/viewer", - "index": "apps/viewer/src/index.html", - "main": "apps/viewer/src/main.ts", - "polyfills": "apps/viewer/src/polyfills.ts", - "tsConfig": "apps/viewer/tsconfig.app.json", - "assets": ["apps/viewer/src/favicon.ico", "apps/viewer/src/assets"], - "styles": ["apps/viewer/src/styles.less"], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "apps/viewer/src/environments/environment.ts", - "with": "apps/viewer/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "aot": true, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "viewer:build" - }, - "configurations": { - "production": { - "browserTarget": "viewer:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "viewer:build" - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "apps/viewer/tsconfig.app.json", - "apps/viewer/tsconfig.spec.json" - ], - "exclude": ["**/node_modules/**", "!apps/viewer/**"] - } - }, - "test": { - "builder": "@nrwl/jest:jest", - "options": { - "jestConfig": "apps/viewer/jest.config.js", - "tsConfig": "apps/viewer/tsconfig.spec.json", - "setupFile": "apps/viewer/src/test-setup.ts" - } - } - } - }, - "viewer-e2e": { - "root": "apps/viewer-e2e", - "sourceRoot": "apps/viewer-e2e/src", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/viewer-e2e/cypress.json", - "tsConfig": "apps/viewer-e2e/tsconfig.e2e.json", - "devServerTarget": "viewer:serve" - }, - "configurations": { - "production": { - "devServerTarget": "viewer:serve:production" - } - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": "apps/viewer-e2e/tsconfig.e2e.json", - "exclude": ["**/node_modules/**", "!apps/viewer-e2e/**"] - } - } - } - } - }, - "cli": { - "warnings": { - "typescriptMismatch": false, - "versionMismatch": false - }, - "defaultCollection": "@nrwl/angular" - }, - "schematics": { - "@nrwl/angular:application": { - "unitTestRunner": "jest", - "e2eTestRunner": "cypress" - }, - "@nrwl/angular:library": { - "unitTestRunner": "jest" - } - }, - "defaultProject": "viewer" -} diff --git a/Demos/MVC/src/client/apps/.gitkeep b/Demos/MVC/src/client/apps/.gitkeep deleted file mode 100644 index 8b1378917..000000000 --- a/Demos/MVC/src/client/apps/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Demos/MVC/src/client/apps/viewer-e2e/cypress.json b/Demos/MVC/src/client/apps/viewer-e2e/cypress.json deleted file mode 100644 index 6df3fe526..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/cypress.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "pluginsFile": "./src/plugins/index", - "supportFile": false, - "video": true, - "videosFolder": "../../dist/cypress/apps/viewer-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/viewer-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/fixtures/example.json b/Demos/MVC/src/client/apps/viewer-e2e/src/fixtures/example.json deleted file mode 100644 index 294cbed6c..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/fixtures/example.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io" -} diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/integration/app.spec.ts b/Demos/MVC/src/client/apps/viewer-e2e/src/integration/app.spec.ts deleted file mode 100644 index 29f39937b..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/integration/app.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { getGreeting } from '../support/app.po'; - -describe('viewer', () => { - beforeEach(() => cy.visit('/')); - - it('should display welcome message', () => { - getGreeting().contains('Welcome to viewer!'); - }); -}); diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/plugins/index.js b/Demos/MVC/src/client/apps/viewer-e2e/src/plugins/index.js deleted file mode 100644 index bc34d630e..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/plugins/index.js +++ /dev/null @@ -1,22 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor'); - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - - // Preprocess Typescript - on('file:preprocessor', preprocessTypescript(config)); -}; diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/support/app.po.ts b/Demos/MVC/src/client/apps/viewer-e2e/src/support/app.po.ts deleted file mode 100644 index 329342469..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/support/app.po.ts +++ /dev/null @@ -1 +0,0 @@ -export const getGreeting = () => cy.get('h1'); diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/support/commands.ts b/Demos/MVC/src/client/apps/viewer-e2e/src/support/commands.ts deleted file mode 100644 index ca4d256f3..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/support/commands.ts +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/Demos/MVC/src/client/apps/viewer-e2e/src/support/index.ts b/Demos/MVC/src/client/apps/viewer-e2e/src/support/index.ts deleted file mode 100644 index 3d469a6b6..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/src/support/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; diff --git a/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.e2e.json b/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.e2e.json deleted file mode 100644 index 629b4c1cc..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.e2e.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "sourceMap": false, - "outDir": "../../dist/out-tsc" - }, - "include": ["src/**/*.ts"] -} diff --git a/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.json b/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.json deleted file mode 100644 index ee6531bc0..000000000 --- a/Demos/MVC/src/client/apps/viewer-e2e/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["cypress", "node"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/MVC/src/client/apps/viewer/browserslist b/Demos/MVC/src/client/apps/viewer/browserslist deleted file mode 100644 index 80848532e..000000000 --- a/Demos/MVC/src/client/apps/viewer/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/Demos/MVC/src/client/apps/viewer/jest.config.js b/Demos/MVC/src/client/apps/viewer/jest.config.js deleted file mode 100644 index faba4818c..000000000 --- a/Demos/MVC/src/client/apps/viewer/jest.config.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - name: 'viewer', - preset: '../../jest.config.js', - coverageDirectory: '../../coverage/apps/viewer', - snapshotSerializers: [ - 'jest-preset-angular/AngularSnapshotSerializer.js', - 'jest-preset-angular/HTMLCommentSerializer.js' - ] -}; diff --git a/Demos/MVC/src/client/apps/viewer/src/app/app.component.html b/Demos/MVC/src/client/apps/viewer/src/app/app.component.html deleted file mode 100644 index 6c494d302..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/app/app.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Demos/MVC/src/client/apps/viewer/src/app/app.component.less b/Demos/MVC/src/client/apps/viewer/src/app/app.component.less deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/MVC/src/client/apps/viewer/src/app/app.component.spec.ts b/Demos/MVC/src/client/apps/viewer/src/app/app.component.spec.ts deleted file mode 100644 index 9a05e0434..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/app/app.component.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { TestBed, async } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent] - }).compileComponents(); - })); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have as title 'viewer'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('viewer'); - }); - - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain( - 'Welcome to viewer!' - ); - }); -}); diff --git a/Demos/MVC/src/client/apps/viewer/src/app/app.component.ts b/Demos/MVC/src/client/apps/viewer/src/app/app.component.ts deleted file mode 100644 index b67ea4d57..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'client-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.less'] -}) -export class AppComponent { - title = 'viewer'; -} diff --git a/Demos/MVC/src/client/apps/viewer/src/app/app.module.ts b/Demos/MVC/src/client/apps/viewer/src/app/app.module.ts deleted file mode 100644 index d0d3ed55f..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/app/app.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; - -import { AppComponent } from './app.component'; -import {ViewerModule} from "@groupdocs.examples.angular/viewer"; - -@NgModule({ - declarations: [AppComponent], - imports: [BrowserModule, - ViewerModule], - providers: [], - bootstrap: [AppComponent] -}) -export class AppModule {} diff --git a/Demos/MVC/src/client/apps/viewer/src/favicon.ico b/Demos/MVC/src/client/apps/viewer/src/favicon.ico deleted file mode 100644 index 8081c7cea..000000000 Binary files a/Demos/MVC/src/client/apps/viewer/src/favicon.ico and /dev/null differ diff --git a/Demos/MVC/src/client/apps/viewer/src/index.html b/Demos/MVC/src/client/apps/viewer/src/index.html deleted file mode 100644 index 4675b4d4e..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Viewer - - - - - - - - - diff --git a/Demos/MVC/src/client/apps/viewer/src/test-setup.ts b/Demos/MVC/src/client/apps/viewer/src/test-setup.ts deleted file mode 100644 index 8d88704e8..000000000 --- a/Demos/MVC/src/client/apps/viewer/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular'; diff --git a/Demos/MVC/src/client/apps/viewer/tsconfig.app.json b/Demos/MVC/src/client/apps/viewer/tsconfig.app.json deleted file mode 100644 index 827b63017..000000000 --- a/Demos/MVC/src/client/apps/viewer/tsconfig.app.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": [] - }, - "include": ["**/*.ts"], - "exclude": ["src/test-setup.ts", "**/*.spec.ts"] -} diff --git a/Demos/MVC/src/client/apps/viewer/tsconfig.json b/Demos/MVC/src/client/apps/viewer/tsconfig.json deleted file mode 100644 index e5decd5e2..000000000 --- a/Demos/MVC/src/client/apps/viewer/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["node", "jest"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/MVC/src/client/apps/viewer/tsconfig.spec.json b/Demos/MVC/src/client/apps/viewer/tsconfig.spec.json deleted file mode 100644 index cfff29a54..000000000 --- a/Demos/MVC/src/client/apps/viewer/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] -} diff --git a/Demos/MVC/src/client/apps/viewer/tslint.json b/Demos/MVC/src/client/apps/viewer/tslint.json deleted file mode 100644 index df7583477..000000000 --- a/Demos/MVC/src/client/apps/viewer/tslint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tslint.json", - "rules": { - "directive-selector": [true, "attribute", "client", "camelCase"], - "component-selector": [true, "element", "client", "kebab-case"] - } -} diff --git a/Demos/MVC/src/client/jest.config.js b/Demos/MVC/src/client/jest.config.js deleted file mode 100644 index caba6c4f7..000000000 --- a/Demos/MVC/src/client/jest.config.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest' - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - collectCoverage: true, - coverageReporters: ['html'] -}; diff --git a/Demos/MVC/src/client/libs/.gitkeep b/Demos/MVC/src/client/libs/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/MVC/src/client/nx.json b/Demos/MVC/src/client/nx.json deleted file mode 100644 index 11d643c59..000000000 --- a/Demos/MVC/src/client/nx.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "npmScope": "client", - "implicitDependencies": { - "angular.json": "*", - "package.json": "*", - "tsconfig.json": "*", - "tslint.json": "*", - "nx.json": "*" - }, - "projects": { - "viewer-e2e": { - "tags": [] - }, - "viewer": { - "tags": [] - } - } -} diff --git a/Demos/MVC/src/client/package.json b/Demos/MVC/src/client/package.json deleted file mode 100644 index e0c3aac6e..000000000 --- a/Demos/MVC/src/client/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "client", - "version": "0.0.0", - "license": "MIT", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "..\\..\\packages\\Node-Kit.11.1.0.1\\node\\win\\node.exe .\\node_modules\\@angular\\cli\\bin\\ng build", - "test": "ng test", - "lint": "nx lint && ng lint", - "e2e": "ng e2e", - "affected:apps": "nx affected:apps", - "affected:libs": "nx affected:libs", - "affected:build": "nx affected:build", - "affected:e2e": "nx affected:e2e", - "affected:test": "nx affected:test", - "affected:lint": "nx affected:lint", - "affected:dep-graph": "nx affected:dep-graph", - "affected": "nx affected", - "format": "nx format:write", - "format:write": "nx format:write", - "format:check": "nx format:check", - "update": "ng update @nrwl/workspace", - "update:check": "ng update", - "workspace-schematic": "nx workspace-schematic", - "dep-graph": "nx dep-graph", - "help": "nx help" - }, - "private": true, - "dependencies": { - "@angular/animations": "^8.0.0", - "@angular/common": "^8.0.0", - "@angular/compiler": "^8.0.0", - "@angular/core": "^8.0.0", - "@angular/forms": "^8.0.0", - "@angular/platform-browser": "^8.0.0", - "@angular/platform-browser-dynamic": "^8.0.0", - "@angular/router": "^8.0.0", - "core-js": "^2.5.4", - "rxjs": "~6.4.0", - "zone.js": "^0.9.1", - "@nrwl/angular": "^8.2.0", - "@groupdocs.examples.angular/viewer": "^0.8.82" - }, - "devDependencies": { - "cypress": "~3.3.1", - "@nrwl/cypress": "8.2.0", - "@nrwl/jest": "8.2.0", - "jest": "24.1.0", - "@types/jest": "24.0.9", - "ts-jest": "24.0.0", - "jest-preset-angular": "7.0.0", - "@angular/compiler-cli": "^8.0.0", - "@angular/language-service": "^8.0.0", - "@angular-devkit/build-angular": "^0.800.0", - "codelyzer": "~5.0.1", - "@nrwl/workspace": "8.2.0", - "@types/node": "~8.9.4", - "dotenv": "6.2.0", - "ts-node": "~7.0.0", - "tslint": "~5.11.0", - "typescript": "~3.4.5", - "prettier": "1.16.4", - "@angular/cli": "8.0.0" - } -} diff --git a/Demos/MVC/src/client/tools/schematics/.gitkeep b/Demos/MVC/src/client/tools/schematics/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/MVC/src/client/tools/tsconfig.tools.json b/Demos/MVC/src/client/tools/tsconfig.tools.json deleted file mode 100644 index 82bd1f098..000000000 --- a/Demos/MVC/src/client/tools/tsconfig.tools.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/out-tsc/tools", - "rootDir": ".", - "module": "commonjs", - "target": "es5", - "types": ["node"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/MVC/src/client/tsconfig.json b/Demos/MVC/src/client/tsconfig.json deleted file mode 100644 index a5099b580..000000000 --- a/Demos/MVC/src/client/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "rootDir": ".", - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "importHelpers": true, - "target": "es2015", - "module": "esnext", - "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "dom"], - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "baseUrl": ".", - "paths": {} - }, - "exclude": ["node_modules", "tmp"] -} diff --git a/Demos/MVC/src/client/tslint.json b/Demos/MVC/src/client/tslint.json deleted file mode 100644 index 2533001b6..000000000 --- a/Demos/MVC/src/client/tslint.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "rulesDirectory": [ - "node_modules/@nrwl/workspace/src/tslint", - "node_modules/codelyzer" - ], - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "deprecation": { - "severity": "warn" - }, - "forin": true, - "import-blacklist": [true, "rxjs/Rx"], - "interface-over-type-literal": true, - "member-access": false, - "member-ordering": [ - true, - { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] - } - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": [true, "ignore-params"], - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "prefer-const": true, - "radix": true, - "triple-equals": [true, "allow-null-check"], - "unified-signatures": true, - "variable-name": false, - "nx-enforce-module-boundaries": [ - true, - { - "allow": [], - "depConstraints": [ - { - "sourceTag": "*", - "onlyDependOnLibsWithTags": ["*"] - } - ] - } - ], - "directive-selector": [true, "attribute", "app", "camelCase"], - "component-selector": [true, "element", "app", "kebab-case"], - "no-conflicting-lifecycle": true, - "no-host-metadata-property": true, - "no-input-rename": true, - "no-inputs-metadata-property": true, - "no-output-native": true, - "no-output-on-prefix": true, - "no-output-rename": true, - "no-outputs-metadata-property": true, - "template-banana-in-box": true, - "template-no-negated-async": true, - "use-lifecycle-interface": true, - "use-pipe-transform-interface": true - } -} diff --git a/Demos/MVC/src/configuration.yml b/Demos/MVC/src/configuration.yml deleted file mode 100644 index d2462f7b7..000000000 --- a/Demos/MVC/src/configuration.yml +++ /dev/null @@ -1,103 +0,0 @@ -################################################ -# Server configurations -################################################ -server: - type: simple - applicationContextPath: / - adminContextPath: /admin - connector: - type: http - port: 8080 - - -################################################ -# Application (global) configurations -################################################ -application: - # License path - # Absolute path to GroupDocs license file - licensePath: 'Licenses/GroupDocs.Viewer.NET.lic' - -################################################ -# Common configurations -################################################ -common: - # File rewriting on document uploading - # Set false to keep both files - # Set true to replace files with same name - rewrite: true - # Page navigation - # Set false to disable document navigation (go to next, previous, last and first page) - pageSelector: true - # Document download - # Set false to disable document download - download: true - # Document upload - # Set false to disable document upload - upload: true - # Document print - # Set false to disable document print - print: true - # File browser - # Set false to disable document browse - browse: true - # Set false to disable right mouse click - enableRightClick: true - -################################################ -# GroupDocs.Viewer configurations -################################################ -viewer: - # Files directory path - # Absolute path to files directory - filesDirectory: 'DocumentSamples/Viewer' - # Cache folder name - # Relative path to cache directory - cacheFolderName: 'cache' - # Fonts path - # Absolute path to custom fonts directory - fontsDirectory: '' - # Default document - # Absolute path to default document - defaultDocument: '' - # Pages preload - # How many pages from a document should be loaded, remaining pages will be loaded on page scrolling - # Set 0 to load all pages at once - preloadPageCount: 0 - # HTML rendering mode - # Set false for image mode - # Set true for HTML mode - htmlMode: true - # Document zoom - # Set false to disable document zooming - zoom: true - # Document search - # Set false to disable document text search - search: true - # Thumbnails - # Set false to disable thumbnails - thumbnails: true - # Page rotation - # Set false to disable pages rotation - rotate: true - # Using cache - # Set true to enable cache - cache: true - # Set true to enable page rotation saving - saveRotateState: true - # Enter text which will be used as a watermark - watermarkText: "" - # Print secured documents mode - # Set false to ignore document print security - # Set true to check document print security - printAllowed: true - # Adds/removes grid lines in the excel documents - # presentation regardless of whether they are in - # the document itself or not - showGridLines: true - # Shows/hides language menu - showLanguageMenu: true - # Default UI language - defaultLanguage: 'en' - # Supported languages - supportedLanguages: ["ar", "ca", "cs", "da", "de", "el", "en", "es", "fil", "fr", "he", "hi", "id", "it", "ja", "kk", "ko", "ms", "nl", "pl", "pt", "ro", "ru", "sv", "vi", "th", "tr", "uk", "zh-hans", "zh-hant" ] \ No newline at end of file diff --git a/Demos/MVC/src/package.json b/Demos/MVC/src/package.json deleted file mode 100644 index 068947ba5..000000000 --- a/Demos/MVC/src/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "groupdocs.viewer-for-.net-mvc", - "version": "1.0.0", - "description": "![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC/master/src/Resources/viewer/images/banner.png \"GroupDocs.Viewer\")\r # GroupDocs.Viewer for .NET MVC Example\r ###### version 1.8.0", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "gulp build" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC.git" - }, - "author": "", - "license": "MIT", - "bugs": { - "url": "https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC/issues" - }, - "homepage": "https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC#readme" -} diff --git a/Demos/MVC/src/packages.config b/Demos/MVC/src/packages.config deleted file mode 100644 index 6d8aa69fe..000000000 --- a/Demos/MVC/src/packages.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/GroupDocs.Viewer.MVC.Test.csproj b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/GroupDocs.Viewer.MVC.Test.csproj deleted file mode 100644 index 63fa73a5c..000000000 --- a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/GroupDocs.Viewer.MVC.Test.csproj +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - Debug - AnyCPU - {C8F2EDB6-BD6C-465F-B59F-2CEA33BD7FE6} - Library - Properties - GroupDocs.Total.MVC.Test - GroupDocs.Total.MVC.Test - v4.6.1 - 512 - true - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - ..\..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll - - - ..\..\packages\GroupDocs.Viewer.22.5.0\lib\net40\GroupDocs.Viewer.dll - True - - - ..\..\packages\Huygens.1.4.5\lib\net46\Huygens.dll - - - ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - ..\..\packages\Mvc2Futures.2.0.50217.0\lib\Microsoft.Web.Mvc.dll - - - ..\..\packages\Moq.4.10.1\lib\net45\Moq.dll - - - .\MvcContrib.TestHelper.dll - - - ..\..\packages\MvcRouteTester.1.2.1\lib\net40\MvcRouteTester.dll - - - ..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll - - - ..\..\packages\NUnit.3.13.2\lib\net45\nunit.framework.dll - True - - - - - - ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - ..\..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - ..\..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll - True - True - - - - ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll - - - ..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll - - - ..\..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - ..\..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll - - - ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll - - - ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll - - - ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll - - - - - - - - - ..\..\packages\WebGrease.1.6.0\lib\WebGrease.dll - - - - - - - - - - - - - - - - {a33ca8b0-a193-40a3-a86a-90ff444ee878} - GroupDocs.Viewer.MVC - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - - - - - - \ No newline at end of file diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/MvcContrib.TestHelper.dll b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/MvcContrib.TestHelper.dll deleted file mode 100644 index a7877eae4..000000000 Binary files a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/MvcContrib.TestHelper.dll and /dev/null differ diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/Properties/AssemblyInfo.cs b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/Properties/AssemblyInfo.cs deleted file mode 100644 index 0ba20d807..000000000 --- a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Общие сведения об этой сборке предоставляются следующим набором -// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения, -// связанные со сборкой. -[assembly: AssemblyTitle("GroupDocs.Viewer.MVC.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GroupDocs.Viewer.MVC.Test")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми -// для компонентов COM. Если необходимо обратиться к типу в этой сборке через -// COM, задайте атрибуту ComVisible значение TRUE для этого типа. -[assembly: ComVisible(false)] - -// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM -[assembly: Guid("c8f2edb6-bd6c-465f-b59f-2cea33bd7fe6")] - -// Сведения о версии сборки состоят из следующих четырех значений: -// -// Основной номер версии -// Дополнительный номер версии -// Номер сборки -// Редакция -// -// Можно задать все значения или принять номер сборки и номер редакции по умолчанию. -// используя "*", как показано ниже: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/ViewerControllerTest.cs b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/ViewerControllerTest.cs deleted file mode 100644 index 3d6ad07fb..000000000 --- a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/ViewerControllerTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -using GroupDocs.Viewer.MVC.Controllers; -using NUnit.Framework; -using System.Web.Routing; -using MvcContrib.TestHelper; -using Huygens; -using System; -using GroupDocs.Viewer.MVC; -using System.Collections.Generic; - -namespace GroupDocs.Viewer.MVC.Test -{ - [TestFixture] - public class ViewerControllerTest - { - - [SetUp] - public void TestInitialize() - { - RouteConfig.RegisterRoutes(RouteTable.Routes); - } - - [TearDown] - public void TearDown() - { - RouteTable.Routes.Clear(); - } - - [Test] - public void ViewStatusTest() - { - string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../../src"; - using (var server = new DirectServer(path)) - { - var request = new SerialisableRequest - { - Method = "GET", - RequestUri = "/viewer", - Content = null - }; - - var result = server.DirectCall(request); - Assert.That(result.StatusCode, Is.EqualTo(200)); - } - } - - [Test] - public void ViewMapControllerTest() - { - "~/viewer".Route().ShouldMapTo(x => x.Index()); - } - - [Test] - public void FileTreeStatusCodeTest() - { - string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../../src"; - using (var server = new DirectServer(path)) - { - var request = new SerialisableRequest - { - Method = "POST", - RequestUri = "/loadfiletree", - Content = null, - Headers = new Dictionary{ - { "Content-Type", "application/json"} - } - }; - - var result = server.DirectCall(request); - Assert.That(result.StatusCode, Is.EqualTo(200)); - } - } - } -} diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/app.config b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/app.config deleted file mode 100644 index 873ea1e7b..000000000 --- a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/app.config +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/packages.config b/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/packages.config deleted file mode 100644 index dbfd4340c..000000000 --- a/Demos/MVC/tests/GroupDocs.Viewer.MVC.Test/packages.config +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WPF/README.md b/Demos/WPF/README.md index 15fda75f9..dde400ca0 100644 --- a/Demos/WPF/README.md +++ b/Demos/WPF/README.md @@ -1,52 +1,25 @@ ![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") + # GroupDocs.Viewer for .NET WPF Example -###### version 1.0.0 -[![GitHub license](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms.svg)](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/blob/master/Demos/WPF/LICENSE) + +![GitHub](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET) + +In order to demonstrate [GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) reach and powerful features we prepared **document viewer** demo. Which can be used as a standalone application or easily integrated into your project. + +NOTE: without a license application will run in trial mode, [purchase a license](https://purchase.groupdocs.com/buy) or [request a temporary license](https://purchase.groupdocs.com/temporary-license). ## System Requirements - .NET Core 3.1 -- Visual Studio 2019 - - -## Document Viewer API for .NET WPF - -[GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) API allows you to view over 170 document formats including **DOCX**, **PDF**, **PPT**, **XLS**, among many others without any additional dependencies. Thanks to its flexible configuration it can be configured to **view documents as images or as HTML5**. - -In order to demonstrate GroupDocs.Viewer for .NET reach and powerful features we prepared a modern **document viewer** WPF UI example. Which can be used as a standalone application or easily integrated into your project. - -**Note:** without a license application will run in trial mode, purchase [GroupDocs.Viewer for .NET license](https://purchase.groupdocs.com/order-online-step-1-of-8.aspx) or request [GroupDocs.Viewer for .NET temporary license](https://purchase.groupdocs.com/temporary-license). - -## Supported document Formats - -| Family | Formats | -| --------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------- | -| Archive formats | `ZIP`, `TAR`, `BZ2`, `RAR`, `GZIP` | -| Apple formats | `Numbers` | -| PDF formats | `PDF`, `XPS`, `OXPS`, `TEX` | -| CAD formats | `DXF`, `DWG` , `DWT`, `STL`, `IFC`,`DWF` , `DWFX`, `DGN`, `PLT`,`CF2`,`OBJ`, `HPG`, `IGS` | -| Microsoft Word | `DOC`, `DOCM` , `DOCX`, `DOT`, `DOTM`, `DOTX`,`RTF` | -| Microsoft Excel | `XLS`, `XLSB`, `XLSM`, `XLSX`, `XLT`, `XLTM`, `XLTX`,`Excel 2003 XML`,`XLAM` | -| Microsoft PowerPoint | `PPT`, `POT`, `POTM`, `POTX`, `PPS`, `PPSM`, `PPSX`, `PPTM`, `PPTX` | -| Microsoft Visio | `VSD`,`VSDX`,`VSDM`,`VDW`, `VDX`, `VSDX`, `VSS`,`VSSX`,`VSSM`,`VST`,`VSTX`, `VSX`, `VTX`,`VSTM` | -| Microsoft Project | `MPP`, `MPT`,`MPX` | -| Help files | `CHM` | -| Email formats | `EML`, `EMLX`, `MSG`, `NSF`, `MBOX`, `PST`,`OST`, `VCF` | -| OpenDocument Formats | `ODT`, `ODP`,`FODP`, `ODS`,`FODS`, `OTT`,`OTS`,`ODG`,`FODG`,`OTG`,`OTP`,`SXC` | -| Plain Text File | `TXT`,`TSV` | -| Comma-Separated Values | `CSV` | -| HyperText Markup Language | `HTML`, `MHT`, `MHTML`, `SVG`,`SVGZ` | -| Extensible Markup Language | `XML`,`XML`, `XPS` | -| AutoCAD Drawing File Format | `DGN`, `DWG`, `DXF` | -| Image files | `BMP`, `CAL`, `DCX`,`CGM`,`PCL`,`PSB`, `DIB`, `EMF`,`EMZ`,`WEBP`,`DNG`,`CDR`,`CMX`, `GIF`,
`JP2`, `JPG`,`JPF`,`JPM`,`J2C`,`J2K`,`JPC`,`JPX`,`MIL`, `MIL`, `PCD`, `PCT`, `PCX`, `PNG`,
`Animated PNG`, `PSD`,`PS`, `RAS`, `TGA`,`TIFF`,`WMF`,`WMZ`,`EPS`, `AI` | -| Electronic publication | `EPUB`,`MOBI`,`DJVU` | -| Windows Icon | `ICO` | -| Medical image files | `DCM` | -| Programming Language Formats | `AS`, `AS3`, `ASM`, `BAT`, `C`, `CC`, `CMAKE`, `CPP`, `CS`,`VB`, `CSS`, `CXX`, `DIFF`, `ERB`,
`GROOVY`, `H`,`HAML`, `HH`, `JAVA`, `JS`, `JSON`, `LESS`, `LOG`, `M`, `MAKE`, `MD`, `ML`,
`MM`, `PHP`, `PL`, `PROPERTIES`, `PY`, `RB`, `RST`, `SASS`, `SCALA`, `SCM`, `SCRIPT`,
`SH`, `SML`, `SQL`, `VIM`, `YAML`| - -## Demo Video +- Visual Studio 2022 + +## Supported Document Formats + +GroupDocs.Viewer for .NET enables you to render Microsoft Word, Microsoft Excel, Microsoft PowerPoint, and many more file types in HTML, PDF, PNG, and JPEG formats. The complete list of the supported document and file formats can be found in the [Supported document formats](https://docs.groupdocs.com/viewer/net/supported-document-formats/) documentation article. + +## Demo Animation

- +

## Features @@ -61,26 +34,27 @@ You can run this sample by one of following methods #### Build from source -Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WPF/archive/main.zip) from github or clone this repository. +Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/archive/refs/heads/master.zip) from github or clone this repository. ```bash -git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WPF +git clone git@github.com:groupdocs-viewer/GroupDocs.Viewer-for-.NET.git ``` -Open solution in the VisualStudio. -Restore packages and build. -Run compiled application +Navigate to `Demos\WPF\src` and open solution in the VisualStudio. Run the application ## License + The MIT License (MIT). -Please have a look at the LICENSE.md for more details +Please have a look at the [LICENSE](LICENSE) for more details -## GroupDocs Document Viewer on other platforms/frameworks +## More Demo Projects -- JAVA DropWizard [Document Viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Dropwizard) -- JAVA Spring boot [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Spring) -- .NET MVC [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC) -- .NET Windows Forms [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WinForms) +- [Java Dropwizard Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) +- [Java Spring Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [ASP.NET Core Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Core) +- [ASP.NET MVC Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%MVC) +- [ASP.NET Web Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Web%20Forms) +- [Windows Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/Windows%20Forms) -[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/family) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) +[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Examples) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/WPF/appveyor.yml b/Demos/WPF/appveyor.yml deleted file mode 100644 index 80c053167..000000000 --- a/Demos/WPF/appveyor.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 1.0.{build} -before_build: -- cmd: cd src -- cmd: nuget restore -build: - verbosity: minimal \ No newline at end of file diff --git a/Demos/WPF/Resources/groupdocs.viewer.wpf.gif b/Demos/WPF/docs/groupdocs.viewer.wpf.gif similarity index 100% rename from Demos/WPF/Resources/groupdocs.viewer.wpf.gif rename to Demos/WPF/docs/groupdocs.viewer.wpf.gif diff --git a/Demos/WPF/src/GroupDocs.Viewer.WPF.csproj b/Demos/WPF/src/GroupDocs.Viewer.WPF.csproj index cfd2a842b..1178170dc 100644 --- a/Demos/WPF/src/GroupDocs.Viewer.WPF.csproj +++ b/Demos/WPF/src/GroupDocs.Viewer.WPF.csproj @@ -41,7 +41,7 @@ - + \ No newline at end of file diff --git a/Demos/WPF/src/Storage/Files/flowchart.vsdx b/Demos/WPF/src/Storage/Files/flowchart.vsdx new file mode 100644 index 000000000..12db7e009 Binary files /dev/null and b/Demos/WPF/src/Storage/Files/flowchart.vsdx differ diff --git a/Demos/WPF/src/Storage/Files/groupdocs.pptx b/Demos/WPF/src/Storage/Files/groupdocs.pptx new file mode 100644 index 000000000..d94d696dd Binary files /dev/null and b/Demos/WPF/src/Storage/Files/groupdocs.pptx differ diff --git a/Demos/WPF/src/Storage/Files/house-plan.dwg b/Demos/WPF/src/Storage/Files/house-plan.dwg new file mode 100644 index 000000000..ff07697b5 Binary files /dev/null and b/Demos/WPF/src/Storage/Files/house-plan.dwg differ diff --git a/Demos/WPF/src/Storage/Files/invoice.xlsx b/Demos/WPF/src/Storage/Files/invoice.xlsx new file mode 100644 index 000000000..f223175b2 Binary files /dev/null and b/Demos/WPF/src/Storage/Files/invoice.xlsx differ diff --git a/Demos/WPF/src/Storage/Files/resume.docx b/Demos/WPF/src/Storage/Files/resume.docx new file mode 100644 index 000000000..1d9f67edb Binary files /dev/null and b/Demos/WPF/src/Storage/Files/resume.docx differ diff --git a/Demos/WPF/src/Storage/Files/resume.pdf b/Demos/WPF/src/Storage/Files/resume.pdf new file mode 100644 index 000000000..ef4cae4db Binary files /dev/null and b/Demos/WPF/src/Storage/Files/resume.pdf differ diff --git a/Demos/WPF/src/Storage/Files/software-development-plan.mpp b/Demos/WPF/src/Storage/Files/software-development-plan.mpp new file mode 100644 index 000000000..5e48341a2 Binary files /dev/null and b/Demos/WPF/src/Storage/Files/software-development-plan.mpp differ diff --git a/Demos/WPF/src/Storage/Files/vector-image.svg b/Demos/WPF/src/Storage/Files/vector-image.svg new file mode 100644 index 000000000..6df8640de --- /dev/null +++ b/Demos/WPF/src/Storage/Files/vector-image.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/WebForms/GroupDocs.Viewer.WebForms.sln b/Demos/WebForms/GroupDocs.Viewer.WebForms.sln deleted file mode 100644 index 48f6c34aa..000000000 --- a/Demos/WebForms/GroupDocs.Viewer.WebForms.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31205.134 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.WebForms", "src\GroupDocs.Viewer.WebForms.csproj", "{7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.WebForms.Test", "tests\GroupDocs.Viewer.WebForms.Test\GroupDocs.Viewer.WebForms.Test.csproj", "{C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC}.Release|Any CPU.Build.0 = Release|Any CPU - {C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {09183FBD-9D9E-4AAF-A5BC-EEAE3C37023A} - EndGlobalSection -EndGlobal diff --git a/Demos/WebForms/README.md b/Demos/WebForms/README.md deleted file mode 100644 index 692f5a904..000000000 --- a/Demos/WebForms/README.md +++ /dev/null @@ -1,149 +0,0 @@ -![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") -# GroupDocs.Viewer for .NET Web.Forms Example -###### version 1.18.0 - -[![GitHub license](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms.svg)](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/blob/master/LICENSE) - -## System Requirements -- .NET Framework 4.5 -- Visual Studio 2015 - - -## Document Viewer API for .NET Web.Forms - -[GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) API allows you to view over 170 document formats including **DOCX**, **PDF**, **PPT**, **XLS**, among many others without any additional dependencies. Thanks to its flexible configuration it can be configured to **view documents as images or as HTML5**. - - -In order to demonstrate GroupDocs.Viewer for Java reach and powerful features we prepared a modern **document viewer** front-end web UI example. Which can be used as a standalone application or easily integrated into your project. - -**Note:** without a license application will run in trial mode, purchase [GroupDocs.Viewer for .NET license](https://purchase.groupdocs.com/order-online-step-1-of-8.aspx) or request [GroupDocs.Viewer for .NET temporary license](https://purchase.groupdocs.com/temporary-license). - -## Supported document Formats - -| Family | Formats | -| --------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------- | -| Archive formats | `ZIP`, `TAR`, `BZ2`, `RAR`, `GZIP` | -| Apple formats | `Numbers` | -| PDF formats | `PDF`, `XPS`, `OXPS`, `TEX` | -| CAD formats | `DXF`, `DWG` , `DWT`, `STL`, `IFC`,`DWF` , `DWFX`, `DGN`, `PLT`,`CF2`,`OBJ`, `HPG`, `IGS` | -| Microsoft Word | `DOC`, `DOCM` , `DOCX`, `DOT`, `DOTM`, `DOTX`,`RTF` | -| Microsoft Excel | `XLS`, `XLSB`, `XLSM`, `XLSX`, `XLT`, `XLTM`, `XLTX`,`Excel 2003 XML`,`XLAM` | -| Microsoft PowerPoint | `PPT`, `POT`, `POTM`, `POTX`, `PPS`, `PPSM`, `PPSX`, `PPTM`, `PPTX` | -| Microsoft Visio | `VSD`,`VSDX`,`VSDM`,`VDW`, `VDX`, `VSDX`, `VSS`,`VSSX`,`VSSM`,`VST`,`VSTX`, `VSX`, `VTX`,`VSTM` | -| Microsoft Project | `MPP`, `MPT`,`MPX` | -| Help files | `CHM` | -| Email formats | `EML`, `EMLX`, `MSG`, `NSF`, `MBOX`, `PST`,`OST`, `VCF` | -| OpenDocument Formats | `ODT`, `ODP`,`FODP`, `ODS`,`FODS`, `OTT`,`OTS`,`ODG`,`FODG`,`OTG`,`OTP`,`SXC` | -| Plain Text File | `TXT`,`TSV` | -| Comma-Separated Values | `CSV` | -| HyperText Markup Language | `HTML`, `MHT`, `MHTML`, `SVG`,`SVGZ` | -| Extensible Markup Language | `XML`,`XML`, `XPS` | -| AutoCAD Drawing File Format | `DGN`, `DWG`, `DXF` | -| Image files | `BMP`, `CAL`, `DCX`,`CGM`,`PCL`,`PSB`, `DIB`, `EMF`,`EMZ`,`WEBP`,`DNG`,`CDR`,`CMX`, `GIF`,
`JP2`, `JPG`,`JPF`,`JPM`,`J2C`,`J2K`,`JPC`,`JPX`,`MIL`, `MIL`, `PCD`, `PCT`, `PCX`, `PNG`,
`Animated PNG`, `PSD`,`PS`, `RAS`, `TGA`,`TIFF`,`WMF`,`WMZ`,`EPS`, `AI` | -| Electronic publication | `EPUB`,`MOBI`,`DJVU` | -| Windows Icon | `ICO` | -| Medical image files | `DCM` | -| Programming Language Formats | `AS`, `AS3`, `ASM`, `BAT`, `C`, `CC`, `CMAKE`, `CPP`, `CS`,`VB`, `CSS`, `CXX`, `DIFF`, `ERB`,
`GROOVY`, `H`,`HAML`, `HH`, `JAVA`, `JS`, `JSON`, `LESS`, `LOG`, `M`, `MAKE`, `MD`, `ML`,
`MM`, `PHP`, `PL`, `PROPERTIES`, `PY`, `RB`, `RST`, `SASS`, `SCALA`, `SCM`, `SCRIPT`,
`SH`, `SML`, `SQL`, `VIM`, `YAML`| | - -## Demo Video - -

- - - -

- -## Features -- Clean, modern and intuitive design -- Easily switchable colour theme (create your own colour theme in 5 minutes) -- Responsive design -- Mobile support (open application on any mobile device) -- Support over 170+ documents and image formats including Word, Excel, PowerPoint -- View in HTML or image modes -- Fully customizable navigation panel -- Open password protected documents -- Text searching & highlighting -- Download documents -- Upload documents -- Print document -- Rotate pages -- Zoom in/out documents without quality loss in HTML mode -- Thumbnails -- Smooth page navigation -- Smooth document scrolling -- Preload pages for faster document rendering -- Multi-language support for displaying errors -- Display two or more pages side by side (when zooming out) -- Cross-browser support (Safari, Chrome, Opera, Firefox) -- Cross-platform support (Windows, Linux, MacOS) - - -## How to run - -You can run this sample by one of following methods - -#### Build from source - -Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms/archive/master.zip) from github or clone this repository. - -```bash -git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms -``` - -Open solution in the VisualStudio. -Update common parameters in `web.config` and example related properties in the `configuration.yml` to meet your requirements. - -Open http://localhost:8080/viewer in your favorite browser - -#### Docker image -Use [docker](https://www.docker.com/) image. - -```bash -mkdir DocumentSamples -mkdir Licenses -docker run -p 8080:8080 --env application.hostAddress=localhost -v `pwd`/DocumentSamples:/home/groupdocs/app/DocumentSamples -v `pwd`/Licenses:/home/groupdocs/app/Licenses groupdocs/viewer -## Open http://localhost:8080/viewer in your favorite browser. -``` - -### Configuration -For all methods above you can adjust settings in `configuration.yml`. By default in this sample will lookup for license file in `./Licenses` folder, so you can simply put your license file in that folder or specify relative/absolute path by setting `licensePath` value in `configuration.yml`. - -#### Viewer configuration options - -| Option | Type | Default value | Description | -| ---------------------- | ------- |:-----------------:|:-------------------------------------------------------------------------------------------------------------------------------------------- | -| **`filesDirectory`** | String | `DocumentSamples` | Files directory path. Indicates where uploaded and predefined files are stored. It can be absolute or relative path | -| **`fontsDirectory`** | String | | Path to custom fonts directory. | -| **`defaultDocument`** | String | | Absolute path to default document that will be loaded automaticaly. | -| **`preloadPageCount`** | Integer | `0` | Indicate how many pages from a document should be loaded, remaining pages will be loaded on page scrolling.Set `0` to load all pages at once | -| **`htmlMode`** | Boolean | `true` | HTML rendering mode. Set `false` to view documents in image mode. Set `true` to view documents in HTML mode | -| **`zoom`** | Boolean | `true` | Enable or disable Document zoom | -| **`search`** | Boolean | `true` | Enable or disable document search | -| **`thumbnails`** | Boolean | `true` | Enable thumbnails preview | -| **`rotate`** | Boolean | `true` | Enable individual page rotation functionality | -| **`cache`** | Boolean | `true` | Set true to enable cache | -| **`saveRotateState`** | Boolean | `true` | If enabled it will save chages made by rotating individual pages to same file. | -| **`watermarkText`** | String | | Text which will be used as a watermark | - -## Troubleshooting -### How to set custom baseURL -BaseURL is fetched from address bar however you can set custom baseURL by adding *forRoot* parameter at [app.module.ts](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms/blob/master/src/client/apps/viewer/src/app/app.module.ts#L10) - -**Example:** -```js - ViewerModule.forRoot("http://localhost:8080") - ``` - -## License -The MIT License (MIT). - -Please have a look at the LICENSE.md for more details - -## GroupDocs Document Viewer on other platforms/frameworks - -- JAVA DropWizard [Document Viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Dropwizard) -- JAVA Spring boot [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Spring) -- .NET MVC [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC) - - -[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/family) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/WebForms/appveyor.yml b/Demos/WebForms/appveyor.yml deleted file mode 100644 index 418632b98..000000000 --- a/Demos/WebForms/appveyor.yml +++ /dev/null @@ -1,5 +0,0 @@ -version: 1.0.{build} -before_build: -- cmd: nuget restore -build: - verbosity: minimal \ No newline at end of file diff --git a/Demos/WebForms/src/AppDomainGenerator/DomainGenerator.cs b/Demos/WebForms/src/AppDomainGenerator/DomainGenerator.cs deleted file mode 100644 index 887c7c536..000000000 --- a/Demos/WebForms/src/AppDomainGenerator/DomainGenerator.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.IO; -using System.Reflection; - -namespace GroupDocs.Viewer.WebForms.AppDomainGenerator -{ - public class DomainGenerator - { - private readonly Products.Common.Config.GlobalConfiguration globalConfiguration; - private readonly Type CurrentType; - - /// - /// Initializes a new instance of the class. - /// - public DomainGenerator(string assemblyName, string className) - { - this.globalConfiguration = new Products.Common.Config.GlobalConfiguration(); - - // Get assembly path - string assemblyPath = GetAssemblyPath(assemblyName); - - // Initiate GroupDocs license class - this.CurrentType = this.CreateDomain(assemblyName + "Domain", assemblyPath, className); - } - - /// - /// Get assembly full path by its name. - /// - /// string. - /// - private static string GetAssemblyPath(string assemblyName) - { - string path = string.Empty; - - // Get path of the executable - string codeBase = Assembly.GetExecutingAssembly().CodeBase; - UriBuilder uri = new UriBuilder(codeBase); - string uriPath = Uri.UnescapeDataString(uri.Path); - - // Get path of the assembly - path = Path.Combine(Path.GetDirectoryName(uriPath), assemblyName); - return path; - } - - /// - /// Create AppDomain for the assembly. - /// - /// string. - /// string. - /// string. - /// - private Type CreateDomain(string domainName, string assemblyPath, string className) - { - // Create domain - AppDomain dom = AppDomain.CreateDomain(domainName); - AssemblyName assemblyName = new AssemblyName { CodeBase = assemblyPath }; - - // Load assembly into the domain - Assembly assembly = dom.Load(assemblyName); - - // Initiate class from the loaded assembly - Type type = assembly.GetType(className); - return type; - } - - /// - /// Set GroupDocs.Viewer license. - /// - /// Type. - public void SetViewerLicense() - { - // Initiate license class - var obj = (GroupDocs.Viewer.License)Activator.CreateInstance(this.CurrentType); - - // Set license - this.SetLicense(obj); - } - - private void SetLicense(dynamic obj) - { - if (!string.IsNullOrEmpty(this.globalConfiguration.Application.LicensePath)) - { - obj.SetLicense(this.globalConfiguration.Application.LicensePath); - } - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/App_Start/RouteConfig.cs b/Demos/WebForms/src/App_Start/RouteConfig.cs deleted file mode 100644 index d96fabd08..000000000 --- a/Demos/WebForms/src/App_Start/RouteConfig.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Web.Routing; -using Microsoft.AspNet.FriendlyUrls; - -namespace GroupDocs.Viewer.WebForms -{ - public static class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - var settings = new FriendlyUrlSettings(); - settings.AutoRedirectMode = RedirectMode.Permanent; - routes.EnableFriendlyUrls(settings); - - routes.MapPageRoute( - "Viewer", - "", - "~/Viewer.aspx" - ); - } - } -} diff --git a/Demos/WebForms/src/App_Start/WebApiConfig.cs b/Demos/WebForms/src/App_Start/WebApiConfig.cs deleted file mode 100644 index 93e85e123..000000000 --- a/Demos/WebForms/src/App_Start/WebApiConfig.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Web.Http; - -namespace GroupDocs.Viewer.WebForms -{ - public static class WebApiConfig - { - public static void Register(HttpConfiguration config) - { - // Web API configuration and services - config.EnableCors(); - - // Web API routes - config.MapHttpAttributeRoutes(); - - config.Routes.MapHttpRoute( - name: "ViewerApi", - routeTemplate: "{controller}/{action}/{id}", - defaults: new { id = RouteParameter.Optional } - ); - } - } -} diff --git a/Demos/WebForms/src/DocumentSamples/Viewer/.gitkeep b/Demos/WebForms/src/DocumentSamples/Viewer/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/Global.asax.cs b/Demos/WebForms/src/Global.asax.cs deleted file mode 100644 index c5ea196f9..000000000 --- a/Demos/WebForms/src/Global.asax.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Web; -using System.Web.Routing; -using System.Web.Http; -using GroupDocs.Viewer.WebForms.AppDomainGenerator; - -namespace GroupDocs.Viewer.WebForms -{ - public class Global : HttpApplication - { - void Application_Start(object sender, EventArgs e) - { - // Fix required to use several GroupDocs products in one project. - // Set GroupDocs products assemblies names - string viewerAssemblyName = "GroupDocs.Viewer.dll"; - - // set GroupDocs.Viewer license - DomainGenerator viewerDomainGenerator = new DomainGenerator(viewerAssemblyName, "GroupDocs.Viewer.License"); - viewerDomainGenerator.SetViewerLicense(); - - // Code that runs on application startup - GlobalConfiguration.Configure(WebApiConfig.Register); - RouteConfig.RegisterRoutes(RouteTable.Routes); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/GroupDocs.Viewer.WebForms.csproj b/Demos/WebForms/src/GroupDocs.Viewer.WebForms.csproj deleted file mode 100644 index 4e4b05325..000000000 --- a/Demos/WebForms/src/GroupDocs.Viewer.WebForms.csproj +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - - Debug - AnyCPU - - - 2.0 - {7B296703-AC7B-4FA6-BD42-BEC76D0C6DDC} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - GroupDocs.Viewer.WebForms - GroupDocs.Viewer.WebForms - v4.5 - true - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\GroupDocs.Viewer.22.7.0\lib\net40\GroupDocs.Viewer.dll - True - - - ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - - - - - - - ..\packages\Microsoft.AspNet.WebApi.Client.5.2.6\lib\net45\System.Net.Http.Formatting.dll - True - - - ..\packages\Microsoft.AspNet.Cors.5.2.6\lib\net45\System.Web.Cors.dll - True - - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.6\lib\net45\System.Web.Http.dll - True - - - ..\packages\Microsoft.AspNet.WebApi.Cors.5.2.6\lib\net45\System.Web.Http.Cors.dll - True - - - - - - - - - - - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - ..\packages\Microsoft.AspNet.ScriptManager.MSAjax.5.0.0\lib\net45\Microsoft.ScriptManager.MSAjax.dll - - - ..\packages\Microsoft.AspNet.ScriptManager.WebForms.5.0.0\lib\net45\Microsoft.ScriptManager.WebForms.dll - - - ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - - True - ..\packages\WebGrease.1.5.2\lib\WebGrease.dll - - - True - ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll - - - True - ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll - - - True - ..\packages\Microsoft.AspNet.Web.Optimization.WebForms.1.1.3\lib\net45\Microsoft.AspNet.Web.Optimization.WebForms.dll - - - ..\packages\Microsoft.AspNet.FriendlyUrls.Core.1.0.2\lib\net45\Microsoft.AspNet.FriendlyUrls.dll - - - ..\packages\YamlDotNet.5.2.1\lib\net45\YamlDotNet.dll - - - - - ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - - - - - Designer - - - - Web.config - - - Web.config - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Global.asax - - - - - Viewer.aspx - ASPXCodeBehind - - - Viewer.aspx - - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - True - 50879 - / - http://localhost:8080/viewer - True - http://localhost:8080 - False - False - - - False - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WebForms/src/Licenses/.gitkeep b/Demos/WebForms/src/Licenses/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/Products/Common/Config/ApplicationConfiguration.cs b/Demos/WebForms/src/Products/Common/Config/ApplicationConfiguration.cs deleted file mode 100644 index f31797ff6..000000000 --- a/Demos/WebForms/src/Products/Common/Config/ApplicationConfiguration.cs +++ /dev/null @@ -1,58 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Common.Util.Parser; -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Config -{ - /// - /// Application configuration. - /// - public class ApplicationConfiguration - { - public string LicensePath { get; set; } = "Licenses"; - - /// - /// Get license path from the application configuration section of the web.config. - /// - public ApplicationConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("application"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - string license = valuesGetter.GetStringPropertyValue("licensePath"); - if (string.IsNullOrEmpty(license)) - { - string[] files = System.IO.Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.LicensePath), "*.lic"); - this.LicensePath = Path.Combine(this.LicensePath, files[0]); - } - else - { - if (!IsFullPath(license)) - { - license = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, license); - if (!Directory.Exists(Path.GetDirectoryName(license))) - { - Directory.CreateDirectory(Path.GetDirectoryName(license)); - } - } - - this.LicensePath = license; - if (!File.Exists(this.LicensePath)) - { - Debug.WriteLine("License file path is incorrect, launched in trial mode"); - this.LicensePath = string.Empty; - } - } - } - - private static bool IsFullPath(string path) - { - return !string.IsNullOrWhiteSpace(path) - && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1 - && Path.IsPathRooted(path) - && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Config/CommonConfiguration.cs b/Demos/WebForms/src/Products/Common/Config/CommonConfiguration.cs deleted file mode 100644 index 06dc5e9fa..000000000 --- a/Demos/WebForms/src/Products/Common/Config/CommonConfiguration.cs +++ /dev/null @@ -1,55 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Common.Util.Parser; -using Newtonsoft.Json; -using System; -using System.Collections.Specialized; -using System.Configuration; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Config -{ - /// - /// CommonConfiguration. - /// - public class CommonConfiguration : ConfigurationSection - { - [JsonProperty] - public bool pageSelector { get; set; } - - [JsonProperty] - public bool download { get; set; } - - [JsonProperty] - public bool upload { get; set; } - - [JsonProperty] - public bool print { get; set; } - - [JsonProperty] - public bool browse { get; set; } - - [JsonProperty] - public bool rewrite { get; set; } - - [JsonProperty] - public bool enableRightClick { get; set; } - - private readonly NameValueCollection commonConfiguration = (NameValueCollection)ConfigurationManager.GetSection("commonConfiguration"); - - /// - /// Constructor. - /// - public CommonConfiguration() - - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("common"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - pageSelector = valuesGetter.GetBooleanPropertyValue("pageSelector", Convert.ToBoolean(commonConfiguration["isPageSelector"])); - download = valuesGetter.GetBooleanPropertyValue("download", Convert.ToBoolean(commonConfiguration["isDownload"])); - upload = valuesGetter.GetBooleanPropertyValue("upload", Convert.ToBoolean(commonConfiguration["isUpload"])); - print = valuesGetter.GetBooleanPropertyValue("print", Convert.ToBoolean(commonConfiguration["isPrint"])); - browse = valuesGetter.GetBooleanPropertyValue("browse", Convert.ToBoolean(commonConfiguration["isBrowse"])); - rewrite = valuesGetter.GetBooleanPropertyValue("rewrite", Convert.ToBoolean(commonConfiguration["isRewrite"])); - enableRightClick = valuesGetter.GetBooleanPropertyValue("enableRightClick", Convert.ToBoolean(commonConfiguration["enableRightClick"])); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Config/ConfigurationValuesGetter.cs b/Demos/WebForms/src/Products/Common/Config/ConfigurationValuesGetter.cs deleted file mode 100644 index 748be27b4..000000000 --- a/Demos/WebForms/src/Products/Common/Config/ConfigurationValuesGetter.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Config -{ - public class ConfigurationValuesGetter - { - private readonly dynamic configuration; - - public ConfigurationValuesGetter(dynamic configuration) - { - this.configuration = configuration; - } - - public string GetStringPropertyValue(string propertyName) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - this.configuration[propertyName].ToString() : - null; - } - - public string GetStringPropertyValue(string propertyName, string defaultValue) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - this.configuration[propertyName].ToString() : - defaultValue; - } - - public string[] GetStringArrayPropertyValue(string propertyName, string[] defaultValue) - { - if (this.configuration != null && this.configuration[propertyName] != null) - { - var array = this.configuration[propertyName] as Newtonsoft.Json.Linq.JArray; - if (array != null) - return array.ToObject(); - } - - return defaultValue; - } - - public int GetIntegerPropertyValue(string propertyName, int defaultValue) - { - int value; - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName]) : - defaultValue; - return value; - } - - public int GetIntegerPropertyValue(string propertyName, int defaultValue, string innerPropertyName) - { - int value; - if (!string.IsNullOrEmpty(innerPropertyName)) - { - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName][innerPropertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName][innerPropertyName]) : - defaultValue; - } - else - { - value = (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? - Convert.ToInt32(this.configuration[propertyName]) : - defaultValue; - } - - return value; - } - - public bool GetBooleanPropertyValue(string propertyName, bool defaultValue) - { - return (this.configuration != null && this.configuration[propertyName] != null && !string.IsNullOrEmpty(this.configuration[propertyName].ToString())) ? Convert.ToBoolean(this.configuration[propertyName]) : defaultValue; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Config/GlobalConfiguration.cs b/Demos/WebForms/src/Products/Common/Config/GlobalConfiguration.cs deleted file mode 100644 index 9908be38f..000000000 --- a/Demos/WebForms/src/Products/Common/Config/GlobalConfiguration.cs +++ /dev/null @@ -1,26 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Viewer.Config; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Config -{ - /// - /// Global configuration. - /// - public class GlobalConfiguration - { - public ServerConfiguration Server { get; set; } - public ApplicationConfiguration Application { get; set; } - public CommonConfiguration Common { get; set; } - public ViewerConfiguration Viewer { get; set; } - - /// - /// Get all configurations. - /// - public GlobalConfiguration() - { - this.Server = new ServerConfiguration(); - this.Application = new ApplicationConfiguration(); - this.Viewer = new ViewerConfiguration(); - this.Common = new CommonConfiguration(); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Config/ServerConfiguration.cs b/Demos/WebForms/src/Products/Common/Config/ServerConfiguration.cs deleted file mode 100644 index b7f56dcba..000000000 --- a/Demos/WebForms/src/Products/Common/Config/ServerConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Common.Util.Parser; -using System; -using System.Collections.Specialized; -using System.Configuration; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Config -{ - /// - /// Server configuration. - /// - public class ServerConfiguration : ConfigurationSection - { - public int HttpPort { get; set; } = 8080; - private readonly string HostAddress = "localhost"; - private readonly NameValueCollection serverConfiguration = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("serverConfiguration"); - - /// - /// Get server configuration section of the web.config. - /// - public ServerConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("server"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - int defaultPort = Convert.ToInt32(this.serverConfiguration["httpPort"]); - this.HttpPort = valuesGetter.GetIntegerPropertyValue("connector", defaultPort, "port"); - this.HostAddress = valuesGetter.GetStringPropertyValue("hostAddress", this.HostAddress); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/ExceptionEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/ExceptionEntity.cs deleted file mode 100644 index be6d0590c..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/ExceptionEntity.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents exception entity. - /// - public class ExceptionEntity - { - /// - /// Exception message. - /// - public string message { get; set; } - - /// - /// Exception object. - /// - public System.Exception exception { get; set; } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/FileDescriptionEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/FileDescriptionEntity.cs deleted file mode 100644 index ed9dbc63b..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/FileDescriptionEntity.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents file or directory. - /// - public class FileDescriptionEntity - { - /// - /// Absolute path to the file/directory. - /// - public string guid { get; set; } - - /// - /// Name of the file/directory. - /// - public string name { get; set; } - - /// - /// File or directory flag. - /// - public bool isDirectory { get; set; } - - /// - /// File size. - /// - public long size { get; set; } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/LoadDocumentEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/LoadDocumentEntity.cs deleted file mode 100644 index 5f79ecbe3..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/LoadDocumentEntity.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Newtonsoft.Json; -using System.Collections.Generic; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents document properties and its pages collection. - /// - public class LoadDocumentEntity - { - /// - /// Document absolute path. - /// - [JsonProperty] - private string guid; - - /// - /// Collection of the document pages with their data. - /// - [JsonProperty] - private List pages = new List(); - - /// - /// Document print allowed flag. - /// - [JsonProperty] - private bool printAllowed = true; - - /// - /// Document show grid lines flag (for Excel files). - /// - [JsonProperty] - private bool showGridLines = true; - - public void SetPrintAllowed(bool allowed) - { - this.printAllowed = allowed; - } - - public bool GetPrintAllowed() - { - return this.printAllowed; - } - - public void SetShowGridLines(bool show) - { - this.showGridLines = show; - } - - public bool GetShowGridLines() - { - return this.showGridLines; - } - - public void SetGuid(string guid) - { - this.guid = guid; - } - - public string GetGuid() - { - return this.guid; - } - - public void SetPages(PageDescriptionEntity page) - { - this.pages.Add(page); - } - - public List GetPages() - { - return this.pages; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/PageDescriptionEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/PageDescriptionEntity.cs deleted file mode 100644 index d396cc8fa..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/PageDescriptionEntity.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Newtonsoft.Json; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents document page data, dimensions and rotation angle. - /// - public class PageDescriptionEntity - { - /// - /// Page width. - /// - public double width { get; set; } - - /// - /// Page height. - /// - public double height { get; set; } - - /// - /// Page number. - /// - public int number { get; set; } - - /// - /// Page rotation angle. - /// - public int angle { get; set; } - - /// - /// Page content data. - /// - [JsonProperty] - private string data; - - /// - /// Sheet name. - /// - public string sheetName { get; set; } - - public void SetData(string data) - { - this.data = data; - } - - public string GetData() - { - return this.data; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/PostedDataEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/PostedDataEntity.cs deleted file mode 100644 index d4edb9863..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/PostedDataEntity.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, representes document with its pages - /// posted from the front-end. - /// - public class PostedDataEntity - { - /// - /// Absolute path to the document. - /// - public string guid { get; set; } - - /// - /// Document password. - /// - public string password { get; set; } - - /// - /// Page number. - /// - public int page { get; set; } - - /// - /// Page rotation angle. - /// - public int angle { get; set; } - - /// - /// Collection of the document pages with their data. - /// - public List pages { get; set; } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs b/Demos/WebForms/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs deleted file mode 100644 index 7edfb0bec..000000000 --- a/Demos/WebForms/src/Products/Common/Entity/Web/UploadedDocumentEntity.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GroupDocs.Viewer.WebForms.Products.Common.Entity.Web -{ - /// - /// DTO-class, represents uploaded document by its absolute path. - /// - public class UploadedDocumentEntity - { - /// - /// Absolute path to the uploaded document. - /// - public string guid { get; set; } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Resources/Resources.cs b/Demos/WebForms/src/Products/Common/Resources/Resources.cs deleted file mode 100644 index 88623a54c..000000000 --- a/Demos/WebForms/src/Products/Common/Resources/Resources.cs +++ /dev/null @@ -1,91 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Common.Entity.Web; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Resources -{ - /// - /// Provides methods for generating uploaded files names and exception entities. - /// - public static class Resources - { - /// - /// Get free file name for uploaded file if such file already exists. - /// - /// Directory where to search files. - /// Uploaded file name. - /// - public static string GetFreeFileName(string directory, string fileName) - { - string resultFileName = string.Empty; - try - { - // get all files from the directory - string[] listOfFiles = Directory.GetFiles(directory); - for (int i = 0; i < listOfFiles.Length; i++) - { - // check if file with current name already exists - int number = i + 1; - string newFileName = Path.GetFileNameWithoutExtension(fileName) + "-Copy(" + number + ")." + Path.GetExtension(fileName); - resultFileName = Path.Combine(directory, newFileName); - if (!File.Exists(resultFileName)) - { - break; - } - } - } - catch (System.Exception e) - { - throw e; - } - - return resultFileName; - } - - /// - /// Generate exception. - /// - /// Exception. - /// ExceptionEntity. - public static ExceptionEntity GenerateException(System.Exception ex) - { - // Initiate Exception entity - ExceptionEntity exceptionEntity = new ExceptionEntity(); - - // set exception data - exceptionEntity.message = ex.Message; - exceptionEntity.exception = ex; - return exceptionEntity; - } - - /// - /// Generate exception for password error. - /// - /// Exception. - /// string. - /// ExceptionEntity. - public static ExceptionEntity GenerateException(System.Exception ex, string password) - { - // Initiate exception - ExceptionEntity exceptionEntity = new ExceptionEntity(); - - // Check if exception message contains password and password is empty - if (ex.Message.Contains("password") && string.IsNullOrEmpty(password)) - { - exceptionEntity.message = "Password Required"; - } - - // Check if exception contains password and password is set - else if (ex.Message.Contains("password") && !string.IsNullOrEmpty(password)) - { - exceptionEntity.message = "Incorrect password"; - } - else - { - exceptionEntity.message = ex.Message; - exceptionEntity.exception = ex; - } - - return exceptionEntity; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Util/Comparator/FileDateComparator.cs b/Demos/WebForms/src/Products/Common/Util/Comparator/FileDateComparator.cs deleted file mode 100644 index dc7a8d45f..000000000 --- a/Demos/WebForms/src/Products/Common/Util/Comparator/FileDateComparator.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Util.Comparator -{ - /// - /// FileDateComparator. - /// - public class FileDateComparator : IComparer - { - /// - /// Compare file creation dates. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = File.GetCreationTime(x).ToString(CultureInfo.InvariantCulture); - string strExt2 = File.GetCreationTime(y).ToString(CultureInfo.InvariantCulture); - - if (strExt1.Equals(strExt2)) - { - return string.CompareOrdinal(x, y); - } - else - { - return string.CompareOrdinal(strExt1, strExt2); - } - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Util/Comparator/FileNameComparator.cs b/Demos/WebForms/src/Products/Common/Util/Comparator/FileNameComparator.cs deleted file mode 100644 index 84770f0e1..000000000 --- a/Demos/WebForms/src/Products/Common/Util/Comparator/FileNameComparator.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Util.Comparator -{ - /// - /// FileNameComparator. - /// - public class FileNameComparator : IComparer - { - /// - /// Compare file names. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = Path.GetFileName(x); - string strExt2 = Path.GetFileName(y); - - if (strExt1.Equals(strExt2)) - { - return string.CompareOrdinal(x, y); - } - else - { - return string.CompareOrdinal(strExt1, strExt2); - } - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Util/Comparator/FileTypeComparator.cs b/Demos/WebForms/src/Products/Common/Util/Comparator/FileTypeComparator.cs deleted file mode 100644 index 6d9fd6a05..000000000 --- a/Demos/WebForms/src/Products/Common/Util/Comparator/FileTypeComparator.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Util.Comparator -{ - /// - /// FileTypeComparator. - /// - public class FileTypeComparator : IComparer - { - /// - /// Compare file types. - /// - /// string. - /// string. - /// - public int Compare(string x, string y) - { - string strExt1 = Path.GetExtension(x); - string strExt2 = Path.GetExtension(y); - - if (strExt1.Equals(strExt2)) - { - return string.CompareOrdinal(x, y); - } - else - { - return string.CompareOrdinal(strExt1, strExt2); - } - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Util/Directory/IDirectoryUtils.cs b/Demos/WebForms/src/Products/Common/Util/Directory/IDirectoryUtils.cs deleted file mode 100644 index d855f8e9c..000000000 --- a/Demos/WebForms/src/Products/Common/Util/Directory/IDirectoryUtils.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace GroupDocs.Viewer.WebForms.Products.Common.Util.Directory -{ - /// - /// IDirectoryUtils. - /// - public interface IDirectoryUtils - { - string GetPath(); - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Common/Util/Parser/YamlParser.cs b/Demos/WebForms/src/Products/Common/Util/Parser/YamlParser.cs deleted file mode 100644 index 6cb66974b..000000000 --- a/Demos/WebForms/src/Products/Common/Util/Parser/YamlParser.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.IO; -using YamlDotNet.Serialization; - -namespace GroupDocs.Viewer.WebForms.Products.Common.Util.Parser -{ - public class YamlParser - { - private static readonly string YamlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "configuration.yml"); - private readonly dynamic ConfiguationData; - - public YamlParser() - { - if (File.Exists(YamlPath)) - { - using (var reader = new StringReader(File.ReadAllText(YamlPath))) - { - var deserializer = new DeserializerBuilder().Build(); - var yamlObject = deserializer.Deserialize(reader); - - var serializer = new SerializerBuilder() - .JsonCompatible() - .Build(); - - this.ConfiguationData = serializer.Serialize(yamlObject); - } - } - } - - public dynamic GetConfiguration(string configurationSectionName) - { - dynamic productConfiguration = null; - if (this.ConfiguationData != null) - { - productConfiguration = JsonConvert.DeserializeObject(this.ConfiguationData)[configurationSectionName]; - } - - return productConfiguration; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/CacheExtensions.cs b/Demos/WebForms/src/Products/Viewer/Cache/CacheExtensions.cs deleted file mode 100644 index 6a2663667..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/CacheExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - internal static class CacheExtensions - { - /// - /// Gets the entry associated with this key if present or acquires and sets the entry if not present. - /// - /// Type of entry. - /// The cache. - /// A key identifying the requested entry. - /// The method which returns entry. - /// The entry associated with this key if present or acquires and sets the entry if not present. - public static TEntry GetValue(this IViewerCache cache, string key, Func acquire) - { - TEntry entry; - if (!cache.TryGetValue(key, out entry)) - { - entry = acquire(); - cache.Set(key, entry); - } - - return entry; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/CrossProcessLock.cs b/Demos/WebForms/src/Products/Viewer/Cache/CrossProcessLock.cs deleted file mode 100644 index 8c1e01229..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/CrossProcessLock.cs +++ /dev/null @@ -1,96 +0,0 @@ -using GroupDocs.Viewer.Exceptions; -using System; -using System.Security.AccessControl; -using System.Security.Principal; -using System.Threading; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - sealed class CrossProcessLock : IDisposable - { - private const int MaxMutexIdLength = 260; - private readonly Mutex mutex; - private readonly bool isMutexOwner; - - /// - /// Initializes a new instance of the class. - /// - /// The file path. - public CrossProcessLock(string path) - { - string mutexId = this.GetMutexId(path); - MutexSecurity mutexSecurity = this.GetMutexSecurity(); - try - { - bool createdNew; - this.mutex = new Mutex(false, mutexId, out createdNew, mutexSecurity); - - try - { - this.isMutexOwner = this.mutex.WaitOne(10 * 60 * 1000); - } - catch (AbandonedMutexException) - { - // NOTE: Log the fact the mutex was abandoned in another process, it will still get acquired - } - } - catch (WaitHandleCannotBeOpenedException ex) - { - // the mutex cannot be opened, probably because a Win32 object of a different - // type with the same name already exists. - throw new GroupDocsViewerException("Mutex can't be opened: " + ex.Message); - } - catch (UnauthorizedAccessException ex) - { - // the mutex exists, but the current process or thread token does not - // have permission to open the mutex with SYNCHRONIZE | MUTEX_MODIFY rights. - throw new GroupDocsViewerException("Current process does not have permission to open the mutex: " + ex.Message); - } - } - - /// - /// Releases mutex. - /// - public void Dispose() - { - if (this.mutex != null) - { - if (this.isMutexOwner) - { - this.mutex.ReleaseMutex(); - } - - this.mutex.Close(); - } - } - - private MutexSecurity GetMutexSecurity() - { - SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null); - MutexAccessRule allowEveryone = new MutexAccessRule(everyone, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); - MutexSecurity mutexSecurity = new MutexSecurity(); - mutexSecurity.AddAccessRule(allowEveryone); - - return mutexSecurity; - } - - private string GetMutexId(string path) - { - string normalized = path.Replace("\\", "_"); - - string mutexId = normalized; - if (mutexId.Length < MaxMutexIdLength) - { - return mutexId; - } - - int maxPathLength = MaxMutexIdLength; - - string trimmedPath = normalized.Length > maxPathLength - ? normalized.Substring(normalized.Length - maxPathLength) - : normalized; - - return trimmedPath; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/FileViewerCache.cs b/Demos/WebForms/src/Products/Viewer/Cache/FileViewerCache.cs deleted file mode 100644 index e0355e4fe..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/FileViewerCache.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.Threading; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - internal class FileViewerCache : IViewerCache - { - private readonly TimeSpan waitTimeout = TimeSpan.FromMilliseconds(100); - - /// - /// Gets the Relative or absolute path to the cache folder. - /// - public string CachePath { get; } - - /// - /// Gets the sub-folder to append to the . - /// - public string CacheSubFolder { get; } - - /// - /// Initializes a new instance of the class. - /// - /// Relative or absolute path where document cache will be stored. - /// The sub-folder to append to . - /// Thrown when is null. - /// Thrown when is null. - public FileViewerCache(string cachePath, string cacheSubFolder) - { - if (cachePath == null) - { - throw new ArgumentNullException(nameof(cachePath)); - } - - if (cacheSubFolder == null) - { - throw new ArgumentNullException(nameof(cacheSubFolder)); - } - - this.CachePath = cachePath; - this.CacheSubFolder = cacheSubFolder; - } - - /// - /// Serializes data to the local disk. - /// - /// An unique identifier for the cache entry. - /// The object to serialize. - public void Set(string key, object value) - { - if (value == null) - { - return; - } - - string filePath = this.GetCacheFilePath(key); - - Stream src = value as Stream; - if (src != null) - { - using (FileStream dst = this.GetStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - src.Position = 0; - this.CopyStream(src, dst); - } - } - else - { - using (FileStream stream = this.GetStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Serialize(stream, value); - } - } - } - - /// - /// Deserializes data associated with this key if present. - /// - /// A key identifying the requested entry. - /// True if the key was found. - public T GetValue(string key) - { - string cacheFilePath = this.GetCacheFilePath(key); - T value = typeof(T) == typeof(Stream) - ? (T)this.ReadStream(cacheFilePath) - : (T)this.Deserialize(cacheFilePath); - - return value; - } - - /// - /// Deserializes data associated with this key if present. - /// - /// A key identifying the requested entry. - /// The located value or null. - /// True if the key was found. - public bool TryGetValue(string key, out T value) - { - string cacheFilePath = this.GetCacheFilePath(key); - - if (File.Exists(cacheFilePath)) - { - value = typeof(T) == typeof(Stream) - ? (T)this.ReadStream(cacheFilePath) - : (T)this.Deserialize(cacheFilePath); - - return true; - } - - value = default(T); - return false; - } - - private object ReadStream(string cacheFilePath) - { - return this.GetStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); - } - - private object Deserialize(string cachePath) - { - object data; - using (FileStream stream = this.GetStream(cachePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Binder = new IgnoreAssemblyVersionSerializationBinder(); - - try - { - data = formatter.Deserialize(stream); - } - catch (SerializationException) - { - data = null; - } - } - - return data; - } - - public string GetCacheFilePath(string key) - { - string folderPath = Path.Combine(this.CachePath, this.CacheSubFolder); - string filePath = Path.Combine(folderPath, key); - - if (!Directory.Exists(folderPath)) - { - Directory.CreateDirectory(folderPath); - } - - return filePath; - } - - public bool Contains(string key) - { - string file = Path.Combine(this.CachePath, this.CacheSubFolder, key); - return File.Exists(file); - } - - private FileStream GetStream(string path, FileMode mode, FileAccess access, FileShare share) - { - FileStream stream = null; - TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); - TimeSpan totalTime = new TimeSpan(); - - while (stream == null) - { - try - { - stream = File.Open(path, mode, access, share); - } - catch (IOException) - { - Thread.Sleep(interval); - totalTime += interval; - - if (this.waitTimeout.Ticks != 0 && totalTime > this.waitTimeout) - { - throw; - } - } - } - - return stream; - } - - private void CopyStream(Stream src, Stream dst) - { - const int bufferSize = 81920; //NOTE: taken from System.IO - byte[] buffer = new byte[bufferSize]; - int read; - while ((read = src.Read(buffer, 0, buffer.Length)) != 0) - { - dst.Write(buffer, 0, read); - } - } - - private class IgnoreAssemblyVersionSerializationBinder : SerializationBinder - { - public override Type BindToType(string assemblyName, string typeName) - { - string assembly = Assembly.GetAssembly(typeof(GroupDocs.Viewer.Viewer)).FullName; - Type type = Type.GetType($"{typeName}, {assembly}"); - - return type; - } - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/HtmlViewer.cs b/Demos/WebForms/src/Products/Viewer/Cache/HtmlViewer.cs deleted file mode 100644 index 03db5d0dc..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/HtmlViewer.cs +++ /dev/null @@ -1,244 +0,0 @@ -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using System; -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - class HtmlViewer : IDisposable, ICustomViewer - { - private readonly string filePath; - private readonly IViewerCache cache; - - private readonly GroupDocs.Viewer.Viewer viewer; - private readonly HtmlViewOptions htmlViewOptions; - private readonly PdfViewOptions pdfViewOptions; - private readonly ViewInfoOptions viewInfoOptions; - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - public HtmlViewer(string filePath, IViewerCache cache, LoadOptions loadOptions, int pageNumber = -1, int newAngle = 0) - { - this.cache = cache; - this.filePath = filePath; - this.viewer = new GroupDocs.Viewer.Viewer(filePath, loadOptions); - this.htmlViewOptions = this.CreateHtmlViewOptions(pageNumber, newAngle); - this.pdfViewOptions = this.CreatePdfViewOptions(); - this.viewInfoOptions = ViewInfoOptions.FromHtmlViewOptions(this.htmlViewOptions); - } - - public GroupDocs.Viewer.Viewer GetViewer() - { - return this.viewer; - } - - private HtmlViewOptions CreateHtmlViewOptions(int passedPageNumber = -1, int newAngle = 0) - { - HtmlViewOptions htmlViewOptions = HtmlViewOptions.ForExternalResources( - pageNumber => - { - string fileName = $"p{pageNumber}.html"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }, - (pageNumber, resource) => - { - string fileName = $"p{pageNumber}_{resource.FileName}"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }, - (pageNumber, resource) => - { - var urlPrefix = "/viewer/resources/" + Path.GetFileName(this.filePath).Replace(".", "_"); - return $"{urlPrefix}/p{ pageNumber}_{ resource.FileName}"; - }); - - htmlViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - htmlViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - htmlViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - htmlViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(htmlViewOptions); - - if (passedPageNumber >= 0 && newAngle != 0) - { - Rotation rotationAngle = GetRotationByAngle(newAngle); - htmlViewOptions.RotatePage(passedPageNumber, rotationAngle); - } - - return htmlViewOptions; - } - - private PdfViewOptions CreatePdfViewOptions() - { - PdfViewOptions pdfViewOptions = new PdfViewOptions( - () => - { - string fileName = "f.pdf"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - pdfViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - pdfViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - pdfViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - pdfViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(pdfViewOptions); - - return pdfViewOptions; - } - - /// - /// Gets enumeration member by rotation angle value. - /// - /// New rotation angle value. - /// Rotation enumeration member. - private static Rotation GetRotationByAngle(int newAngle) - { - switch (newAngle) - { - case 90: - return Rotation.On90Degree; - case 180: - return Rotation.On180Degree; - case 270: - return Rotation.On270Degree; - default: - return Rotation.On90Degree; - } - } - - public Results.FileInfo GetFileInfo() - { - string cacheKey = "file_info.dat"; - - Results.FileInfo viewInfo = this.cache.GetValue(cacheKey, () => this.ReadFileInfo()); - - return viewInfo; - } - - public System.IO.FileInfo GetPageFile(int pageNumber) - { - this.CreateCache(); - - string pageKey = $"p{pageNumber}.html"; - string cacheFilePath = this.cache.GetCacheFilePath(pageKey); - - return new System.IO.FileInfo(cacheFilePath); - } - - public void CreateCache() - { - ViewInfo viewInfo = this.GetViewInfo(); - - using (new CrossProcessLock(this.filePath)) - { - int[] missingPages = this.GetPagesMissingFromCache(viewInfo.Pages); - - if (missingPages.Length > 0) - { - this.viewer.View(this.htmlViewOptions, missingPages); - } - } - } - - public Stream GetPdf() - { - string cacheKey = "f.pdf"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - this.viewer.View(this.pdfViewOptions); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - public void Dispose() - { - this.viewer?.Dispose(); - } - - /// - /// Adds watermark on document if its specified in configuration file. - /// - /// View options. - private static void SetWatermarkOptions(ViewOptions options) - { - Watermark watermark = null; - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetWatermarkText())) - { - // Set watermark properties - watermark = new Watermark(globalConfiguration.Viewer.GetWatermarkText()) - { - Color = System.Drawing.Color.Blue, - Position = Position.Diagonal, - }; - } - - if (watermark != null) - { - options.Watermark = watermark; - } - } - - private Results.FileInfo ReadFileInfo() - { - using (new CrossProcessLock(this.filePath)) - { - Results.FileInfo fileInfo = this.viewer.GetFileInfo(); - return fileInfo; - } - } - - private ViewInfo GetViewInfo() - { - string cacheKey = "view_info.dat"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - return this.cache.GetValue(cacheKey, () => this.ReadViewInfo()); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - private ViewInfo ReadViewInfo() - { - ViewInfo viewInfo = this.viewer.GetViewInfo(this.viewInfoOptions); - return viewInfo; - } - - private int[] GetPagesMissingFromCache(IList pages) - { - List missingPages = new List(); - foreach (Page page in pages) - { - string pageKey = $"p{page.Number}.html"; - if (!this.cache.Contains(pageKey)) - { - missingPages.Add(page.Number); - } - } - - return missingPages.ToArray(); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/ICustomViewer.cs b/Demos/WebForms/src/Products/Viewer/Cache/ICustomViewer.cs deleted file mode 100644 index a1f0064b4..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/ICustomViewer.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - interface ICustomViewer - { - GroupDocs.Viewer.Viewer GetViewer(); - Stream GetPdf(); - void CreateCache(); - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/IViewerCache.cs b/Demos/WebForms/src/Products/Viewer/Cache/IViewerCache.cs deleted file mode 100644 index aea889ff3..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/IViewerCache.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - /// - /// Defines methods required for storing rendered document and document resources сache. - /// - interface IViewerCache - { - /// - /// The Relative or absolute path to the cache folder. - /// - string CachePath { get; } - - /// - /// The sub-folder to append to the . - /// - string CacheSubFolder { get; } - - /// - /// Inserts a cache entry into the cache. - /// - /// A unique identifier for the cache entry. - /// The object to insert. - void Set(string key, object value); - - - T GetValue(string key); - - /// - /// Gets the entry associated with this key if present. - /// - /// Type of entry. - /// A key identifying the requested entry. - /// The located value or null. - /// True if the key was found. - bool TryGetValue(string key, out TEntry value); - - /// - /// Gets cache file path;. - /// - /// The cache file key. - /// Cache file path. - string GetCacheFilePath(string key); - - bool Contains(string key); - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Cache/PngViewer.cs b/Demos/WebForms/src/Products/Viewer/Cache/PngViewer.cs deleted file mode 100644 index dc250dfdb..000000000 --- a/Demos/WebForms/src/Products/Viewer/Cache/PngViewer.cs +++ /dev/null @@ -1,209 +0,0 @@ -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using System; -using System.Collections.Generic; -using System.IO; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Cache -{ - class PngViewer : IDisposable, ICustomViewer - { - private readonly string filePath; - private readonly IViewerCache cache; - - private readonly GroupDocs.Viewer.Viewer viewer; - private readonly PngViewOptions pngViewOptions; - private readonly PdfViewOptions pdfViewOptions; - private readonly ViewInfoOptions viewInfoOptions; - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - public PngViewer(string filePath, IViewerCache cache, LoadOptions loadOptions, int pageNumber = -1, int newAngle = 0) - { - this.cache = cache; - this.filePath = filePath; - this.viewer = new GroupDocs.Viewer.Viewer(filePath, loadOptions); - this.pngViewOptions = this.CreatePngViewOptions(pageNumber, newAngle); - this.pdfViewOptions = this.CreatePdfViewOptions(); - this.viewInfoOptions = ViewInfoOptions.FromPngViewOptions(this.pngViewOptions); - } - - public GroupDocs.Viewer.Viewer GetViewer() - { - return this.viewer; - } - - private PngViewOptions CreatePngViewOptions(int passedPageNumber = -1, int newAngle = 0) - { - PngViewOptions createdPngViewOptions = new PngViewOptions(pageNumber => - { - string fileName = $"p{pageNumber}.png"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - if (passedPageNumber >= 0 && newAngle != 0) - { - Rotation rotationAngle = GetRotationByAngle(newAngle); - createdPngViewOptions.RotatePage(passedPageNumber, rotationAngle); - } - - createdPngViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(createdPngViewOptions); - - return createdPngViewOptions; - } - - private PdfViewOptions CreatePdfViewOptions() - { - PdfViewOptions pdfViewOptions = new PdfViewOptions( - () => - { - string fileName = "f.pdf"; - string cacheFilePath = this.cache.GetCacheFilePath(fileName); - - return File.Create(cacheFilePath); - }); - - pdfViewOptions.SpreadsheetOptions = SpreadsheetOptions.ForOnePagePerSheet(); - pdfViewOptions.SpreadsheetOptions.TextOverflowMode = TextOverflowMode.HideText; - pdfViewOptions.SpreadsheetOptions.RenderGridLines = globalConfiguration.Viewer.GetShowGridLines(); - pdfViewOptions.SpreadsheetOptions.RenderHeadings = true; - - SetWatermarkOptions(pdfViewOptions); - - return pdfViewOptions; - } - - /// - /// Gets enumeration member by rotation angle value. - /// - /// New rotation angle value. - /// Rotation enumeration member. - private static Rotation GetRotationByAngle(int newAngle) - { - switch (newAngle) - { - case 90: - return Rotation.On90Degree; - case 180: - return Rotation.On180Degree; - case 270: - return Rotation.On270Degree; - default: - return Rotation.On90Degree; - } - } - - public void CreateCache() - { - ViewInfo viewInfo = this.GetViewInfo(); - - using (new CrossProcessLock(this.filePath)) - { - int[] missingPages = this.GetPagesMissingFromCache(viewInfo.Pages); - - if (missingPages.Length > 0) - { - this.viewer.View(this.pngViewOptions, missingPages); - } - } - } - - public Stream GetPdf() - { - string cacheKey = "f.pdf"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - this.viewer.View(this.pdfViewOptions); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - public void Dispose() - { - this.viewer?.Dispose(); - } - - /// - /// Adds watermark on document if its specified in configuration file. - /// - /// - private static void SetWatermarkOptions(ViewOptions options) - { - Watermark watermark = null; - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetWatermarkText())) - { - // Set watermark properties - watermark = new Watermark(globalConfiguration.Viewer.GetWatermarkText()) - { - Color = System.Drawing.Color.Blue, - Position = Position.Diagonal, - }; - } - - if (watermark != null) - { - options.Watermark = watermark; - } - } - - private Results.FileInfo ReadFileInfo() - { - using (new CrossProcessLock(this.filePath)) - { - Results.FileInfo fileInfo = this.viewer.GetFileInfo(); - return fileInfo; - } - } - - private ViewInfo GetViewInfo() - { - string cacheKey = "view_info.dat"; - - if (!this.cache.Contains(cacheKey)) - { - using (new CrossProcessLock(this.filePath)) - { - if (!this.cache.Contains(cacheKey)) - { - return this.cache.GetValue(cacheKey, () => this.ReadViewInfo()); - } - } - } - - return this.cache.GetValue(cacheKey); - } - - private ViewInfo ReadViewInfo() - { - ViewInfo viewInfo = this.viewer.GetViewInfo(this.viewInfoOptions); - return viewInfo; - } - - private int[] GetPagesMissingFromCache(IList pages) - { - List missingPages = new List(); - foreach (Page page in pages) - { - string pageKey = $"p{page.Number}.png"; - if (!this.cache.Contains(pageKey)) - { - missingPages.Add(page.Number); - } - } - - return missingPages.ToArray(); - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Config/ViewerConfiguration.cs b/Demos/WebForms/src/Products/Viewer/Config/ViewerConfiguration.cs deleted file mode 100644 index 55fb9f9b1..000000000 --- a/Demos/WebForms/src/Products/Viewer/Config/ViewerConfiguration.cs +++ /dev/null @@ -1,338 +0,0 @@ -using GroupDocs.Viewer.WebForms.Products.Common.Config; -using GroupDocs.Viewer.WebForms.Products.Common.Util.Parser; -using Newtonsoft.Json; -using System; -using System.IO; -using System.Linq; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Config -{ - /// - /// ViewerConfiguration. - /// - public class ViewerConfiguration : CommonConfiguration - { - [JsonProperty] - private string filesDirectory = "DocumentSamples/Viewer"; - - [JsonProperty] - private string fontsDirectory = string.Empty; - - [JsonProperty] - private string defaultDocument = string.Empty; - - [JsonProperty] - private string watermarkText = string.Empty; - - [JsonProperty] - private int preloadPageCount; - - [JsonProperty] - private bool zoom = true; - - [JsonProperty] - private bool search = true; - - [JsonProperty] - private bool thumbnails = true; - - [JsonProperty] - private bool rotate = true; - - [JsonProperty] - private bool htmlMode = true; - - [JsonProperty] - private bool cache = true; - - [JsonProperty] - private bool saveRotateState = true; - - [JsonProperty] - private bool printAllowed = true; - - [JsonProperty] - private bool showGridLines = true; - - [JsonProperty] - private string cacheFolderName = "cache"; - - [JsonProperty] - private bool showLanguageMenu = true; - - [JsonProperty] - private string defaultLanguage = "en"; - - [JsonProperty] - private string[] supportedLanguages = new string[] - { - "ar", // العربية - "ca", // Català - "cs", // Čeština - "da", // Dansk - "de", // Deutsch - "el", // Ελληνικά - "en", // English - "es", // Español - "fil", // Filipino - "fr", // Français - "he", // עברית - "hi", // हिन्दी - "id", // Indonesia - "it", // Italiano - "ja", // 日本語 - "kk", // Қазақ Тілі - "ko", // 한국어 - "ms", // Melayu - "nl", // Nederlands - "pl", // Polski - "pt", // Português - "ro", // Română - "ru", // Русский - "sv", // Svenska - "vi", // Tiếng Việt - "th", // ไทย - "tr", // Türkçe - "uk", // Українська - "zh-hans", // 中文 - "zh-hant", // 中文 - }; - - - /// - /// Initializes a new instance of the class. - /// - public ViewerConfiguration() - { - YamlParser parser = new YamlParser(); - dynamic configuration = parser.GetConfiguration("viewer"); - ConfigurationValuesGetter valuesGetter = new ConfigurationValuesGetter(configuration); - - // get Viewer configuration section from the web.config - this.filesDirectory = valuesGetter.GetStringPropertyValue("filesDirectory", this.filesDirectory); - if (!IsFullPath(this.filesDirectory)) - { - this.filesDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.filesDirectory); - if (!Directory.Exists(this.filesDirectory)) - { - Directory.CreateDirectory(this.filesDirectory); - } - } - - this.cacheFolderName = valuesGetter.GetStringPropertyValue("cacheFolderName", this.cacheFolderName); - if (!IsFullPath(this.cacheFolderName)) - { - var cacheDirectory = Path.Combine(this.filesDirectory, this.cacheFolderName); - if (!Directory.Exists(cacheDirectory)) - { - Directory.CreateDirectory(cacheDirectory); - } - } - - this.fontsDirectory = valuesGetter.GetStringPropertyValue("fontsDirectory", this.fontsDirectory); - this.defaultDocument = valuesGetter.GetStringPropertyValue("defaultDocument", this.defaultDocument); - this.preloadPageCount = valuesGetter.GetIntegerPropertyValue("preloadPageCount", this.preloadPageCount); - this.zoom = valuesGetter.GetBooleanPropertyValue("zoom", this.zoom); - this.search = valuesGetter.GetBooleanPropertyValue("search", this.search); - this.thumbnails = valuesGetter.GetBooleanPropertyValue("thumbnails", this.thumbnails); - this.rotate = valuesGetter.GetBooleanPropertyValue("rotate", this.rotate); - this.htmlMode = valuesGetter.GetBooleanPropertyValue("htmlMode", this.htmlMode); - this.cache = valuesGetter.GetBooleanPropertyValue("cache", this.cache); - this.saveRotateState = valuesGetter.GetBooleanPropertyValue("saveRotateState", this.saveRotateState); - this.watermarkText = valuesGetter.GetStringPropertyValue("watermarkText", this.watermarkText); - this.printAllowed = valuesGetter.GetBooleanPropertyValue("printAllowed", this.printAllowed); - this.showGridLines = valuesGetter.GetBooleanPropertyValue("showGridLines", this.showGridLines); - this.showLanguageMenu = valuesGetter.GetBooleanPropertyValue("showLanguageMenu", this.showLanguageMenu); - this.defaultLanguage = valuesGetter.GetStringPropertyValue("defaultLanguage", this.defaultLanguage); - this.supportedLanguages = valuesGetter.GetStringArrayPropertyValue("supportedLanguages", this.supportedLanguages); - - } - - private static bool IsFullPath(string path) - { - return !string.IsNullOrWhiteSpace(path) - && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1 - && Path.IsPathRooted(path) - && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal); - } - - public void SetFilesDirectory(string filesDirectory) - { - this.filesDirectory = filesDirectory; - } - - public string GetFilesDirectory() - { - return this.filesDirectory; - } - - public void SetCacheFolderName(string cacheFolderName) - { - this.cacheFolderName = cacheFolderName; - } - - public string GetCacheFolderName() - { - return this.cacheFolderName; - } - - public void SetFontsDirectory(string fontsDirectory) - { - this.fontsDirectory = fontsDirectory; - } - - public string GetFontsDirectory() - { - return this.fontsDirectory; - } - - public void SetDefaultDocument(string defaultDocument) - { - this.defaultDocument = defaultDocument; - } - - public string GetDefaultDocument() - { - return this.defaultDocument; - } - - public void SetPreloadPageCount(int preloadPageCount) - { - this.preloadPageCount = preloadPageCount; - } - - public int GetPreloadPageCount() - { - return this.preloadPageCount; - } - - public void SetIsZoom(bool isZoom) - { - this.zoom = isZoom; - } - - public bool GetIsZoom() - { - return this.zoom; - } - - public void SetIsSearch(bool isSearch) - { - this.search = isSearch; - } - - public bool GetIsSearch() - { - return this.search; - } - - public void SetIsThumbnails(bool isThumbnails) - { - this.thumbnails = isThumbnails; - } - - public bool GetIsThumbnails() - { - return this.thumbnails; - } - - public void SetIsRotate(bool isRotate) - { - this.rotate = isRotate; - } - - public bool GetIsRotate() - { - return this.rotate; - } - - public void SetIsHtmlMode(bool isHtmlMode) - { - this.htmlMode = isHtmlMode; - } - - public bool GetIsHtmlMode() - { - return this.htmlMode; - } - - public void SetCache(bool Cache) - { - this.cache = Cache; - } - - public bool GetCache() - { - return this.cache; - } - - public void SetSaveRotateState(bool saveRotateState) - { - this.saveRotateState = saveRotateState; - } - - public bool GetSaveRotateState() - { - return this.saveRotateState; - } - - public void SetWatermarkText(string watermarkText) - { - this.watermarkText = watermarkText; - } - - public string GetWatermarkText() - { - return this.watermarkText; - } - - public void SetPrintAllowed(bool printAllowed) - { - this.printAllowed = printAllowed; - } - - public bool GetPrintAllowed() - { - return this.printAllowed; - } - - public void SetShowGridLines(bool showGridLines) - { - this.showGridLines = showGridLines; - } - - public bool GetShowGridLines() - { - return this.showGridLines; - } - public void SetShowLanguageMenu(bool showLanguageMenu) - { - this.showLanguageMenu = showLanguageMenu; - } - - public bool GetShowLanguageMenu() - { - return this.showLanguageMenu; - } - - public void SetDefaultLanguage(string defaultLanguage) - { - this.defaultLanguage = defaultLanguage; - } - - public string GetDefaultLanguage() - { - return this.defaultLanguage; - } - - public void SetSupportedLanguages(string[] supportedLanguages) - { - this.supportedLanguages = supportedLanguages; - } - - public string[] GetSupportedLanguages() - { - return this.supportedLanguages; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Controllers/ViewerApiController.cs b/Demos/WebForms/src/Products/Viewer/Controllers/ViewerApiController.cs deleted file mode 100644 index dcb922827..000000000 --- a/Demos/WebForms/src/Products/Viewer/Controllers/ViewerApiController.cs +++ /dev/null @@ -1,729 +0,0 @@ -using GroupDocs.Viewer.Exceptions; -using GroupDocs.Viewer.Options; -using GroupDocs.Viewer.Results; -using GroupDocs.Viewer.WebForms.Products.Common.Entity.Web; -using GroupDocs.Viewer.WebForms.Products.Common.Resources; -using GroupDocs.Viewer.WebForms.Products.Common.Util.Comparator; -using GroupDocs.Viewer.WebForms.Products.Viewer.Cache; -using GroupDocs.Viewer.WebForms.Products.Viewer.Config; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Web; -using System.Web.Http; -using System.Web.Http.Cors; -using System.Xml.Linq; -using WebGrease.Css.Extensions; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Controllers -{ - [EnableCors(origins: "*", headers: "*", methods: "*")] - public class ViewerApiController : ApiController - { - private static readonly Common.Config.GlobalConfiguration globalConfiguration = new Common.Config.GlobalConfiguration(); - - private static readonly string cachePath = Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), globalConfiguration.Viewer.GetCacheFolderName()); - - /// - /// Initializes a new instance of the class. - /// - public ViewerApiController() - { - List fontsDirectory = new List(); - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetFontsDirectory())) - { - fontsDirectory.Add(globalConfiguration.Viewer.GetFontsDirectory()); - } - } - - /// - /// Loads Viewer configuration. - /// - /// Viewer configuration. - [HttpGet] - [Route("loadConfig")] - public ViewerConfiguration LoadConfig() - { - return globalConfiguration.Viewer; - } - - /// - /// Gets all files and directories from sample directory: - /// src/DocumentSamples/Viewer/. - /// - /// List of files and directories. - [HttpPost] - [Route("loadFileTree")] - public HttpResponseMessage GetFileTree() - { - try - { - List filesList = new List(); - - if (!string.IsNullOrEmpty(globalConfiguration.Viewer.GetFilesDirectory())) - { - var currentPath = globalConfiguration.Viewer.GetFilesDirectory(); - List allFiles = new List(Directory.GetFiles(currentPath)); - allFiles.AddRange(Directory.GetDirectories(currentPath)); - - string cacheFolderName = globalConfiguration.Viewer.GetCacheFolderName(); - - allFiles.Sort(new FileNameComparator()); - allFiles.Sort(new FileDateComparator()); - - foreach (string file in allFiles) - { - System.IO.FileInfo fileInfo = new System.IO.FileInfo(file); - - // check if current file/folder is hidden - if (!(cacheFolderName.Equals(Path.GetFileName(file)) || - Path.GetFileName(file).StartsWith(".") || - fileInfo.Attributes.HasFlag(FileAttributes.Hidden) || - Path.GetFileName(file).Equals(Path.GetFileName(globalConfiguration.Viewer.GetFilesDirectory())))) - { - FileDescriptionEntity fileDescription = new FileDescriptionEntity - { - guid = Path.GetFullPath(file), - name = Path.GetFileName(file), - - // set is directory true/false - isDirectory = fileInfo.Attributes.HasFlag(FileAttributes.Directory), - }; - - // set file size - if (!fileDescription.isDirectory) - { - fileDescription.size = fileInfo.Length; - } - - // add object to array list - filesList.Add(fileDescription); - } - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, filesList); - } - catch (Exception ex) - { - return this.Request.CreateResponse(HttpStatusCode.OK, Resources.GenerateException(ex)); - } - } - - /// - /// Gets document pages data, dimensions and angles. - /// - /// Posted data with document guid. - /// Document pages data, dimensions and angles. - [HttpPost] - [Route("loadDocumentDescription")] - public HttpResponseMessage GetDocumentData(PostedDataEntity postedData) - { - try - { - LoadDocumentEntity loadDocumentEntity = GetDocumentPages(postedData, globalConfiguration.Viewer.GetPreloadPageCount() == 0); - - // return document description - return this.Request.CreateResponse(HttpStatusCode.OK, loadDocumentEntity); - } - catch (PasswordRequiredException ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.Forbidden, Resources.GenerateException(ex, postedData.password)); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, postedData.password)); - } - } - - /// - /// Gets document page info. - /// - /// Posted data with page number. - /// Document page info. - [HttpPost] - [Route("loadDocumentPage")] - public HttpResponseMessage GetDocumentPage(PostedDataEntity postedData) - { - string password = string.Empty; - try - { - string documentGuid = GetFilePath(postedData.guid); - int pageNumber = postedData.page; - password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - - PageDescriptionEntity page; - if (globalConfiguration.Viewer.GetIsHtmlMode()) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password))) - { - page = this.GetPageDescritpionEntity(htmlViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password))) - { - page = this.GetPageDescritpionEntity(pngViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, page); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.Forbidden, Resources.GenerateException(ex, password)); - } - } - - /// - /// Rotates specific page(s) of the document. - /// - /// Document page number to rotate and rotation angle. - /// Rotated document page object. - [HttpPost] - [Route("rotateDocumentPages")] - public HttpResponseMessage RotateDocumentPages(PostedDataEntity postedData) - { - try - { - var documentGuid = GetFilePath(postedData.guid); - var pageNumber = postedData.pages[0]; - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - // Delete page cache-files before regenerating with another angle. - var cacheFiles = Directory.GetFiles(fileCacheSubFolder).Where(f => Path.GetFileName(f).StartsWith($"p{pageNumber}")); - cacheFiles.ForEach(f => File.Delete(f)); - - // Getting new rotation angle value. - var currentAngle = GetCurrentAngle(pageNumber, Path.Combine(fileCacheSubFolder, "PagesInfo.xml")); - int newAngle = GetNewAngleValue(currentAngle, postedData.angle); - SaveChangedAngleInCache(fileCacheSubFolder, pageNumber, newAngle); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - PageDescriptionEntity page; - if (globalConfiguration.Viewer.GetIsHtmlMode()) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password), pageNumber, newAngle)) - { - page = this.GetPageDescritpionEntity(htmlViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password), pageNumber, newAngle)) - { - page = this.GetPageDescritpionEntity(pngViewer, documentGuid, pageNumber, fileCacheSubFolder); - } - } - - return this.Request.CreateResponse(HttpStatusCode.OK, page); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex)); - } - } - - /// - /// Downloads curerntly viewed document. - /// - /// Path of the document to download. - /// Document stream as attachement. - [HttpGet] - [Route("downloadDocument")] - public HttpResponseMessage DownloadDocument(string path) - { - if (!string.IsNullOrEmpty(path)) - { - path = GetFilePath(path); - - if (File.Exists(path)) - { - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - var fileStream = new FileStream(path, FileMode.Open); - response.Content = new StreamContent(fileStream); - response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); - response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(path); - return response; - } - } - - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - - /// - /// Downloads requested resource file. - /// - /// Name of the file containing resource. - /// Name of the resource file. - /// Document stream as attachement. - [HttpGet] - [Route("resources/{guid}/{resourceName}")] - public HttpResponseMessage GetResource(string guid, string resourceName) - { - if (!string.IsNullOrEmpty(guid)) - { - var path = Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), globalConfiguration.Viewer.GetCacheFolderName()); - path = Path.Combine(path, guid); - path = Path.Combine(path, resourceName); - - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - response.Content = new StreamContent(fileStream); - var fileName = Path.GetFileName(path); - response.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(fileName)); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline"); - response.Content.Headers.ContentDisposition.FileName = fileName; - return response; - } - - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - - /// - /// Uploads document. - /// - /// Uploaded document object. - [HttpPost] - [Route("uploadDocument")] - public HttpResponseMessage UploadDocument() - { - try - { - string url = HttpContext.Current.Request.Form["url"]; - string documentStoragePath = globalConfiguration.Viewer.GetFilesDirectory(); - bool rewrite = bool.Parse(HttpContext.Current.Request.Form["rewrite"]); - string fileSavePath = string.Empty; - if (string.IsNullOrEmpty(url)) - { - if (HttpContext.Current.Request.Files.AllKeys != null) - { - // Get the uploaded document from the Files collection - var httpPostedFile = HttpContext.Current.Request.Files["file"]; - if (httpPostedFile != null) - { - if (rewrite) - { - // Get the complete file path - fileSavePath = Path.Combine(documentStoragePath, httpPostedFile.FileName); - } - else - { - fileSavePath = Resources.GetFreeFileName(documentStoragePath, httpPostedFile.FileName); - } - - // Save the uploaded file to "UploadedFiles" folder - httpPostedFile.SaveAs(fileSavePath); - } - } - } - else - { - using (WebClient client = new WebClient()) - { - // get file name from the URL - Uri uri = new Uri(url); - string fileName = Path.GetFileName(uri.LocalPath); - if (rewrite) - { - // Get the complete file path - fileSavePath = Path.Combine(documentStoragePath, fileName); - } - else - { - fileSavePath = Resources.GetFreeFileName(documentStoragePath, fileName); - } - - // Download the Web resource and save it into the current filesystem folder. - client.DownloadFile(url, fileSavePath); - } - } - - UploadedDocumentEntity uploadedDocument = new UploadedDocumentEntity - { - guid = fileSavePath, - }; - - return this.Request.CreateResponse(HttpStatusCode.OK, uploadedDocument); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex)); - } - } - - /// - /// Loads document pages thumbnails. - /// - /// Posted data with document guid. - /// Data of all document pages. - [HttpPost] - [Route("loadThumbnails")] - public LoadDocumentEntity GetPagesThumbnails(PostedDataEntity loadDocumentRequest) - { - return GetDocumentPages(loadDocumentRequest, true); - } - - /// - /// Loads print version. - /// - /// PostedDataEntity. - /// Data of all document pages. - [HttpPost] - [Route("loadPrint")] - public HttpResponseMessage GetPrintVersion(PostedDataEntity loadDocumentRequest) - { - try - { - LoadDocumentEntity loadPrintDocument = GetDocumentPages(loadDocumentRequest, true, true); - - // return document description - return this.Request.CreateResponse(HttpStatusCode.OK, loadPrintDocument); - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, loadDocumentRequest.password)); - } - } - - /// - /// Loads PDF document. - /// - /// PostedDataEntity. - /// Data of all document pages. - [HttpPost] - [Route("printPdf")] - public HttpResponseMessage PrintPdf(PostedDataEntity loadDocumentRequest) - { - try - { - Stream pdfStream = GetPdf(loadDocumentRequest); - string fileName = Path.GetFileName(loadDocumentRequest.guid); - string pdfFileName = Path.ChangeExtension(fileName, ".pdf"); - - // return document description - HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); - - response.Content = new StreamContent(pdfStream); - response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); - response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); - response.Content.Headers.ContentDisposition.FileName = pdfFileName; - return response; - } - catch (Exception ex) - { - // set exception message - return this.Request.CreateResponse(HttpStatusCode.InternalServerError, Resources.GenerateException(ex, loadDocumentRequest.password)); - } - } - - /// - /// Gets PDF data - /// - /// Posted data with document guid. - /// Document pages data, dimensions and rotation angles. - private Stream GetPdf(PostedDataEntity postedData) - { - string documentGuid = GetFilePath(postedData.guid); - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - if (!File.Exists(documentGuid)) - throw new GroupDocsViewerException("File not found."); - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - Options.LoadOptions loadOptions = GetLoadOptions(password); - - ICustomViewer viewer = globalConfiguration.Viewer.GetIsHtmlMode() - ? (ICustomViewer)new HtmlViewer(documentGuid, cache, loadOptions) - : (ICustomViewer)new PngViewer(documentGuid, cache, loadOptions); - - Stream pdfStream = viewer.GetPdf(); - return pdfStream; - } - - /// - /// Gets page dimensions and rotation angle. - /// - /// Page object. - /// Path to file with pages rotation angles data. - /// Page dimensions and rotation angle. - private static PageDescriptionEntity GetPageInfo(Page page, string pagesInfoPath) - { - int currentAngle = GetCurrentAngle(page.Number, pagesInfoPath); - - PageDescriptionEntity pageDescriptionEntity = new PageDescriptionEntity - { - number = page.Number, - - // we intentionally use the 0 here because we plan to rotate only the page background using height/width - angle = 0, - height = currentAngle == 0 || currentAngle == 180 ? page.Height : page.Width, - width = currentAngle == 0 || currentAngle == 180 ? page.Width : page.Height, - sheetName = page.Name, - }; - - return pageDescriptionEntity; - } - - /// - /// Gets page content as a string. - /// - /// Page number. - /// Document path. - /// Cache path. - /// Page content as a string. - private static string GetPageContent(int pageNumber, string documentGuid, string cachePath, bool printVersion) - { - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - - if (globalConfiguration.Viewer.GetIsHtmlMode() && !printVersion) - { - string htmlFilePath = $"{cachePath}/{fileFolderName}/p{pageNumber}.html"; - return File.ReadAllText(htmlFilePath); - } - else - { - string pngFilePath = $"{cachePath}/{fileFolderName}/p{pageNumber}.png"; - - byte[] imageBytes = null; - using (Image image = Image.FromFile(pngFilePath)) - { - using (MemoryStream m = new MemoryStream()) - { - image.Save(m, image.RawFormat); - imageBytes = m.ToArray(); - } - } - - return Convert.ToBase64String(imageBytes); - } - } - - /// - /// Gets current rotation angle of the page. - /// - /// Page number. - /// Path to file with pages rotation angles data. - /// Current rotation angle of the page. - private static int GetCurrentAngle(int pageNumber, string pagesInfoPath) - { - XDocument xdoc = XDocument.Load(pagesInfoPath); - var pageData = xdoc.Descendants()?.Elements("Number")?.Where(x => int.Parse(x.Value) == pageNumber)?.Ancestors("PageData"); - var angle = pageData?.Elements("Angle").FirstOrDefault(); - - if (angle != null) - { - return int.Parse(angle.Value); - } - - return 0; - } - - /// - /// Gets document load options used in Viewer object constructor. - /// - /// Document password. - /// Load options object. - private static Options.LoadOptions GetLoadOptions(string password) - { - Options.LoadOptions loadOptions = new Options.LoadOptions - { - Password = password, - }; - - return loadOptions; - } - - /// - /// Saves changed page rotation angle in cache. - /// - /// Cache files path. - /// Page number. - /// New angle value. - private static void SaveChangedAngleInCache(string fileCacheSubFolder, int pageNumber, int newAngle) - { - var pagesInfoPath = Path.Combine(fileCacheSubFolder, "PagesInfo.xml"); - - if (File.Exists(pagesInfoPath)) - { - XDocument xdoc = XDocument.Load(pagesInfoPath); - var pageData = xdoc.Descendants()?.Elements("Number")?.Where(x => int.Parse(x.Value) == pageNumber)?.Ancestors("PageData"); - var angle = pageData?.Elements("Angle").FirstOrDefault(); - - if (angle != null) - { - angle.Value = newAngle.ToString(CultureInfo.InvariantCulture); - } - - xdoc.Save(pagesInfoPath); - } - } - - /// - /// Calculates new page rotation angle value. - /// - /// Current page rotation angle value. - /// Posted page rotation angle value. - /// New page rotation angle value. - private static int GetNewAngleValue(int currentAngle, int postedAngle) - { - switch (currentAngle) - { - case 0: - return postedAngle == 90 ? 90 : 270; - case 90: - return postedAngle == 90 ? 180 : 0; - case 180: - return postedAngle == 90 ? 270 : 90; - case 270: - return postedAngle == 90 ? 0 : 180; - default: - return 0; - } - } - - /// - /// Gets document pages data, dimensions and rotation angles. - /// - /// Posted data with document guid. - /// Flag to load all pages. - /// Document pages data, dimensions and rotation angles. - private LoadDocumentEntity GetDocumentPages(PostedDataEntity postedData, bool loadAllPages, bool printVersion = false) - { - // get/set parameters - string documentGuid = GetFilePath(postedData.guid); - string password = string.IsNullOrEmpty(postedData.password) ? null : postedData.password; - - var fileFolderName = Path.GetFileName(documentGuid).Replace(".", "_"); - string fileCacheSubFolder = Path.Combine(cachePath, fileFolderName); - - if (!File.Exists(documentGuid)) - { - throw new GroupDocsViewerException("File not found."); - } - - IViewerCache cache = new FileViewerCache(cachePath, fileCacheSubFolder); - - LoadDocumentEntity loadDocumentEntity; - if (globalConfiguration.Viewer.GetIsHtmlMode() && !printVersion) - { - using (HtmlViewer htmlViewer = new HtmlViewer(documentGuid, cache, GetLoadOptions(password))) - { - loadDocumentEntity = GetLoadDocumentEntity(loadAllPages, documentGuid, fileCacheSubFolder, htmlViewer, printVersion); - } - } - else - { - using (PngViewer pngViewer = new PngViewer(documentGuid, cache, GetLoadOptions(password))) - { - loadDocumentEntity = GetLoadDocumentEntity(loadAllPages, documentGuid, fileCacheSubFolder, pngViewer, printVersion); - } - } - - return loadDocumentEntity; - } - - private string GetFilePath(string filename) - { - if (Path.IsPathRooted(filename)) - return filename; - - return Path.Combine(globalConfiguration.Viewer.GetFilesDirectory(), filename); - } - - private static LoadDocumentEntity GetLoadDocumentEntity(bool loadAllPages, string documentGuid, string fileCacheSubFolder, ICustomViewer customViewer, bool printVersion) - { - if (loadAllPages) - { - customViewer.CreateCache(); - } - - dynamic viewInfo = customViewer.GetViewer().GetViewInfo(ViewInfoOptions.ForHtmlView()); - LoadDocumentEntity loadDocumentEntity = new LoadDocumentEntity(); - - if (!Directory.Exists(cachePath)) - { - Directory.CreateDirectory(cachePath); - } - - string pagesInfoPath; - TryCreatePagesInfoXml(fileCacheSubFolder, viewInfo, out pagesInfoPath); - - foreach (Page page in viewInfo.Pages) - { - PageDescriptionEntity pageData = GetPageInfo(page, pagesInfoPath); - if (loadAllPages) - { - pageData.SetData(GetPageContent(page.Number, documentGuid, cachePath, printVersion)); - } - - loadDocumentEntity.SetPages(pageData); - } - - loadDocumentEntity.SetGuid(documentGuid); - return loadDocumentEntity; - } - - private static void TryCreatePagesInfoXml(string fileCacheSubFolder, dynamic viewInfo, out string pagesInfoPath) - { - if (!Directory.Exists(fileCacheSubFolder)) - { - Directory.CreateDirectory(fileCacheSubFolder); - } - - pagesInfoPath = Path.Combine(fileCacheSubFolder, "PagesInfo.xml"); - - if (!File.Exists(pagesInfoPath)) - { - var xdoc = new XDocument(new XElement("Pages")); - - foreach (var page in viewInfo.Pages) - { - xdoc.Element("Pages") - .Add(new XElement( - "PageData", - new XElement("Number", page.Number), - new XElement("Angle", 0))); - } - - xdoc.Save(pagesInfoPath); - } - } - - private PageDescriptionEntity GetPageDescritpionEntity(ICustomViewer customViewer, string documentGuid, int pageNumber, string fileCacheSubFolder) - { - PageDescriptionEntity page; - customViewer.CreateCache(); - - var viewInfo = customViewer.GetViewer().GetViewInfo(ViewInfoOptions.ForHtmlView()); - page = GetPageInfo(viewInfo.Pages[pageNumber - 1], Path.Combine(fileCacheSubFolder, "PagesInfo.xml")); - page.SetData(GetPageContent(pageNumber, documentGuid, cachePath, false)); - - return page; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs b/Demos/WebForms/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs deleted file mode 100644 index 78da153c7..000000000 --- a/Demos/WebForms/src/Products/Viewer/Entity/Web/RotatedPageEntity.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Newtonsoft.Json; - -namespace GroupDocs.Viewer.WebForms.Products.Viewer.Entity.Web -{ - /// - /// RotatedPageEntity. - /// - public class RotatedPageEntity - { - [JsonProperty] - private int pageNumber; - - [JsonProperty] - private string angle; - - public void SetPageNumber(int number) - { - this.pageNumber = number; - } - - public int GetPageNumber() - { - return this.pageNumber; - } - - public void SetAngle(string angle) - { - this.angle = angle; - } - - public string GetAngle() - { - return this.angle; - } - } -} \ No newline at end of file diff --git a/Demos/WebForms/src/Resources/.gitkeep b/Demos/WebForms/src/Resources/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/Startup.cs b/Demos/WebForms/src/Startup.cs deleted file mode 100644 index bd859377f..000000000 --- a/Demos/WebForms/src/Startup.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace GroupDocs.Viewer.WebForms -{ - public partial class Startup { - public void Configuration() { - // Not implmemented. - } - } -} diff --git a/Demos/WebForms/src/Viewer.aspx b/Demos/WebForms/src/Viewer.aspx deleted file mode 100644 index 1ae5de3b2..000000000 --- a/Demos/WebForms/src/Viewer.aspx +++ /dev/null @@ -1,27 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Viewer.aspx.cs" Inherits="GroupDocs.Viewer.WebForms.Viewer" %> - -<% - GroupDocs.Viewer.WebForms.Products.Common.Config.GlobalConfiguration config = new GroupDocs.Viewer.WebForms.Products.Common.Config.GlobalConfiguration(); -%> - - - - - - Viewer for .NET Web Forms - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WebForms/src/Web.config b/Demos/WebForms/src/Web.config deleted file mode 100644 index f6c0dda55..000000000 --- a/Demos/WebForms/src/Web.config +++ /dev/null @@ -1,207 +0,0 @@ - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WebForms/src/client/.editorconfig b/Demos/WebForms/src/client/.editorconfig deleted file mode 100644 index 6e87a003d..000000000 --- a/Demos/WebForms/src/client/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Editor configuration, see http://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/Demos/WebForms/src/client/.prettierignore b/Demos/WebForms/src/client/.prettierignore deleted file mode 100644 index 931aad992..000000000 --- a/Demos/WebForms/src/client/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -# Add files here to ignore them from prettier formatting diff --git a/Demos/WebForms/src/client/.prettierrc b/Demos/WebForms/src/client/.prettierrc deleted file mode 100644 index 544138be4..000000000 --- a/Demos/WebForms/src/client/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "singleQuote": true -} diff --git a/Demos/WebForms/src/client/README.md b/Demos/WebForms/src/client/README.md deleted file mode 100644 index b148586e6..000000000 --- a/Demos/WebForms/src/client/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Client - -This project was generated using [Nx](https://nx.dev). - -

- -🔎 **Nx is a set of Angular CLI power-ups for modern development.** - -## Quick Start & Documentation - -[Nx Documentation](https://nx.dev) - -[30-minute video showing all Nx features](https://nx.dev/getting-started/what-is-nx) - -[Interactive Tutorial](https://nx.dev/tutorial/01-create-application) - -## Adding capabilities to your workspace - -Nx supports many plugins which add capabilities for developing different types of applications and different tools. - -These capabilities include generating applications, libraries, .etc as well as the devtools to test, and build projects as well. - -Below are some plugins which you can add to your workspace: - -- [Angular](https://angular.io) - - `ng add @nrwl/angular` -- [React](https://reactjs.org) - - `ng add @nrwl/react` -- Web (no framework frontends) - - `ng add @nrwl/web` -- [Nest](https://nestjs.com) - - `ng add @nrwl/nest` -- [Express](https://expressjs.com) - - `ng add @nrwl/express` -- [Node](https://nodejs.org) - - `ng add @nrwl/node` - -## Generate an application - -Run `ng g @nrwl/angular:app my-app` to generate an application. - -> You can use any of the plugins above to generate applications as well. - -When using Nx, you can create multiple applications and libraries in the same workspace. - -## Generate a library - -Run `ng g @nrwl/angular:lib my-lib` to generate a library. - -> You can also use any of the plugins above to generate libraries as well. - -Libraries are sharable across libraries and applications. They can be imported from `@client/mylib`. - -## Development server - -Run `ng serve my-app` for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files. - -## Code scaffolding - -Run `ng g component my-component --project=my-app` to generate a new component. - -## Build - -Run `ng build my-app` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. - -## Running unit tests - -Run `ng test my-app` to execute the unit tests via [Jest](https://jestjs.io). - -Run `npm run affected:test` to execute the unit tests affected by a change. - -## Running end-to-end tests - -Run `ng e2e my-app` to execute the end-to-end tests via [Cypress](https://www.cypress.io). - -Run `npm run affected:e2e` to execute the end-to-end tests affected by a change. - -## Understand your workspace - -Run `npm run dep-graph` to see a diagram of the dependencies of your projects. - -## Further help - -Visit the [Nx Documentation](https://nx.dev) to learn more. diff --git a/Demos/WebForms/src/client/angular.json b/Demos/WebForms/src/client/angular.json deleted file mode 100644 index b25917fa2..000000000 --- a/Demos/WebForms/src/client/angular.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "version": 1, - "newProjectRoot": "", - "projects": { - "viewer": { - "projectType": "application", - "schematics": { - "@nrwl/workspace:component": { - "style": "less" - } - }, - "root": "apps/viewer", - "sourceRoot": "apps/viewer/src", - "prefix": "client", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "../resources/viewer", - "index": "apps/viewer/src/index.html", - "main": "apps/viewer/src/main.ts", - "polyfills": "apps/viewer/src/polyfills.ts", - "tsConfig": "apps/viewer/tsconfig.app.json", - "assets": ["apps/viewer/src/favicon.ico", "apps/viewer/src/assets"], - "styles": ["apps/viewer/src/styles.less"], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "apps/viewer/src/environments/environment.ts", - "with": "apps/viewer/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "extractCss": true, - "namedChunks": false, - "aot": true, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - } - ] - } - } - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "viewer:build" - }, - "configurations": { - "production": { - "browserTarget": "viewer:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "viewer:build" - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "apps/viewer/tsconfig.app.json", - "apps/viewer/tsconfig.spec.json" - ], - "exclude": ["**/node_modules/**", "!apps/viewer/**"] - } - }, - "test": { - "builder": "@nrwl/jest:jest", - "options": { - "jestConfig": "apps/viewer/jest.config.js", - "tsConfig": "apps/viewer/tsconfig.spec.json", - "setupFile": "apps/viewer/src/test-setup.ts" - } - } - } - }, - "viewer-e2e": { - "root": "apps/viewer-e2e", - "sourceRoot": "apps/viewer-e2e/src", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "apps/viewer-e2e/cypress.json", - "tsConfig": "apps/viewer-e2e/tsconfig.e2e.json", - "devServerTarget": "viewer:serve" - }, - "configurations": { - "production": { - "devServerTarget": "viewer:serve:production" - } - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": "apps/viewer-e2e/tsconfig.e2e.json", - "exclude": ["**/node_modules/**", "!apps/viewer-e2e/**"] - } - } - } - } - }, - "cli": { - "warnings": { - "typescriptMismatch": false, - "versionMismatch": false - }, - "defaultCollection": "@nrwl/angular" - }, - "schematics": { - "@nrwl/angular:application": { - "unitTestRunner": "jest", - "e2eTestRunner": "cypress" - }, - "@nrwl/angular:library": { - "unitTestRunner": "jest" - } - }, - "defaultProject": "viewer" -} diff --git a/Demos/WebForms/src/client/apps/.gitkeep b/Demos/WebForms/src/client/apps/.gitkeep deleted file mode 100644 index 8b1378917..000000000 --- a/Demos/WebForms/src/client/apps/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/cypress.json b/Demos/WebForms/src/client/apps/viewer-e2e/cypress.json deleted file mode 100644 index 6df3fe526..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/cypress.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", - "integrationFolder": "./src/integration", - "pluginsFile": "./src/plugins/index", - "supportFile": false, - "video": true, - "videosFolder": "../../dist/cypress/apps/viewer-e2e/videos", - "screenshotsFolder": "../../dist/cypress/apps/viewer-e2e/screenshots", - "chromeWebSecurity": false -} diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/fixtures/example.json b/Demos/WebForms/src/client/apps/viewer-e2e/src/fixtures/example.json deleted file mode 100644 index 294cbed6c..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/fixtures/example.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io" -} diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/integration/app.spec.ts b/Demos/WebForms/src/client/apps/viewer-e2e/src/integration/app.spec.ts deleted file mode 100644 index 29f39937b..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/integration/app.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { getGreeting } from '../support/app.po'; - -describe('viewer', () => { - beforeEach(() => cy.visit('/')); - - it('should display welcome message', () => { - getGreeting().contains('Welcome to viewer!'); - }); -}); diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/plugins/index.js b/Demos/WebForms/src/client/apps/viewer-e2e/src/plugins/index.js deleted file mode 100644 index bc34d630e..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/plugins/index.js +++ /dev/null @@ -1,22 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor'); - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - - // Preprocess Typescript - on('file:preprocessor', preprocessTypescript(config)); -}; diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/app.po.ts b/Demos/WebForms/src/client/apps/viewer-e2e/src/support/app.po.ts deleted file mode 100644 index 329342469..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/app.po.ts +++ /dev/null @@ -1 +0,0 @@ -export const getGreeting = () => cy.get('h1'); diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/commands.ts b/Demos/WebForms/src/client/apps/viewer-e2e/src/support/commands.ts deleted file mode 100644 index ca4d256f3..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/commands.ts +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/index.ts b/Demos/WebForms/src/client/apps/viewer-e2e/src/support/index.ts deleted file mode 100644 index 3d469a6b6..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/src/support/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.e2e.json b/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.e2e.json deleted file mode 100644 index 629b4c1cc..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.e2e.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "sourceMap": false, - "outDir": "../../dist/out-tsc" - }, - "include": ["src/**/*.ts"] -} diff --git a/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.json b/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.json deleted file mode 100644 index ee6531bc0..000000000 --- a/Demos/WebForms/src/client/apps/viewer-e2e/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["cypress", "node"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/WebForms/src/client/apps/viewer/browserslist b/Demos/WebForms/src/client/apps/viewer/browserslist deleted file mode 100644 index 80848532e..000000000 --- a/Demos/WebForms/src/client/apps/viewer/browserslist +++ /dev/null @@ -1,12 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -> 0.5% -last 2 versions -Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/Demos/WebForms/src/client/apps/viewer/jest.config.js b/Demos/WebForms/src/client/apps/viewer/jest.config.js deleted file mode 100644 index faba4818c..000000000 --- a/Demos/WebForms/src/client/apps/viewer/jest.config.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - name: 'viewer', - preset: '../../jest.config.js', - coverageDirectory: '../../coverage/apps/viewer', - snapshotSerializers: [ - 'jest-preset-angular/AngularSnapshotSerializer.js', - 'jest-preset-angular/HTMLCommentSerializer.js' - ] -}; diff --git a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.html b/Demos/WebForms/src/client/apps/viewer/src/app/app.component.html deleted file mode 100644 index 6c494d302..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.less b/Demos/WebForms/src/client/apps/viewer/src/app/app.component.less deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.spec.ts b/Demos/WebForms/src/client/apps/viewer/src/app/app.component.spec.ts deleted file mode 100644 index 9a05e0434..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { TestBed, async } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent] - }).compileComponents(); - })); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have as title 'viewer'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('viewer'); - }); - - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain( - 'Welcome to viewer!' - ); - }); -}); diff --git a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.ts b/Demos/WebForms/src/client/apps/viewer/src/app/app.component.ts deleted file mode 100644 index b67ea4d57..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/app/app.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'client-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.less'] -}) -export class AppComponent { - title = 'viewer'; -} diff --git a/Demos/WebForms/src/client/apps/viewer/src/app/app.module.ts b/Demos/WebForms/src/client/apps/viewer/src/app/app.module.ts deleted file mode 100644 index d65153072..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/app/app.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; - -import { AppComponent } from './app.component'; -import { ViewerModule } from "@groupdocs.examples.angular/viewer"; - -@NgModule({ - declarations: [AppComponent], - imports: [BrowserModule, - ViewerModule], - providers: [], - bootstrap: [AppComponent] -}) -export class AppModule {} diff --git a/Demos/WebForms/src/client/apps/viewer/src/assets/.gitkeep b/Demos/WebForms/src/client/apps/viewer/src/assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/client/apps/viewer/src/favicon.ico b/Demos/WebForms/src/client/apps/viewer/src/favicon.ico deleted file mode 100644 index 8081c7cea..000000000 Binary files a/Demos/WebForms/src/client/apps/viewer/src/favicon.ico and /dev/null differ diff --git a/Demos/WebForms/src/client/apps/viewer/src/index.html b/Demos/WebForms/src/client/apps/viewer/src/index.html deleted file mode 100644 index 4675b4d4e..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Viewer - - - - - - - - - diff --git a/Demos/WebForms/src/client/apps/viewer/src/test-setup.ts b/Demos/WebForms/src/client/apps/viewer/src/test-setup.ts deleted file mode 100644 index 8d88704e8..000000000 --- a/Demos/WebForms/src/client/apps/viewer/src/test-setup.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular'; diff --git a/Demos/WebForms/src/client/apps/viewer/tsconfig.app.json b/Demos/WebForms/src/client/apps/viewer/tsconfig.app.json deleted file mode 100644 index 827b63017..000000000 --- a/Demos/WebForms/src/client/apps/viewer/tsconfig.app.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": [] - }, - "include": ["**/*.ts"], - "exclude": ["src/test-setup.ts", "**/*.spec.ts"] -} diff --git a/Demos/WebForms/src/client/apps/viewer/tsconfig.json b/Demos/WebForms/src/client/apps/viewer/tsconfig.json deleted file mode 100644 index e5decd5e2..000000000 --- a/Demos/WebForms/src/client/apps/viewer/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["node", "jest"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/WebForms/src/client/apps/viewer/tsconfig.spec.json b/Demos/WebForms/src/client/apps/viewer/tsconfig.spec.json deleted file mode 100644 index cfff29a54..000000000 --- a/Demos/WebForms/src/client/apps/viewer/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "files": ["src/test-setup.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] -} diff --git a/Demos/WebForms/src/client/apps/viewer/tslint.json b/Demos/WebForms/src/client/apps/viewer/tslint.json deleted file mode 100644 index df7583477..000000000 --- a/Demos/WebForms/src/client/apps/viewer/tslint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tslint.json", - "rules": { - "directive-selector": [true, "attribute", "client", "camelCase"], - "component-selector": [true, "element", "client", "kebab-case"] - } -} diff --git a/Demos/WebForms/src/client/jest.config.js b/Demos/WebForms/src/client/jest.config.js deleted file mode 100644 index caba6c4f7..000000000 --- a/Demos/WebForms/src/client/jest.config.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], - transform: { - '^.+\\.(ts|js|html)$': 'ts-jest' - }, - resolver: '@nrwl/jest/plugins/resolver', - moduleFileExtensions: ['ts', 'js', 'html'], - collectCoverage: true, - coverageReporters: ['html'] -}; diff --git a/Demos/WebForms/src/client/libs/.gitkeep b/Demos/WebForms/src/client/libs/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/client/nx.json b/Demos/WebForms/src/client/nx.json deleted file mode 100644 index 11d643c59..000000000 --- a/Demos/WebForms/src/client/nx.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "npmScope": "client", - "implicitDependencies": { - "angular.json": "*", - "package.json": "*", - "tsconfig.json": "*", - "tslint.json": "*", - "nx.json": "*" - }, - "projects": { - "viewer-e2e": { - "tags": [] - }, - "viewer": { - "tags": [] - } - } -} diff --git a/Demos/WebForms/src/client/package.json b/Demos/WebForms/src/client/package.json deleted file mode 100644 index e0c3aac6e..000000000 --- a/Demos/WebForms/src/client/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "client", - "version": "0.0.0", - "license": "MIT", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "..\\..\\packages\\Node-Kit.11.1.0.1\\node\\win\\node.exe .\\node_modules\\@angular\\cli\\bin\\ng build", - "test": "ng test", - "lint": "nx lint && ng lint", - "e2e": "ng e2e", - "affected:apps": "nx affected:apps", - "affected:libs": "nx affected:libs", - "affected:build": "nx affected:build", - "affected:e2e": "nx affected:e2e", - "affected:test": "nx affected:test", - "affected:lint": "nx affected:lint", - "affected:dep-graph": "nx affected:dep-graph", - "affected": "nx affected", - "format": "nx format:write", - "format:write": "nx format:write", - "format:check": "nx format:check", - "update": "ng update @nrwl/workspace", - "update:check": "ng update", - "workspace-schematic": "nx workspace-schematic", - "dep-graph": "nx dep-graph", - "help": "nx help" - }, - "private": true, - "dependencies": { - "@angular/animations": "^8.0.0", - "@angular/common": "^8.0.0", - "@angular/compiler": "^8.0.0", - "@angular/core": "^8.0.0", - "@angular/forms": "^8.0.0", - "@angular/platform-browser": "^8.0.0", - "@angular/platform-browser-dynamic": "^8.0.0", - "@angular/router": "^8.0.0", - "core-js": "^2.5.4", - "rxjs": "~6.4.0", - "zone.js": "^0.9.1", - "@nrwl/angular": "^8.2.0", - "@groupdocs.examples.angular/viewer": "^0.8.82" - }, - "devDependencies": { - "cypress": "~3.3.1", - "@nrwl/cypress": "8.2.0", - "@nrwl/jest": "8.2.0", - "jest": "24.1.0", - "@types/jest": "24.0.9", - "ts-jest": "24.0.0", - "jest-preset-angular": "7.0.0", - "@angular/compiler-cli": "^8.0.0", - "@angular/language-service": "^8.0.0", - "@angular-devkit/build-angular": "^0.800.0", - "codelyzer": "~5.0.1", - "@nrwl/workspace": "8.2.0", - "@types/node": "~8.9.4", - "dotenv": "6.2.0", - "ts-node": "~7.0.0", - "tslint": "~5.11.0", - "typescript": "~3.4.5", - "prettier": "1.16.4", - "@angular/cli": "8.0.0" - } -} diff --git a/Demos/WebForms/src/client/tools/schematics/.gitkeep b/Demos/WebForms/src/client/tools/schematics/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/Demos/WebForms/src/client/tools/tsconfig.tools.json b/Demos/WebForms/src/client/tools/tsconfig.tools.json deleted file mode 100644 index 82bd1f098..000000000 --- a/Demos/WebForms/src/client/tools/tsconfig.tools.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../dist/out-tsc/tools", - "rootDir": ".", - "module": "commonjs", - "target": "es5", - "types": ["node"] - }, - "include": ["**/*.ts"] -} diff --git a/Demos/WebForms/src/client/tsconfig.json b/Demos/WebForms/src/client/tsconfig.json deleted file mode 100644 index a5099b580..000000000 --- a/Demos/WebForms/src/client/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "rootDir": ".", - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "importHelpers": true, - "target": "es2015", - "module": "esnext", - "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "dom"], - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "baseUrl": ".", - "paths": {} - }, - "exclude": ["node_modules", "tmp"] -} diff --git a/Demos/WebForms/src/client/tslint.json b/Demos/WebForms/src/client/tslint.json deleted file mode 100644 index 2533001b6..000000000 --- a/Demos/WebForms/src/client/tslint.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "rulesDirectory": [ - "node_modules/@nrwl/workspace/src/tslint", - "node_modules/codelyzer" - ], - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "deprecation": { - "severity": "warn" - }, - "forin": true, - "import-blacklist": [true, "rxjs/Rx"], - "interface-over-type-literal": true, - "member-access": false, - "member-ordering": [ - true, - { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] - } - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": [true, "ignore-params"], - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "prefer-const": true, - "radix": true, - "triple-equals": [true, "allow-null-check"], - "unified-signatures": true, - "variable-name": false, - "nx-enforce-module-boundaries": [ - true, - { - "allow": [], - "depConstraints": [ - { - "sourceTag": "*", - "onlyDependOnLibsWithTags": ["*"] - } - ] - } - ], - "directive-selector": [true, "attribute", "app", "camelCase"], - "component-selector": [true, "element", "app", "kebab-case"], - "no-conflicting-lifecycle": true, - "no-host-metadata-property": true, - "no-input-rename": true, - "no-inputs-metadata-property": true, - "no-output-native": true, - "no-output-on-prefix": true, - "no-output-rename": true, - "no-outputs-metadata-property": true, - "template-banana-in-box": true, - "template-no-negated-async": true, - "use-lifecycle-interface": true, - "use-pipe-transform-interface": true - } -} diff --git a/Demos/WebForms/src/configuration.yml b/Demos/WebForms/src/configuration.yml deleted file mode 100644 index d2462f7b7..000000000 --- a/Demos/WebForms/src/configuration.yml +++ /dev/null @@ -1,103 +0,0 @@ -################################################ -# Server configurations -################################################ -server: - type: simple - applicationContextPath: / - adminContextPath: /admin - connector: - type: http - port: 8080 - - -################################################ -# Application (global) configurations -################################################ -application: - # License path - # Absolute path to GroupDocs license file - licensePath: 'Licenses/GroupDocs.Viewer.NET.lic' - -################################################ -# Common configurations -################################################ -common: - # File rewriting on document uploading - # Set false to keep both files - # Set true to replace files with same name - rewrite: true - # Page navigation - # Set false to disable document navigation (go to next, previous, last and first page) - pageSelector: true - # Document download - # Set false to disable document download - download: true - # Document upload - # Set false to disable document upload - upload: true - # Document print - # Set false to disable document print - print: true - # File browser - # Set false to disable document browse - browse: true - # Set false to disable right mouse click - enableRightClick: true - -################################################ -# GroupDocs.Viewer configurations -################################################ -viewer: - # Files directory path - # Absolute path to files directory - filesDirectory: 'DocumentSamples/Viewer' - # Cache folder name - # Relative path to cache directory - cacheFolderName: 'cache' - # Fonts path - # Absolute path to custom fonts directory - fontsDirectory: '' - # Default document - # Absolute path to default document - defaultDocument: '' - # Pages preload - # How many pages from a document should be loaded, remaining pages will be loaded on page scrolling - # Set 0 to load all pages at once - preloadPageCount: 0 - # HTML rendering mode - # Set false for image mode - # Set true for HTML mode - htmlMode: true - # Document zoom - # Set false to disable document zooming - zoom: true - # Document search - # Set false to disable document text search - search: true - # Thumbnails - # Set false to disable thumbnails - thumbnails: true - # Page rotation - # Set false to disable pages rotation - rotate: true - # Using cache - # Set true to enable cache - cache: true - # Set true to enable page rotation saving - saveRotateState: true - # Enter text which will be used as a watermark - watermarkText: "" - # Print secured documents mode - # Set false to ignore document print security - # Set true to check document print security - printAllowed: true - # Adds/removes grid lines in the excel documents - # presentation regardless of whether they are in - # the document itself or not - showGridLines: true - # Shows/hides language menu - showLanguageMenu: true - # Default UI language - defaultLanguage: 'en' - # Supported languages - supportedLanguages: ["ar", "ca", "cs", "da", "de", "el", "en", "es", "fil", "fr", "he", "hi", "id", "it", "ja", "kk", "ko", "ms", "nl", "pl", "pt", "ro", "ru", "sv", "vi", "th", "tr", "uk", "zh-hans", "zh-hant" ] \ No newline at end of file diff --git a/Demos/WebForms/src/package.json b/Demos/WebForms/src/package.json deleted file mode 100644 index e5b5ecc89..000000000 --- a/Demos/WebForms/src/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "groupdocs.viewer-for-.net-webforms", - "version": "1.0.0", - "description": "![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-webforms/development/src/Resources/viewer/images/banner.png \"GroupDocs.Viewer\") # GroupDocs.Viewer for .NET Web.Forms Example ###### version 1.9.0", - "main": "gulpfile.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms.git" - }, - "author": "", - "license": "MIT", - "bugs": { - "url": "https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms/issues" - }, - "homepage": "https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms#readme" -} diff --git a/Demos/WebForms/src/packages.config b/Demos/WebForms/src/packages.config deleted file mode 100644 index a84ddb1e0..000000000 --- a/Demos/WebForms/src/packages.config +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/GroupDocs.Viewer.WebForms.Test.csproj b/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/GroupDocs.Viewer.WebForms.Test.csproj deleted file mode 100644 index 9b0e92e85..000000000 --- a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/GroupDocs.Viewer.WebForms.Test.csproj +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - Debug - AnyCPU - {C0E13EC1-3C31-4D1C-AD67-A68D228FE8C9} - Library - Properties - GroupDocs.Viewer.WebForms.Test - GroupDocs.Viewer.WebForms.Test - v4.6.1 - 512 - true - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll - - - ..\packages\Huygens.1.4.5\lib\net46\Huygens.dll - - - ..\packages\Moq.4.10.1\lib\net45\Moq.dll - - - ..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll - - - - - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - - - {7b296703-ac7b-4fa6-bd42-bec76d0c6ddc} - GroupDocs.Viewer.WebForms - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - \ No newline at end of file diff --git a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/Properties/AssemblyInfo.cs b/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/Properties/AssemblyInfo.cs deleted file mode 100644 index 4d6a60248..000000000 --- a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Общие сведения об этой сборке предоставляются следующим набором -// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения, -// связанные со сборкой. -[assembly: AssemblyTitle("GroupDocs.Viewer.WebForms.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GroupDocs.Viewer.WebForms.Test")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми -// для компонентов COM. Если необходимо обратиться к типу в этой сборке через -// COM, задайте атрибуту ComVisible значение TRUE для этого типа. -[assembly: ComVisible(false)] - -// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM -[assembly: Guid("c0e13ec1-3c31-4d1c-ad67-a68d228fe8c9")] - -// Сведения о версии сборки состоят из следующих четырех значений: -// -// Основной номер версии -// Дополнительный номер версии -// Номер сборки -// Редакция -// -// Можно задать все значения или принять номер сборки и номер редакции по умолчанию. -// используя "*", как показано ниже: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/ViewerTest.cs b/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/ViewerTest.cs deleted file mode 100644 index 06761cb5c..000000000 --- a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/ViewerTest.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Huygens; -using NUnit.Framework; -using System; -using System.Collections.Generic; - -namespace GroupDocs.Viewer.WebForms.Test -{ - [TestFixture] - public class ViewerTest - { - [Test] - public void ViewStatusTest() - { - string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src"; - using (var server = new DirectServer(path)) - { - var request = new SerialisableRequest - { - Method = "GET", - RequestUri = "/viewer", - Content = null - }; - var result = server.DirectCall(request); - Assert.That(result.StatusCode, Is.EqualTo(200)); - } - } - - [Test] - public void FileTreeStatusCodeTest() - { - string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src"; - using (var server = new DirectServer(path)) - { - var request = new SerialisableRequest - { - Method = "POST", - RequestUri = "/loadfiletree", - Content = null, - Headers = new Dictionary{ - { "Content-Type", "application/json"} - } - }; - - var result = server.DirectCall(request); - Assert.That(result.StatusCode, Is.EqualTo(200)); - } - } - } -} diff --git a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/app.config b/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/app.config deleted file mode 100644 index d6afccd48..000000000 --- a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/app.config +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/packages.config b/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/packages.config deleted file mode 100644 index 57ef4e91c..000000000 --- a/Demos/WebForms/tests/GroupDocs.Viewer.WebForms.Test/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Demos/WinForms/README.md b/Demos/WinForms/README.md deleted file mode 100644 index 3fafaca3d..000000000 --- a/Demos/WinForms/README.md +++ /dev/null @@ -1,87 +0,0 @@ -![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") -# GroupDocs.Viewer for .NET Windows Forms Example -###### version 1.0.0 - -[![GitHub license](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WebForms.svg)](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/blob/master/Demos/WinForms/LICENSE) - -## System Requirements -- .NET Framework 4.6.1 -- Visual Studio 2019 - - -## Document Viewer API for .NET Windows Forms - -[GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) API allows you to view over 170 document formats including **DOCX**, **PDF**, **PPT**, **XLS**, among many others without any additional dependencies. Thanks to its flexible configuration it can be configured to **view documents as images or as HTML5**. - -In order to demonstrate GroupDocs.Viewer for .NET reach and powerful features we prepared a modern **document viewer** Windows Forms UI example. Which can be used as a standalone application or easily integrated into your project. - -**Note:** without a license application will run in trial mode, purchase [GroupDocs.Viewer for .NET license](https://purchase.groupdocs.com/order-online-step-1-of-8.aspx) or request [GroupDocs.Viewer for .NET temporary license](https://purchase.groupdocs.com/temporary-license). - -## Supported document Formats - -| Family | Formats | -| --------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------- | -| Archive formats | `ZIP`, `TAR`, `BZ2`, `RAR`, `GZIP` | -| Apple formats | `Numbers` | -| PDF formats | `PDF`, `XPS`, `OXPS`, `TEX` | -| CAD formats | `DXF`, `DWG` , `DWT`, `STL`, `IFC`,`DWF` , `DWFX`, `DGN`, `PLT`,`CF2`,`OBJ`, `HPG`, `IGS` | -| Microsoft Word | `DOC`, `DOCM` , `DOCX`, `DOT`, `DOTM`, `DOTX`,`RTF` | -| Microsoft Excel | `XLS`, `XLSB`, `XLSM`, `XLSX`, `XLT`, `XLTM`, `XLTX`,`Excel 2003 XML`,`XLAM` | -| Microsoft PowerPoint | `PPT`, `POT`, `POTM`, `POTX`, `PPS`, `PPSM`, `PPSX`, `PPTM`, `PPTX` | -| Microsoft Visio | `VSD`,`VSDX`,`VSDM`,`VDW`, `VDX`, `VSDX`, `VSS`,`VSSX`,`VSSM`,`VST`,`VSTX`, `VSX`, `VTX`,`VSTM` | -| Microsoft Project | `MPP`, `MPT`,`MPX` | -| Help files | `CHM` | -| Email formats | `EML`, `EMLX`, `MSG`, `NSF`, `MBOX`, `PST`,`OST`, `VCF` | -| OpenDocument Formats | `ODT`, `ODP`,`FODP`, `ODS`,`FODS`, `OTT`,`OTS`,`ODG`,`FODG`,`OTG`,`OTP`,`SXC` | -| Plain Text File | `TXT`,`TSV` | -| Comma-Separated Values | `CSV` | -| HyperText Markup Language | `HTML`, `MHT`, `MHTML`, `SVG`,`SVGZ` | -| Extensible Markup Language | `XML`,`XML`, `XPS` | -| AutoCAD Drawing File Format | `DGN`, `DWG`, `DXF` | -| Image files | `BMP`, `CAL`, `DCX`,`CGM`,`PCL`,`PSB`, `DIB`, `EMF`,`EMZ`,`WEBP`,`DNG`,`CDR`,`CMX`, `GIF`,
`JP2`, `JPG`,`JPF`,`JPM`,`J2C`,`J2K`,`JPC`,`JPX`,`MIL`, `MIL`, `PCD`, `PCT`, `PCX`, `PNG`,
`Animated PNG`, `PSD`,`PS`, `RAS`, `TGA`,`TIFF`,`WMF`,`WMZ`,`EPS`, `AI` | -| Electronic publication | `EPUB`,`MOBI`,`DJVU` | -| Windows Icon | `ICO` | -| Medical image files | `DCM` | -| Programming Language Formats | `AS`, `AS3`, `ASM`, `BAT`, `C`, `CC`, `CMAKE`, `CPP`, `CS`,`VB`, `CSS`, `CXX`, `DIFF`, `ERB`,
`GROOVY`, `H`,`HAML`, `HH`, `JAVA`, `JS`, `JSON`, `LESS`, `LOG`, `M`, `MAKE`, `MD`, `ML`,
`MM`, `PHP`, `PL`, `PROPERTIES`, `PY`, `RB`, `RST`, `SASS`, `SCALA`, `SCM`, `SCRIPT`,
`SH`, `SML`, `SQL`, `VIM`, `YAML`| - -## Demo Video - -

- -

- -## Features -- Open password protected documents -- Support over 170+ documents and image formats including Word, Excel, PowerPoint -- Smooth page navigation -- Smooth document scrolling - -## How to run - -You can run this sample by one of following methods - -#### Build from source - -Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WinForms/archive/main.zip) from github or clone this repository. - -```bash -git clone https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-WinForms -``` - -Open solution in the VisualStudio. -Restore packages and build. -Run compiled application - -## License -The MIT License (MIT). - -Please have a look at the LICENSE.md for more details - -## GroupDocs Document Viewer on other platforms/frameworks - -- JAVA DropWizard [Document Viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Dropwizard) -- JAVA Spring boot [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java-Spring) -- .NET MVC [Document viewer](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET-MVC) - - -[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/family) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/WinForms/appveyor.yml b/Demos/WinForms/appveyor.yml deleted file mode 100644 index 80c053167..000000000 --- a/Demos/WinForms/appveyor.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 1.0.{build} -before_build: -- cmd: cd src -- cmd: nuget restore -build: - verbosity: minimal \ No newline at end of file diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/packages.config b/Demos/WinForms/src/GroupDocs.Viewer.WinForms/packages.config deleted file mode 100644 index f25110957..000000000 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Demos/WinForms/.gitignore b/Demos/Windows Forms/.gitignore similarity index 100% rename from Demos/WinForms/.gitignore rename to Demos/Windows Forms/.gitignore diff --git a/Demos/WinForms/LICENSE b/Demos/Windows Forms/LICENSE similarity index 100% rename from Demos/WinForms/LICENSE rename to Demos/Windows Forms/LICENSE diff --git a/Demos/Windows Forms/README.md b/Demos/Windows Forms/README.md new file mode 100644 index 000000000..5d8337038 --- /dev/null +++ b/Demos/Windows Forms/README.md @@ -0,0 +1,56 @@ +![Alt text](https://raw.githubusercontent.com/groupdocs-viewer/groupdocs-viewer.github.io/master/resources/image/banner.png "GroupDocs.Viewer") + +# GroupDocs.Viewer for .NET Windows Forms Example + +![GitHub](https://img.shields.io/github/license/groupdocs-viewer/GroupDocs.Viewer-for-.NET) + +## System Requirements +- .NET Framework 4.8 +- Visual Studio 2022 + +## Document Viewer API for .NET Windows Forms + +In order to demonstrate [GroupDocs.Viewer for .NET](https://products.groupdocs.com/viewer/net) reach and powerful features we prepared **document viewer** demo. Which can be used as a standalone application or easily integrated into your project. + +## Supported Document Formats + +GroupDocs.Viewer for .NET enables you to render Microsoft Word, Microsoft Excel, Microsoft PowerPoint, and many more file types in HTML, PDF, PNG, and JPEG formats. The complete list of the supported document and file formats can be found in the [Supported document formats](https://docs.groupdocs.com/viewer/net/supported-document-formats/) documentation article. + +## Demo Animation + +

+ +

+ +## Features +- Open password protected documents +- Support over 170+ documents and image formats including Word, Excel, PowerPoint +- Smooth page navigation +- Smooth document scrolling + +## How to run + +Download [source code](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/archive/refs/heads/master.zip) from github or clone this repository. + +```bash +git clone git@github.com:groupdocs-viewer/GroupDocs.Viewer-for-.NET.git +``` + +Navigate to `Demos\Windows Forms\src` and open solution in the VisualStudio. Run the application + +## License + +The MIT License (MIT). + +Please have a look at the [LICENSE](LICENSE) for more details + +## More Demo Projects + +- [Java Dropwizard Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Dropwizard) +- [Java Spring Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-Java/tree/master/Demos/Spring) +- [ASP.NET Core Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Core) +- [ASP.NET MVC Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20MVC) +- [ASP.NET Web Forms Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/ASP.NET%20Web%20Forms) +- [WPF Demo](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Demos/WPF) + +[Home](https://www.groupdocs.com/) | [Product Page](https://products.groupdocs.com/viewer/net) | [Documentation](https://docs.groupdocs.com/viewer/net/) | [Demo](https://products.groupdocs.app/viewer/total) | [API Reference](https://apireference.groupdocs.com/net/viewer) | [Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET/tree/master/Examples) | [Blog](https://blog.groupdocs.com/category/viewer/) | [Free Support](https://forum.groupdocs.com/c/viewer) | [Temporary License](https://purchase.groupdocs.com/temporary-license) diff --git a/Demos/WinForms/Resources/groupdocs.viewer.winforms.gif b/Demos/Windows Forms/docs/groupdocs.viewer.winforms.gif similarity index 100% rename from Demos/WinForms/Resources/groupdocs.viewer.winforms.gif rename to Demos/Windows Forms/docs/groupdocs.viewer.winforms.gif diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/App.config b/Demos/Windows Forms/src/App.config similarity index 89% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/App.config rename to Demos/Windows Forms/src/App.config index a21c98d89..658c14a70 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/App.config +++ b/Demos/Windows Forms/src/App.config @@ -1,75 +1,75 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.Designer.cs b/Demos/Windows Forms/src/EnterPasswordBox.Designer.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.Designer.cs rename to Demos/Windows Forms/src/EnterPasswordBox.Designer.cs diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.cs b/Demos/Windows Forms/src/EnterPasswordBox.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.cs rename to Demos/Windows Forms/src/EnterPasswordBox.cs diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.resx b/Demos/Windows Forms/src/EnterPasswordBox.resx similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/EnterPasswordBox.resx rename to Demos/Windows Forms/src/EnterPasswordBox.resx diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/GroupDocs.Viewer.WinForms.csproj b/Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.csproj similarity index 93% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/GroupDocs.Viewer.WinForms.csproj rename to Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.csproj index f67db19a3..d1e28adde 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/GroupDocs.Viewer.WinForms.csproj +++ b/Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.csproj @@ -1,105 +1,106 @@ - - - - - Debug - AnyCPU - {B57F5DB0-7F9D-4B27-97C4-E60321D7D094} - WinExe - GroupsDocs.Viewer.Forms.UI - GroupsDocs.Viewer.Forms.UI - v4.6.1 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\GroupDocs.Viewer.22.7.0\lib\net40\GroupDocs.Viewer.dll - - - - - - - - - - - - - - - - Form - - - EnterPasswordBox.cs - - - Form - - - MainForm.cs - - - - - - EnterPasswordBox.cs - - - MainForm.cs - - - ResXFileCodeGenerator - Designer - Resources.Designer.cs - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - - - - - - - - - + + + + + Debug + AnyCPU + {B57F5DB0-7F9D-4B27-97C4-E60321D7D094} + WinExe + GroupsDocs.Viewer.Forms.UI + GroupsDocs.Viewer.Forms.UI + v4.8 + 512 + true + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + packages\GroupDocs.Viewer.22.9.0\lib\net40\GroupDocs.Viewer.dll + + + + + + + + + + + + + + + + Form + + + EnterPasswordBox.cs + + + Form + + + MainForm.cs + + + + + + EnterPasswordBox.cs + + + MainForm.cs + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms.sln b/Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.sln similarity index 89% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms.sln rename to Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.sln index e9402f321..d0ef98c17 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms.sln +++ b/Demos/Windows Forms/src/GroupDocs.Viewer.WinForms.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.WinForms", "GroupDocs.Viewer.WinForms\GroupDocs.Viewer.WinForms.csproj", "{B57F5DB0-7F9D-4B27-97C4-E60321D7D094}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroupDocs.Viewer.WinForms", "GroupDocs.Viewer.WinForms.csproj", "{B57F5DB0-7F9D-4B27-97C4-E60321D7D094}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.Designer.cs b/Demos/Windows Forms/src/MainForm.Designer.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.Designer.cs rename to Demos/Windows Forms/src/MainForm.Designer.cs diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.cs b/Demos/Windows Forms/src/MainForm.cs similarity index 98% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.cs rename to Demos/Windows Forms/src/MainForm.cs index 2a930e849..f4e4252f8 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.cs +++ b/Demos/Windows Forms/src/MainForm.cs @@ -1,10 +1,10 @@ -using GroupDocs.Viewer.Exceptions; -using GroupDocs.Viewer.Options; -using GroupsDocs.Viewer.Forms.UI; +using GroupsDocs.Viewer.Forms.UI; using System; using System.IO; using System.Threading; using System.Windows.Forms; +using GroupDocs.Viewer.Exceptions; +using GroupDocs.Viewer.Options; namespace GroupDocs.Viewer.Forms.UI { @@ -18,7 +18,7 @@ public partial class MainForm : Form private MemoryPageStreamFactory MemoryPageStreamFactory { get; set; } - private GroupDocs.Viewer.Viewer Viewer { get; set; } + private Viewer Viewer { get; set; } private int CurrentPage { get; set; } = 1; diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.resx b/Demos/Windows Forms/src/MainForm.resx similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/MainForm.resx rename to Demos/Windows Forms/src/MainForm.resx diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Program.cs b/Demos/Windows Forms/src/Program.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Program.cs rename to Demos/Windows Forms/src/Program.cs diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/AssemblyInfo.cs b/Demos/Windows Forms/src/Properties/AssemblyInfo.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/AssemblyInfo.cs rename to Demos/Windows Forms/src/Properties/AssemblyInfo.cs diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Resources.Designer.cs b/Demos/Windows Forms/src/Properties/Resources.Designer.cs similarity index 98% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Resources.Designer.cs rename to Demos/Windows Forms/src/Properties/Resources.Designer.cs index 878292972..52586aa27 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Resources.Designer.cs +++ b/Demos/Windows Forms/src/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace GroupsDocs.Viewer.Forms.UI.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Resources.resx b/Demos/Windows Forms/src/Properties/Resources.resx similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Resources.resx rename to Demos/Windows Forms/src/Properties/Resources.resx diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Settings.Designer.cs b/Demos/Windows Forms/src/Properties/Settings.Designer.cs similarity index 97% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Settings.Designer.cs rename to Demos/Windows Forms/src/Properties/Settings.Designer.cs index 8f4dc008d..e1d93da23 100644 --- a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Settings.Designer.cs +++ b/Demos/Windows Forms/src/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace GroupsDocs.Viewer.Forms.UI.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Settings.settings b/Demos/Windows Forms/src/Properties/Settings.settings similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Properties/Settings.settings rename to Demos/Windows Forms/src/Properties/Settings.settings diff --git a/Demos/Windows Forms/src/Resources/application.ico b/Demos/Windows Forms/src/Resources/application.ico new file mode 100644 index 000000000..54fb2a9b6 Binary files /dev/null and b/Demos/Windows Forms/src/Resources/application.ico differ diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/first.ico b/Demos/Windows Forms/src/Resources/first.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/first.ico rename to Demos/Windows Forms/src/Resources/first.ico diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/last.ico b/Demos/Windows Forms/src/Resources/last.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/last.ico rename to Demos/Windows Forms/src/Resources/last.ico diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/locked.ico b/Demos/Windows Forms/src/Resources/locked.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/locked.ico rename to Demos/Windows Forms/src/Resources/locked.ico diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/next.ico b/Demos/Windows Forms/src/Resources/next.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/next.ico rename to Demos/Windows Forms/src/Resources/next.ico diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/open_file.ico b/Demos/Windows Forms/src/Resources/open_file.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/open_file.ico rename to Demos/Windows Forms/src/Resources/open_file.ico diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/prev.ico b/Demos/Windows Forms/src/Resources/prev.ico similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Resources/prev.ico rename to Demos/Windows Forms/src/Resources/prev.ico diff --git a/Demos/Windows Forms/src/Storage/Files/flowchart.vsdx b/Demos/Windows Forms/src/Storage/Files/flowchart.vsdx new file mode 100644 index 000000000..12db7e009 Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/flowchart.vsdx differ diff --git a/Demos/Windows Forms/src/Storage/Files/groupdocs.pptx b/Demos/Windows Forms/src/Storage/Files/groupdocs.pptx new file mode 100644 index 000000000..d94d696dd Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/groupdocs.pptx differ diff --git a/Demos/Windows Forms/src/Storage/Files/house-plan.dwg b/Demos/Windows Forms/src/Storage/Files/house-plan.dwg new file mode 100644 index 000000000..ff07697b5 Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/house-plan.dwg differ diff --git a/Demos/Windows Forms/src/Storage/Files/invoice.xlsx b/Demos/Windows Forms/src/Storage/Files/invoice.xlsx new file mode 100644 index 000000000..f223175b2 Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/invoice.xlsx differ diff --git a/Demos/Windows Forms/src/Storage/Files/resume.docx b/Demos/Windows Forms/src/Storage/Files/resume.docx new file mode 100644 index 000000000..1d9f67edb Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/resume.docx differ diff --git a/Demos/Windows Forms/src/Storage/Files/resume.pdf b/Demos/Windows Forms/src/Storage/Files/resume.pdf new file mode 100644 index 000000000..ef4cae4db Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/resume.pdf differ diff --git a/Demos/Windows Forms/src/Storage/Files/software-development-plan.mpp b/Demos/Windows Forms/src/Storage/Files/software-development-plan.mpp new file mode 100644 index 000000000..5e48341a2 Binary files /dev/null and b/Demos/Windows Forms/src/Storage/Files/software-development-plan.mpp differ diff --git a/Demos/Windows Forms/src/Storage/Files/vector-image.svg b/Demos/Windows Forms/src/Storage/Files/vector-image.svg new file mode 100644 index 000000000..6df8640de --- /dev/null +++ b/Demos/Windows Forms/src/Storage/Files/vector-image.svg @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demos/WinForms/src/GroupDocs.Viewer.WinForms/Utils/MemoryPageStreamFactory.cs b/Demos/Windows Forms/src/Utils/MemoryPageStreamFactory.cs similarity index 100% rename from Demos/WinForms/src/GroupDocs.Viewer.WinForms/Utils/MemoryPageStreamFactory.cs rename to Demos/Windows Forms/src/Utils/MemoryPageStreamFactory.cs diff --git a/Demos/Windows Forms/src/packages.config b/Demos/Windows Forms/src/packages.config new file mode 100644 index 000000000..beb8f81be --- /dev/null +++ b/Demos/Windows Forms/src/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Examples/GroupDocs.Viewer.Examples.CSharp.Core/GroupDocs.Viewer.Examples.CSharp.Core.csproj b/Examples/GroupDocs.Viewer.Examples.CSharp.Core/GroupDocs.Viewer.Examples.CSharp.Core.csproj index 6730fb7c4..e935c90e8 100644 --- a/Examples/GroupDocs.Viewer.Examples.CSharp.Core/GroupDocs.Viewer.Examples.CSharp.Core.csproj +++ b/Examples/GroupDocs.Viewer.Examples.CSharp.Core/GroupDocs.Viewer.Examples.CSharp.Core.csproj @@ -9,7 +9,7 @@ - + diff --git a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/App.config b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/App.config index 3ee0c0c52..5d30fe876 100644 --- a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/App.config +++ b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/App.config @@ -35,7 +35,7 @@ - + @@ -65,12 +65,12 @@ - + - + @@ -80,12 +80,12 @@ - + - + diff --git a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/GroupDocs.Viewer.Examples.CSharp.Framework.csproj b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/GroupDocs.Viewer.Examples.CSharp.Framework.csproj index f7c53e760..5d61b0d39 100644 --- a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/GroupDocs.Viewer.Examples.CSharp.Framework.csproj +++ b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/GroupDocs.Viewer.Examples.CSharp.Framework.csproj @@ -47,8 +47,8 @@ 4 - - ..\packages\GroupDocs.Viewer.22.7.0\lib\net40\GroupDocs.Viewer.dll + + ..\packages\GroupDocs.Viewer.22.9.0\lib\net40\GroupDocs.Viewer.dll ..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll diff --git a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/packages.config b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/packages.config index e6d464e38..d3432ff64 100644 --- a/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/packages.config +++ b/Examples/GroupDocs.Viewer.Examples.CSharp.Framework/packages.config @@ -1,6 +1,6 @@  - +