From 2b94dc5942a256e7a81dba804a24ddf74098bd48 Mon Sep 17 00:00:00 2001 From: Sean Engelhardt Date: Wed, 19 Apr 2017 14:56:15 +0200 Subject: [PATCH 1/3] Added configurable header and footer logos for PDF. --- openslides/core/config_variables.py | 25 ++++++++++++++- openslides/core/static/js/core/pdf.js | 20 ++++++------ .../templates/mediafiles/mediafile-list.html | 17 ++++++++++ openslides/users/static/js/users/site.js | 31 +++++++++++++++---- 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/openslides/core/config_variables.py b/openslides/core/config_variables.py index 58cb779f2..997e8685e 100644 --- a/openslides/core/config_variables.py +++ b/openslides/core/config_variables.py @@ -223,7 +223,9 @@ def get_config_variables(): name='logos_available', default_value=[ 'logo_projector_main', - 'logo_projector_header'], + 'logo_projector_header', + 'logo_pdf_header', + 'logo_pdf_footer'], weight=300, group='Logo', hidden=True) @@ -247,3 +249,24 @@ def get_config_variables(): weight=302, group='Logo', hidden=True) + + #PDF logos + yield ConfigVariable( + name='logo_pdf_header', + default_value={ + 'display_name': 'Header PDF logo', + 'path': ''}, + input_type='logo', + weight=310, + group='Logo', + hidden=True) + + yield ConfigVariable( + name='logo_pdf_footer', + default_value={ + 'display_name': 'Footer PDF logo', + 'path': ''}, + input_type='logo', + weight=311, + group='Logo', + hidden=True) diff --git a/openslides/core/static/js/core/pdf.js b/openslides/core/static/js/core/pdf.js index 8e02663ac..0bd2faf99 100644 --- a/openslides/core/static/js/core/pdf.js +++ b/openslides/core/static/js/core/pdf.js @@ -144,18 +144,19 @@ angular.module('OpenSlidesApp.core.pdf', []) * @param {object} contentProvider - Object with on method `getContent`, which * returns an array for content */ - var createInstance = function(contentProvider) { + //images shall contain the the logos as URL: base64Str, just like the converter + var createInstance = function(contentProvider, images) { // PDF header var getHeader = function() { var columns = []; + var logoUrl = Config.get('logo_pdf_header').value.path; - // add here your custom logo (which has to be added to a custom vfs_fonts.js) - // see https://github.com/pdfmake/pdfmake/wiki/Custom-Fonts---client-side - /* - columns.push({ - image: 'logo.png', - fit: [180,40] - });*/ + if (logoUrl) { + columns.push({ + image: images[logoUrl], + fit: [180,40] + }); + } var line1 = [ Config.translate(Config.get('general_event_name').value), @@ -768,7 +769,7 @@ angular.module('OpenSlidesApp.core.pdf', []) height *= scaleByHeight; } alreadyConverted.push({ - image: BaseMap[element.getAttribute("src")], + image: images[element.getAttribute("src")], width: width, height: height }); @@ -837,7 +838,6 @@ angular.module('OpenSlidesApp.core.pdf', []) ParseHtml(content, html); return content; }, - BaseMap = images, /** * Creates containerelements for pdfMake * e.g create("text":"MyText") result in { text: "MyText" } diff --git a/openslides/mediafiles/static/templates/mediafiles/mediafile-list.html b/openslides/mediafiles/static/templates/mediafiles/mediafile-list.html index c76c40676..4b756399d 100644 --- a/openslides/mediafiles/static/templates/mediafiles/mediafile-list.html +++ b/openslides/mediafiles/static/templates/mediafiles/mediafile-list.html @@ -321,6 +321,7 @@ ng-mouseleave="mediafile.logoHover=false" ng-show="mediafile.canBeUsedAsLogo()"> +<<<<<<< e1a95588e7f81cf06db3e753be82bc17a125d059 @@ -335,6 +336,22 @@ {{ logo.display_name | translate }},
+======= + + + + + + + + + + {{ logo.display_name }} + +
+>>>>>>> add logos in PDF (WIP)
': 1}}}, $scope, 'groups'); $scope.$watch(function () { @@ -685,10 +687,27 @@ angular.module('OpenSlidesApp.users.site', [ // Export as PDF $scope.pdfExportUserList = function () { - var filename = gettextCatalog.getString("List of participants")+".pdf"; - var userListContentProvider = UserListContentProvider.createInstance($scope.usersFiltered, $scope.groups); - var documentProvider = PdfMakeDocumentProvider.createInstance(userListContentProvider); - PdfCreate.download(documentProvider.getDocument(), filename); + var imageMap = {}; + var imagePromises = []; + var imageSources = []; + + imageSources.push(Config.get('logo_pdf_header').value.path); + imageSources.push(Config.get('logo_pdf_footer').value.path); + + imagePromises = _.map(imageSources, function (image_source) { + return PDFLayout.imageURLtoBase64(image_source).then(function (base64Str) { + imageMap[image_source] = base64Str; + }); + }); + + return $q(function (resolve) { + $q.all(imagePromises).then(function(base64Str) { + var filename = gettextCatalog.getString("List of participants")+".pdf"; + var userListContentProvider = UserListContentProvider.createInstance($scope.usersFiltered, $scope.groups); + var documentProvider = PdfMakeDocumentProvider.createInstance(userListContentProvider, imageMap); + PdfCreate.download(documentProvider.getDocument(), filename); + }); + }); }; $scope.pdfExportUserAccessDataList = function () { var filename = gettextCatalog.getString("List of access data")+".pdf"; @@ -1506,7 +1525,7 @@ angular.module('OpenSlidesApp.users.site', [ }, function (error) { // Error: Username or password is not correct. - $state.transitionTo($state.current, {msg: error.data.detail}, { + $state.transitionTo($state.current, {msg: error.data.detail}, { reload: true, inherit: false, notify: true }); } From fb45d30a34a075609d92cdf9ad79cf4fe7cd479e Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Wed, 26 Apr 2017 16:09:27 +0200 Subject: [PATCH 2/3] Changed PDF documentProvider to accept images and some cleanup. --- openslides/agenda/static/js/agenda/pdf.js | 20 +- openslides/agenda/static/js/agenda/site.js | 13 +- .../assignments/static/js/assignments/pdf.js | 89 +- .../assignments/static/js/assignments/site.js | 64 +- .../assignments/assignment-detail.html | 4 +- .../assignments/assignment-list.html | 2 +- openslides/core/config_variables.py | 2 +- openslides/core/static/js/core/pdf-worker.js | 11 +- openslides/core/static/js/core/pdf.js | 84 +- .../templates/mediafiles/mediafile-list.html | 19 +- openslides/motions/static/js/motions/pdf.js | 1102 +++++++++-------- openslides/users/static/js/users/pdf.js | 207 ++-- openslides/users/static/js/users/site.js | 42 +- 13 files changed, 878 insertions(+), 781 deletions(-) diff --git a/openslides/agenda/static/js/agenda/pdf.js b/openslides/agenda/static/js/agenda/pdf.js index 841ba0364..28e957cef 100644 --- a/openslides/agenda/static/js/agenda/pdf.js +++ b/openslides/agenda/static/js/agenda/pdf.js @@ -75,6 +75,24 @@ angular.module('OpenSlidesApp.agenda.pdf', ['OpenSlidesApp.core.pdf']) createInstance: createInstance }; -}]); +}]) + +.factory('AgendaPdfExport', [ + 'gettextCatalog', + 'AgendaContentProvider', + 'PdfMakeDocumentProvider', + 'PdfCreate', + function (gettextCatalog, AgendaContentProvider, PdfMakeDocumentProvider, PdfCreate) { + return { + export: function (items) { + var filename = gettextCatalog.getString('Agenda') + '.pdf'; + var agendaContentProvider = AgendaContentProvider.createInstance(items); + PdfMakeDocumentProvider.createInstance(agendaContentProvider).then(function (documentProvider) { + PdfCreate.download(documentProvider.getDocument(), filename); + }); + }, + }; + } +]); }()); diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index 9d68f685a..73b04808e 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -89,17 +89,15 @@ angular.module('OpenSlidesApp.agenda.site', [ 'AgendaTree', 'Projector', 'ProjectionDefault', - 'AgendaContentProvider', - 'PdfMakeDocumentProvider', 'gettextCatalog', 'gettext', 'osTableFilter', 'AgendaCsvExport', - 'PdfCreate', + 'AgendaPdfExport', 'ErrorMessage', function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, - AgendaTree, Projector, ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider, - gettextCatalog, gettext, osTableFilter, AgendaCsvExport, PdfCreate, ErrorMessage) { + AgendaTree, Projector, ProjectionDefault, gettextCatalog, gettext, osTableFilter, + AgendaCsvExport, AgendaPdfExport, ErrorMessage) { // Bind agenda tree to the scope $scope.$watch(function () { return Agenda.lastModified(); @@ -276,10 +274,7 @@ angular.module('OpenSlidesApp.agenda.site', [ }; // export $scope.pdfExport = function () { - var filename = gettextCatalog.getString('Agenda') + '.pdf'; - var agendaContentProvider = AgendaContentProvider.createInstance($scope.itemsFiltered); - var documentProvider = PdfMakeDocumentProvider.createInstance(agendaContentProvider); - PdfCreate.download(documentProvider.getDocument(), filename); + AgendaPdfExport.export($scope.itemsFiltered); }; $scope.csvExport = function () { AgendaCsvExport.export($scope.itemsFiltered); diff --git a/openslides/assignments/static/js/assignments/pdf.js b/openslides/assignments/static/js/assignments/pdf.js index d27f36c48..4f5df21c8 100644 --- a/openslides/assignments/static/js/assignments/pdf.js +++ b/openslides/assignments/static/js/assignments/pdf.js @@ -259,10 +259,11 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf']) }; }; - return { - createInstance: createInstance - }; -}]) + return { + createInstance: createInstance + }; + } +]) .factory('BallotContentProvider', [ '$filter', @@ -271,12 +272,12 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf']) 'Config', 'User', function($filter, gettextCatalog, PDFLayout, Config, User) { - var createInstance = function(scope, poll, pollNumber) { + var createInstance = function(assignment, poll, pollNumber) { // page title var createTitle = function() { return { - text: scope.assignment.title, + text: assignment.title, style: 'title', }; }; @@ -477,10 +478,11 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf']) }; }; - return { - createInstance: createInstance - }; -}]) + return { + createInstance: createInstance + }; + } +]) .factory('AssignmentCatalogContentProvider', [ 'gettextCatalog', @@ -552,9 +554,68 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf']) }; }; - return { - createInstance: createInstance - }; -}]); + return { + createInstance: createInstance + }; + } +]) + +.factory('AssignmentPdfExport', [ + 'gettextCatalog', + 'AssignmentContentProvider', + 'AssignmentCatalogContentProvider', + 'PdfMakeDocumentProvider', + 'BallotContentProvider', + 'PdfMakeBallotPaperProvider', + 'PdfCreate', + function (gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider, + PdfMakeDocumentProvider, BallotContentProvider, PdfMakeBallotPaperProvider, PdfCreate) { + return { + export: function (assignments, singleAssignment) { + var filename = singleAssignment ? + gettextCatalog.getString('Election') + '_' + assignments.title : + gettextCatalog.getString('Elections'); + filename += '.pdf'; + if (singleAssignment) { + assignments = [assignments]; + } + var assignmentContentProviderArray = []; + + // Convert the assignments to content providers + angular.forEach(assignments, function(assignment) { + assignmentContentProviderArray.push(AssignmentContentProvider.createInstance(assignment)); + }); + + var documentProviderPromise; + if (singleAssignment) { + documentProviderPromise = + PdfMakeDocumentProvider.createInstance(assignmentContentProviderArray[0]); + } else { + var assignmentCatalogContentProvider = + AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray); + documentProviderPromise = + PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider); + } + documentProviderPromise.then(function (documentProvider) { + PdfCreate.download(documentProvider.getDocument(), filename); + }); + }, + createBallotPdf: function (assignment, pollId) { + var thePoll; + var pollNumber; + angular.forEach(assignment.polls, function(poll, pollIndex) { + if (poll.id == pollId) { + thePoll = poll; + pollNumber = pollIndex+1; + } + }); + var filename = gettextCatalog.getString('Ballot') + '_' + pollNumber + '_' + assignment.title + '.pdf'; + var ballotContentProvider = BallotContentProvider.createInstance(assignment, thePoll, pollNumber); + var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider); + PdfCreate.download(documentProvider.getDocument(), filename); + }, + }; + } +]); }()); diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index 1a5416af6..6a639ce3f 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -265,18 +265,14 @@ angular.module('OpenSlidesApp.assignments.site', [ 'Projector', 'ProjectionDefault', 'gettextCatalog', - 'AssignmentContentProvider', - 'AssignmentCatalogContentProvider', - 'PdfMakeDocumentProvider', 'User', 'osTableFilter', 'osTableSort', 'gettext', - 'PdfCreate', 'AssignmentPhases', + 'AssignmentPdfExport', function($scope, ngDialog, AssignmentForm, Assignment, Tag, Agenda, Projector, ProjectionDefault, - gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider, PdfMakeDocumentProvider, - User, osTableFilter, osTableSort, gettext, PdfCreate, AssignmentPhases) { + gettextCatalog, User, osTableFilter, osTableSort, gettext, AssignmentPhases, AssignmentPdfExport) { Assignment.bindAll({}, $scope, 'assignments'); Tag.bindAll({}, $scope, 'tags'); $scope.$watch(function () { @@ -383,20 +379,8 @@ angular.module('OpenSlidesApp.assignments.site', [ Assignment.destroy(assignment.id); }; // create the PDF List - $scope.makePDF_assignmentList = function () { - var filename = gettextCatalog.getString("Elections") + ".pdf"; - var assignmentContentProviderArray = []; - - //convert the filtered assignments to content providers - angular.forEach($scope.assignmentsFiltered, function(assignment) { - assignmentContentProviderArray.push(AssignmentContentProvider.createInstance(assignment)); - }); - - var assignmentCatalogContentProvider = - AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray); - var documentProvider = - PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider); - PdfCreate.download(documentProvider.getDocument(), filename); + $scope.pdfExport = function () { + AssignmentPdfExport.export($scope.assignmentsFiltered); }; } ]) @@ -416,18 +400,13 @@ angular.module('OpenSlidesApp.assignments.site', [ 'assignmentId', 'Projector', 'ProjectionDefault', - 'AssignmentContentProvider', - 'BallotContentProvider', - 'PdfMakeDocumentProvider', - 'PdfMakeBallotPaperProvider', 'gettextCatalog', - 'PdfCreate', 'AssignmentPhases', + 'AssignmentPdfExport', 'ErrorMessage', - function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment, - User, assignmentId, Projector, ProjectionDefault, AssignmentContentProvider, BallotContentProvider, - PdfMakeDocumentProvider, PdfMakeBallotPaperProvider, gettextCatalog, PdfCreate, AssignmentPhases, - ErrorMessage) { + function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator, + Assignment, User, assignmentId, Projector, ProjectionDefault, gettextCatalog, AssignmentPhases, + AssignmentPdfExport, ErrorMessage) { User.bindAll({}, $scope, 'users'); var assignment = Assignment.get(assignmentId); Assignment.loadRelations(assignment, 'agenda_item'); @@ -600,28 +579,13 @@ angular.module('OpenSlidesApp.assignments.site', [ }; - //creates the document as pdf - $scope.makePDF_singleAssignment = function() { - var filename = gettextCatalog.getString("Election") + "_" + $scope.assignment.title + ".pdf"; - var assignmentContentProvider = AssignmentContentProvider.createInstance($scope.assignment); - var documentProvider = PdfMakeDocumentProvider.createInstance(assignmentContentProvider); - PdfCreate.download(documentProvider.getDocument(), filename); + // Creates the document as pdf + $scope.pdfExport = function() { + AssignmentPdfExport.export($scope.assignment, true); }; - - //creates the ballotpaper as pdf - $scope.makePDF_assignmentpoll = function(pollID) { - var thePoll; - var pollNumber; - angular.forEach($scope.assignment.polls, function(poll, pollIndex) { - if (poll.id == pollID) { - thePoll = poll; - pollNumber = pollIndex+1; - } - }); - var filename = gettextCatalog.getString("Ballot") + "_" + pollNumber + "_" + $scope.assignment.title + ".pdf"; - var ballotContentProvider = BallotContentProvider.createInstance($scope, thePoll, pollNumber); - var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider); - PdfCreate.download(documentProvider.getDocument(), filename); + // Creates the ballotpaper as pdf + $scope.ballotpaperExport = function(pollId) { + AssignmentPdfExport.createBallotPdf($scope.assignment, pollId); }; // Just mark some vote value strings for translation. diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html index d9b40a250..28cd8787d 100644 --- a/openslides/assignments/static/templates/assignments/assignment-detail.html +++ b/openslides/assignments/static/templates/assignments/assignment-detail.html @@ -21,7 +21,7 @@ - + PDF @@ -152,7 +152,7 @@ - + Print ballot paper diff --git a/openslides/assignments/static/templates/assignments/assignment-list.html b/openslides/assignments/static/templates/assignments/assignment-list.html index d8f61a412..313bf9802 100644 --- a/openslides/assignments/static/templates/assignments/assignment-list.html +++ b/openslides/assignments/static/templates/assignments/assignment-list.html @@ -39,7 +39,7 @@