Merge branch 'MDL-60008-master' of git://github.com/damyon/moodle
This commit is contained in:
@@ -70,6 +70,7 @@ if ($action === 'pollconversions') {
|
||||
'filecount' => 0,
|
||||
'pagecount' => 0,
|
||||
'pageready' => 0,
|
||||
'partial' => false,
|
||||
'pages' => [],
|
||||
];
|
||||
|
||||
@@ -77,10 +78,13 @@ if ($action === 'pollconversions') {
|
||||
$response->status = $combineddocument->get_status();
|
||||
$response->filecount = $combineddocument->get_document_count();
|
||||
|
||||
if ($response->status === combined_document::STATUS_READY) {
|
||||
$readystatuslist = [combined_document::STATUS_READY, combined_document::STATUS_READY_PARTIAL];
|
||||
$completestatuslist = [combined_document::STATUS_COMPLETE, combined_document::STATUS_FAILED];
|
||||
|
||||
if (in_array($response->status, $readystatuslist)) {
|
||||
$combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$response->pagecount = $combineddocument->get_page_count();
|
||||
} else if ($response->status === combined_document::STATUS_COMPLETE || $response->status === combined_document::STATUS_FAILED) {
|
||||
} else if (in_array($response->status, $completestatuslist)) {
|
||||
$pages = document_services::get_page_images_for_attempt($assignment,
|
||||
$userid,
|
||||
$attemptnumber,
|
||||
@@ -95,6 +99,7 @@ if ($action === 'pollconversions') {
|
||||
if ($readonly) {
|
||||
$filearea = document_services::PAGE_IMAGE_READONLY_FILEAREA;
|
||||
}
|
||||
$response->partial = $combineddocument->is_partial_conversion();
|
||||
|
||||
foreach ($pages as $id => $pagefile) {
|
||||
$index = count($response->pages);
|
||||
|
||||
@@ -44,6 +44,11 @@ class combined_document {
|
||||
*/
|
||||
const STATUS_READY = 1;
|
||||
|
||||
/**
|
||||
* Status value representing all documents are ready to be combined as are supported.
|
||||
*/
|
||||
const STATUS_READY_PARTIAL = 3;
|
||||
|
||||
/**
|
||||
* Status value representing a successful conversion.
|
||||
*/
|
||||
@@ -76,6 +81,9 @@ class combined_document {
|
||||
|
||||
/**
|
||||
* Check the current status of the document combination.
|
||||
* Note that the combined document may not contain all the source files if some of the
|
||||
* source files were not able to be converted. An example is an audio file with a pdf cover sheet. Only
|
||||
* the cover sheet will be included in the combined document.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -97,6 +105,7 @@ class combined_document {
|
||||
}
|
||||
|
||||
$pending = false;
|
||||
$partial = false;
|
||||
foreach ($this->sourcefiles as $file) {
|
||||
// The combined file has not yet been generated.
|
||||
// Check the status of each source file.
|
||||
@@ -108,14 +117,19 @@ class combined_document {
|
||||
$pending = true;
|
||||
break;
|
||||
|
||||
// There are 4 status flags, so the only remaining one is complete which is fine.
|
||||
case \core_files\conversion::STATUS_FAILED:
|
||||
return self::STATUS_FAILED;
|
||||
$partial = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($pending) {
|
||||
return self::STATUS_PENDING_INPUT;
|
||||
} else {
|
||||
if ($partial) {
|
||||
return self::STATUS_READY_PARTIAL;
|
||||
}
|
||||
return self::STATUS_READY;
|
||||
}
|
||||
}
|
||||
@@ -131,6 +145,20 @@ class combined_document {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true of the combined file contained only some of the submission files.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_partial_conversion() {
|
||||
$combinedfile = $this->get_combined_file();
|
||||
if (empty($combinedfile)) {
|
||||
return false;
|
||||
}
|
||||
$filearea = $combinedfile->get_filearea();
|
||||
return $filearea == document_services::PARTIAL_PDF_FILEAREA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the completed combined file.
|
||||
*
|
||||
@@ -210,11 +238,12 @@ class combined_document {
|
||||
global $CFG;
|
||||
|
||||
$currentstatus = $this->get_status();
|
||||
$readystatuslist = [self::STATUS_READY, self::STATUS_READY_PARTIAL];
|
||||
if ($currentstatus === self::STATUS_FAILED) {
|
||||
$this->store_empty_document($contextid, $itemid);
|
||||
|
||||
return $this;
|
||||
} else if ($currentstatus !== self::STATUS_READY) {
|
||||
} else if (!in_array($currentstatus, $readystatuslist)) {
|
||||
// The document is either:
|
||||
// * already combined; or
|
||||
// * pending input being fully converted; or
|
||||
@@ -235,7 +264,10 @@ class combined_document {
|
||||
// Note: We drop non-compatible files.
|
||||
$compatiblepdf = false;
|
||||
if (is_a($file, \core_files\conversion::class)) {
|
||||
$compatiblepdf = pdf::ensure_pdf_compatible($file->get_destfile());
|
||||
$status = $file->get('status');
|
||||
if ($status == \core_files\conversion::STATUS_COMPLETE) {
|
||||
$compatiblepdf = pdf::ensure_pdf_compatible($file->get_destfile());
|
||||
}
|
||||
} else {
|
||||
$compatiblepdf = pdf::ensure_pdf_compatible($file);
|
||||
}
|
||||
@@ -270,7 +302,7 @@ class combined_document {
|
||||
}
|
||||
|
||||
// Store the newly created file as a stored_file.
|
||||
$this->store_combined_file($tmpfile, $contextid, $itemid);
|
||||
$this->store_combined_file($tmpfile, $contextid, $itemid, ($currentstatus == self::STATUS_READY_PARTIAL));
|
||||
|
||||
// Note the verified page count.
|
||||
$this->pagecount = $verifypagecount;
|
||||
@@ -295,11 +327,12 @@ class combined_document {
|
||||
* @param string $tmpfile The path to the file on disk to be stored.
|
||||
* @param int $contextid The contextid for the file to be stored under
|
||||
* @param int $itemid The itemid for the file to be stored under
|
||||
* @param boolean $partial The combined pdf contains only some of the source files.
|
||||
* @return $this
|
||||
*/
|
||||
protected function store_combined_file($tmpfile, $contextid, $itemid) {
|
||||
protected function store_combined_file($tmpfile, $contextid, $itemid, $partial = false) {
|
||||
// Store the file.
|
||||
$record = $this->get_stored_file_record($contextid, $itemid);
|
||||
$record = $this->get_stored_file_record($contextid, $itemid, $partial);
|
||||
$fs = get_file_storage();
|
||||
|
||||
// Delete existing files first.
|
||||
@@ -349,12 +382,14 @@ class combined_document {
|
||||
return $this->pagecount;
|
||||
}
|
||||
|
||||
if ($this->get_status() === self::STATUS_FAILED) {
|
||||
$status = $this->get_status();
|
||||
|
||||
if ($status === self::STATUS_FAILED) {
|
||||
// The empty document will be returned.
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($this->get_status() !== self::STATUS_COMPLETE) {
|
||||
if ($status !== self::STATUS_COMPLETE) {
|
||||
// No pages yet.
|
||||
return 0;
|
||||
}
|
||||
@@ -391,13 +426,18 @@ class combined_document {
|
||||
*
|
||||
* @param int $contextid The contextid for the file to be stored under
|
||||
* @param int $itemid The itemid for the file to be stored under
|
||||
* @param boolean $partial The combined file contains only some of the source files.
|
||||
* @return stdClass
|
||||
*/
|
||||
protected function get_stored_file_record($contextid, $itemid) {
|
||||
protected function get_stored_file_record($contextid, $itemid, $partial = false) {
|
||||
$filearea = document_services::COMBINED_PDF_FILEAREA;
|
||||
if ($partial) {
|
||||
$filearea = document_services::PARTIAL_PDF_FILEAREA;
|
||||
}
|
||||
return (object) [
|
||||
'contextid' => $contextid,
|
||||
'component' => 'assignfeedback_editpdf',
|
||||
'filearea' => document_services::COMBINED_PDF_FILEAREA,
|
||||
'filearea' => $filearea,
|
||||
'itemid' => $itemid,
|
||||
'filepath' => '/',
|
||||
'filename' => document_services::COMBINED_PDF_FILENAME,
|
||||
|
||||
@@ -42,6 +42,8 @@ class document_services {
|
||||
const FINAL_PDF_FILEAREA = 'download';
|
||||
/** File area for combined pdf */
|
||||
const COMBINED_PDF_FILEAREA = 'combined';
|
||||
/** File area for partial combined pdf */
|
||||
const PARTIAL_PDF_FILEAREA = 'partial';
|
||||
/** File area for importing html */
|
||||
const IMPORT_HTML_FILEAREA = 'importhtml';
|
||||
/** File area for page images */
|
||||
@@ -261,15 +263,23 @@ EOD;
|
||||
$submission = $assignment->get_user_submission($userid, false, $attemptnumber);
|
||||
}
|
||||
|
||||
|
||||
$contextid = $assignment->get_context()->id;
|
||||
$component = 'assignfeedback_editpdf';
|
||||
$filearea = self::COMBINED_PDF_FILEAREA;
|
||||
$partialfilearea = self::PARTIAL_PDF_FILEAREA;
|
||||
$itemid = $grade->id;
|
||||
$filepath = '/';
|
||||
$filename = self::COMBINED_PDF_FILENAME;
|
||||
$fs = get_file_storage();
|
||||
|
||||
$combinedpdf = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename);
|
||||
$partialpdf = $fs->get_file($contextid, $component, $partialfilearea, $itemid, $filepath, $filename);
|
||||
if (!empty($partialpdf)) {
|
||||
$combinedpdf = $partialpdf;
|
||||
} else {
|
||||
$combinedpdf = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename);
|
||||
}
|
||||
|
||||
if ($combinedpdf && $submission) {
|
||||
if ($combinedpdf->get_timemodified() < $submission->timemodified) {
|
||||
// The submission has been updated since the PDF was generated.
|
||||
@@ -381,6 +391,7 @@ EOD;
|
||||
|
||||
$tmpdir = \make_temp_directory('assignfeedback_editpdf/pageimages/' . self::hash($assignment, $userid, $attemptnumber));
|
||||
$combined = $tmpdir . '/' . self::COMBINED_PDF_FILENAME;
|
||||
|
||||
$document->get_combined_file()->copy_content_to($combined); // Copy the file.
|
||||
|
||||
$pdf = new pdf();
|
||||
|
||||
@@ -217,15 +217,14 @@ class assignfeedback_editpdf_renderer extends plugin_renderer_base {
|
||||
|
||||
$canvas = html_writer::div($loading, 'drawingcanvas');
|
||||
$canvas = html_writer::div($canvas, 'drawingregion');
|
||||
$changesmessage = html_writer::tag('div',
|
||||
get_string('draftchangessaved', 'assignfeedback_editpdf'),
|
||||
array(
|
||||
'class' => 'assignfeedback_editpdf_unsavedchanges warning label label-info'
|
||||
));
|
||||
|
||||
$changesmessage = html_writer::div($changesmessage, 'unsaved-changes');
|
||||
// Place for messages, but no warnings displayed yet.
|
||||
$changesmessage = html_writer::div('', 'warningmessages');
|
||||
$canvas .= $changesmessage;
|
||||
|
||||
$infoicon = $this->image_icon('i/info', '');
|
||||
$infomessage = html_writer::div($infoicon, 'infoicon');
|
||||
$canvas .= $infomessage;
|
||||
|
||||
$body .= $canvas;
|
||||
|
||||
$footer = '';
|
||||
@@ -268,7 +267,9 @@ class assignfeedback_editpdf_renderer extends plugin_renderer_base {
|
||||
'stamp',
|
||||
'stamppicker',
|
||||
'cannotopenpdf',
|
||||
'pagenumber'
|
||||
'pagenumber',
|
||||
'partialwarning',
|
||||
'draftchangessaved'
|
||||
), 'assignfeedback_editpdf');
|
||||
|
||||
return $html;
|
||||
|
||||
@@ -102,10 +102,9 @@ class convert_submissions extends scheduled_task {
|
||||
foreach ($users as $userid) {
|
||||
try {
|
||||
$combineddocument = document_services::get_combined_pdf_for_attempt($assignment, $userid, $attemptnumber);
|
||||
$status = $combineddocument->get_status();
|
||||
|
||||
switch ($combineddocument->get_status()) {
|
||||
case combined_document::STATUS_READY:
|
||||
case combined_document::STATUS_READY_PARTIAL:
|
||||
case combined_document::STATUS_PENDING_INPUT:
|
||||
// The document has not been converted yet or is somehow still ready.
|
||||
continue 2;
|
||||
|
||||
@@ -72,6 +72,7 @@ $string['output'] = 'Output:';
|
||||
$string['pagenumber'] = 'Page {$a}';
|
||||
$string['pagexofy'] = 'Page {$a->page} of {$a->total}';
|
||||
$string['pen'] = 'Pen';
|
||||
$string['partialwarning'] = 'Some of the files in this submission can only be accessed by direct download.';
|
||||
$string['pluginname'] = 'Annotate PDF';
|
||||
$string['privacy:metadata:colourpurpose'] = 'Colour of the comment or annotation';
|
||||
$string['privacy:metadata:conversionpurpose'] = 'Files are converted to PDFs to allow for annotations.';
|
||||
|
||||
@@ -26,6 +26,17 @@
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .infoicon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .warningmessages {
|
||||
position: absolute;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .drawingregion {
|
||||
border: 1px solid #ccc;
|
||||
left: 1em;
|
||||
@@ -59,17 +70,6 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .assignfeedback_editpdf_unsavedchanges.haschanges {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .assignfeedback_editpdf_unsavedchanges {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.yui3-colourpicker-hidden,
|
||||
.yui3-commentsearch-hidden,
|
||||
.yui3-commentmenu-hidden {
|
||||
@@ -229,6 +229,7 @@
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
border-radius: 4px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.moodle-dialogue-base .moodle-dialogue.assignfeedback_editpdf_dropdown .moodle-dialogue-bd {
|
||||
|
||||
+78
-14
@@ -43,7 +43,9 @@ var AJAXBASE = M.cfg.wwwroot + '/mod/assign/feedback/editpdf/ajax.php',
|
||||
COMMENTMENU: '.commentdrawable a',
|
||||
ANNOTATIONCOLOURBUTTON: '.annotationcolourbutton',
|
||||
DELETEANNOTATIONBUTTON: '.deleteannotationbutton',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_unsavedchanges',
|
||||
WARNINGMESSAGECONTAINER: '.warningmessages',
|
||||
ICONMESSAGECONTAINER: '.infoicon',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_warningmessages',
|
||||
UNSAVEDCHANGESINPUT: 'input[name="assignfeedback_editpdf_haschanges"]',
|
||||
STAMPSBUTTON: '.currentstampbutton',
|
||||
DIALOGUE: '.' + CSS.DIALOGUE
|
||||
@@ -3756,7 +3758,7 @@ EDITOR.prototype = {
|
||||
// The combined document is still waiting for input to be ready.
|
||||
poll = true;
|
||||
|
||||
} else if (data.status === 1) {
|
||||
} else if (data.status === 1 || data.status === 3) {
|
||||
// The combine document is ready for conversion into a single PDF.
|
||||
poll = true;
|
||||
|
||||
@@ -3829,6 +3831,47 @@ EDITOR.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Display an error in a small part of the page (don't block everything).
|
||||
*
|
||||
* @param string The error text.
|
||||
* @param boolean dismissable Not critical messages can be removed after a short display.
|
||||
* @protected
|
||||
* @method warning
|
||||
*/
|
||||
warning: function(message, dismissable) {
|
||||
var icontemplate = this.get_dialogue_element(SELECTOR.ICONMESSAGECONTAINER);
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
var delay = 15, duration = 1;
|
||||
var messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-warning';
|
||||
if (dismissable) {
|
||||
delay = 4;
|
||||
messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-info';
|
||||
}
|
||||
var warningelement = Y.Node.create('<div class="' + messageclasses + '" role="alert"></div>');
|
||||
|
||||
// Copy info icon template.
|
||||
warningelement.append(icontemplate.one('*').cloneNode());
|
||||
|
||||
// Append the message.
|
||||
warningelement.append(message);
|
||||
|
||||
// Add the entire warning to the container.
|
||||
warningregion.prepend(warningelement);
|
||||
|
||||
// Remove the message after a short delay.
|
||||
warningelement.transition(
|
||||
{
|
||||
duration: duration,
|
||||
delay: delay,
|
||||
opacity: 0
|
||||
},
|
||||
function() {
|
||||
warningelement.remove();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* The info about all pages in the pdf has been returned.
|
||||
*
|
||||
@@ -3837,7 +3880,8 @@ EDITOR.prototype = {
|
||||
* @method prepare_pages_for_display
|
||||
*/
|
||||
prepare_pages_for_display: function(data) {
|
||||
var i, j, comment, error;
|
||||
var i, j, comment, error, annotation, readonly;
|
||||
|
||||
if (!data.pagecount) {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
@@ -3863,11 +3907,17 @@ EDITOR.prototype = {
|
||||
comment.rawtext);
|
||||
}
|
||||
for (j = 0; j < this.pages[i].annotations.length; j++) {
|
||||
data = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(data.type, data);
|
||||
annotation = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(annotation.type, annotation);
|
||||
}
|
||||
}
|
||||
|
||||
readonly = this.get('readonly');
|
||||
if (!readonly && data.partial) {
|
||||
// Warn about non converted files, but only for teachers.
|
||||
this.warning(M.util.get_string('partialwarning', 'assignfeedback_editpdf'), false);
|
||||
}
|
||||
|
||||
// Update the ui.
|
||||
if (this.quicklist) {
|
||||
this.quicklist.load();
|
||||
@@ -4454,6 +4504,7 @@ EDITOR.prototype = {
|
||||
* @method save_current_page
|
||||
*/
|
||||
save_current_page: function() {
|
||||
this.clear_warnings(false);
|
||||
if (this.get('destroyed')) {
|
||||
return;
|
||||
}
|
||||
@@ -4481,16 +4532,9 @@ EDITOR.prototype = {
|
||||
if (jsondata.error) {
|
||||
return new M.core.ajaxException(jsondata);
|
||||
}
|
||||
// Show warning that we have not saved the feedback.
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESINPUT).set('value', 'true');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('opacity', 1);
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'inline-block');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).transition({
|
||||
duration: 1,
|
||||
delay: 2,
|
||||
opacity: 0
|
||||
}, function() {
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'none');
|
||||
});
|
||||
this.warning(M.util.get_string('draftchangessaved', 'assignfeedback_editpdf'), true);
|
||||
} catch (e) {
|
||||
return new M.core.exception(e);
|
||||
}
|
||||
@@ -4565,6 +4609,22 @@ EDITOR.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all current warning messages from display.
|
||||
* @protected
|
||||
* @method clear_warnings
|
||||
* @param {Boolean} allwarnings If true, all previous warnings are removed.
|
||||
*/
|
||||
clear_warnings: function(allwarnings) {
|
||||
// Remove all warning messages, they may not relate to the current document or page anymore.
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
if (allwarnings) {
|
||||
warningregion.empty();
|
||||
} else {
|
||||
warningregion.all('.alert-info').remove(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the image for this pdf page and remove the loading icon (if there).
|
||||
* @protected
|
||||
@@ -4631,6 +4691,7 @@ EDITOR.prototype = {
|
||||
pageselect.removeAttribute('disabled');
|
||||
pageselect.on('change', function() {
|
||||
this.currentpage = pageselect.get('value');
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
}, this);
|
||||
|
||||
@@ -4654,6 +4715,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage < 0) {
|
||||
this.currentpage = 0;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
@@ -4668,6 +4730,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage >= this.pages.length) {
|
||||
this.currentpage = this.pages.length - 1;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
@@ -4817,6 +4880,7 @@ M.assignfeedback_editpdf.editor.init = M.assignfeedback_editpdf.editor.init || f
|
||||
"querystring-stringify-simple",
|
||||
"moodle-core-notification-dialog",
|
||||
"moodle-core-notification-alert",
|
||||
"moodle-core-notification-warning",
|
||||
"moodle-core-notification-exception",
|
||||
"moodle-core-notification-ajaxexception"
|
||||
]
|
||||
|
||||
+9
-9
File diff suppressed because one or more lines are too long
+78
-14
@@ -43,7 +43,9 @@ var AJAXBASE = M.cfg.wwwroot + '/mod/assign/feedback/editpdf/ajax.php',
|
||||
COMMENTMENU: '.commentdrawable a',
|
||||
ANNOTATIONCOLOURBUTTON: '.annotationcolourbutton',
|
||||
DELETEANNOTATIONBUTTON: '.deleteannotationbutton',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_unsavedchanges',
|
||||
WARNINGMESSAGECONTAINER: '.warningmessages',
|
||||
ICONMESSAGECONTAINER: '.infoicon',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_warningmessages',
|
||||
UNSAVEDCHANGESINPUT: 'input[name="assignfeedback_editpdf_haschanges"]',
|
||||
STAMPSBUTTON: '.currentstampbutton',
|
||||
DIALOGUE: '.' + CSS.DIALOGUE
|
||||
@@ -3756,7 +3758,7 @@ EDITOR.prototype = {
|
||||
// The combined document is still waiting for input to be ready.
|
||||
poll = true;
|
||||
|
||||
} else if (data.status === 1) {
|
||||
} else if (data.status === 1 || data.status === 3) {
|
||||
// The combine document is ready for conversion into a single PDF.
|
||||
poll = true;
|
||||
|
||||
@@ -3829,6 +3831,47 @@ EDITOR.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Display an error in a small part of the page (don't block everything).
|
||||
*
|
||||
* @param string The error text.
|
||||
* @param boolean dismissable Not critical messages can be removed after a short display.
|
||||
* @protected
|
||||
* @method warning
|
||||
*/
|
||||
warning: function(message, dismissable) {
|
||||
var icontemplate = this.get_dialogue_element(SELECTOR.ICONMESSAGECONTAINER);
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
var delay = 15, duration = 1;
|
||||
var messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-warning';
|
||||
if (dismissable) {
|
||||
delay = 4;
|
||||
messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-info';
|
||||
}
|
||||
var warningelement = Y.Node.create('<div class="' + messageclasses + '" role="alert"></div>');
|
||||
|
||||
// Copy info icon template.
|
||||
warningelement.append(icontemplate.one('*').cloneNode());
|
||||
|
||||
// Append the message.
|
||||
warningelement.append(message);
|
||||
|
||||
// Add the entire warning to the container.
|
||||
warningregion.prepend(warningelement);
|
||||
|
||||
// Remove the message after a short delay.
|
||||
warningelement.transition(
|
||||
{
|
||||
duration: duration,
|
||||
delay: delay,
|
||||
opacity: 0
|
||||
},
|
||||
function() {
|
||||
warningelement.remove();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* The info about all pages in the pdf has been returned.
|
||||
*
|
||||
@@ -3837,7 +3880,8 @@ EDITOR.prototype = {
|
||||
* @method prepare_pages_for_display
|
||||
*/
|
||||
prepare_pages_for_display: function(data) {
|
||||
var i, j, comment, error;
|
||||
var i, j, comment, error, annotation, readonly;
|
||||
|
||||
if (!data.pagecount) {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
@@ -3863,11 +3907,17 @@ EDITOR.prototype = {
|
||||
comment.rawtext);
|
||||
}
|
||||
for (j = 0; j < this.pages[i].annotations.length; j++) {
|
||||
data = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(data.type, data);
|
||||
annotation = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(annotation.type, annotation);
|
||||
}
|
||||
}
|
||||
|
||||
readonly = this.get('readonly');
|
||||
if (!readonly && data.partial) {
|
||||
// Warn about non converted files, but only for teachers.
|
||||
this.warning(M.util.get_string('partialwarning', 'assignfeedback_editpdf'), false);
|
||||
}
|
||||
|
||||
// Update the ui.
|
||||
if (this.quicklist) {
|
||||
this.quicklist.load();
|
||||
@@ -4454,6 +4504,7 @@ EDITOR.prototype = {
|
||||
* @method save_current_page
|
||||
*/
|
||||
save_current_page: function() {
|
||||
this.clear_warnings(false);
|
||||
if (this.get('destroyed')) {
|
||||
return;
|
||||
}
|
||||
@@ -4481,16 +4532,9 @@ EDITOR.prototype = {
|
||||
if (jsondata.error) {
|
||||
return new M.core.ajaxException(jsondata);
|
||||
}
|
||||
// Show warning that we have not saved the feedback.
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESINPUT).set('value', 'true');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('opacity', 1);
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'inline-block');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).transition({
|
||||
duration: 1,
|
||||
delay: 2,
|
||||
opacity: 0
|
||||
}, function() {
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'none');
|
||||
});
|
||||
this.warning(M.util.get_string('draftchangessaved', 'assignfeedback_editpdf'), true);
|
||||
} catch (e) {
|
||||
return new M.core.exception(e);
|
||||
}
|
||||
@@ -4565,6 +4609,22 @@ EDITOR.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all current warning messages from display.
|
||||
* @protected
|
||||
* @method clear_warnings
|
||||
* @param {Boolean} allwarnings If true, all previous warnings are removed.
|
||||
*/
|
||||
clear_warnings: function(allwarnings) {
|
||||
// Remove all warning messages, they may not relate to the current document or page anymore.
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
if (allwarnings) {
|
||||
warningregion.empty();
|
||||
} else {
|
||||
warningregion.all('.alert-info').remove(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the image for this pdf page and remove the loading icon (if there).
|
||||
* @protected
|
||||
@@ -4631,6 +4691,7 @@ EDITOR.prototype = {
|
||||
pageselect.removeAttribute('disabled');
|
||||
pageselect.on('change', function() {
|
||||
this.currentpage = pageselect.get('value');
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
}, this);
|
||||
|
||||
@@ -4654,6 +4715,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage < 0) {
|
||||
this.currentpage = 0;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
@@ -4668,6 +4730,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage >= this.pages.length) {
|
||||
this.currentpage = this.pages.length - 1;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
@@ -4817,6 +4880,7 @@ M.assignfeedback_editpdf.editor.init = M.assignfeedback_editpdf.editor.init || f
|
||||
"querystring-stringify-simple",
|
||||
"moodle-core-notification-dialog",
|
||||
"moodle-core-notification-alert",
|
||||
"moodle-core-notification-warning",
|
||||
"moodle-core-notification-exception",
|
||||
"moodle-core-notification-ajaxexception"
|
||||
]
|
||||
|
||||
+74
-13
@@ -483,7 +483,7 @@ EDITOR.prototype = {
|
||||
// The combined document is still waiting for input to be ready.
|
||||
poll = true;
|
||||
|
||||
} else if (data.status === 1) {
|
||||
} else if (data.status === 1 || data.status === 3) {
|
||||
// The combine document is ready for conversion into a single PDF.
|
||||
poll = true;
|
||||
|
||||
@@ -556,6 +556,47 @@ EDITOR.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Display an error in a small part of the page (don't block everything).
|
||||
*
|
||||
* @param string The error text.
|
||||
* @param boolean dismissable Not critical messages can be removed after a short display.
|
||||
* @protected
|
||||
* @method warning
|
||||
*/
|
||||
warning: function(message, dismissable) {
|
||||
var icontemplate = this.get_dialogue_element(SELECTOR.ICONMESSAGECONTAINER);
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
var delay = 15, duration = 1;
|
||||
var messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-warning';
|
||||
if (dismissable) {
|
||||
delay = 4;
|
||||
messageclasses = 'assignfeedback_editpdf_warningmessages alert alert-info';
|
||||
}
|
||||
var warningelement = Y.Node.create('<div class="' + messageclasses + '" role="alert"></div>');
|
||||
|
||||
// Copy info icon template.
|
||||
warningelement.append(icontemplate.one('*').cloneNode());
|
||||
|
||||
// Append the message.
|
||||
warningelement.append(message);
|
||||
|
||||
// Add the entire warning to the container.
|
||||
warningregion.prepend(warningelement);
|
||||
|
||||
// Remove the message after a short delay.
|
||||
warningelement.transition(
|
||||
{
|
||||
duration: duration,
|
||||
delay: delay,
|
||||
opacity: 0
|
||||
},
|
||||
function() {
|
||||
warningelement.remove();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* The info about all pages in the pdf has been returned.
|
||||
*
|
||||
@@ -564,7 +605,8 @@ EDITOR.prototype = {
|
||||
* @method prepare_pages_for_display
|
||||
*/
|
||||
prepare_pages_for_display: function(data) {
|
||||
var i, j, comment, error;
|
||||
var i, j, comment, error, annotation, readonly;
|
||||
|
||||
if (!data.pagecount) {
|
||||
if (this.dialogue) {
|
||||
this.dialogue.hide();
|
||||
@@ -590,11 +632,17 @@ EDITOR.prototype = {
|
||||
comment.rawtext);
|
||||
}
|
||||
for (j = 0; j < this.pages[i].annotations.length; j++) {
|
||||
data = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(data.type, data);
|
||||
annotation = this.pages[i].annotations[j];
|
||||
this.pages[i].annotations[j] = this.create_annotation(annotation.type, annotation);
|
||||
}
|
||||
}
|
||||
|
||||
readonly = this.get('readonly');
|
||||
if (!readonly && data.partial) {
|
||||
// Warn about non converted files, but only for teachers.
|
||||
this.warning(M.util.get_string('partialwarning', 'assignfeedback_editpdf'), false);
|
||||
}
|
||||
|
||||
// Update the ui.
|
||||
if (this.quicklist) {
|
||||
this.quicklist.load();
|
||||
@@ -1181,6 +1229,7 @@ EDITOR.prototype = {
|
||||
* @method save_current_page
|
||||
*/
|
||||
save_current_page: function() {
|
||||
this.clear_warnings(false);
|
||||
if (this.get('destroyed')) {
|
||||
return;
|
||||
}
|
||||
@@ -1208,16 +1257,9 @@ EDITOR.prototype = {
|
||||
if (jsondata.error) {
|
||||
return new M.core.ajaxException(jsondata);
|
||||
}
|
||||
// Show warning that we have not saved the feedback.
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESINPUT).set('value', 'true');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('opacity', 1);
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'inline-block');
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).transition({
|
||||
duration: 1,
|
||||
delay: 2,
|
||||
opacity: 0
|
||||
}, function() {
|
||||
Y.one(SELECTOR.UNSAVEDCHANGESDIV).setStyle('display', 'none');
|
||||
});
|
||||
this.warning(M.util.get_string('draftchangessaved', 'assignfeedback_editpdf'), true);
|
||||
} catch (e) {
|
||||
return new M.core.exception(e);
|
||||
}
|
||||
@@ -1292,6 +1334,22 @@ EDITOR.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all current warning messages from display.
|
||||
* @protected
|
||||
* @method clear_warnings
|
||||
* @param {Boolean} allwarnings If true, all previous warnings are removed.
|
||||
*/
|
||||
clear_warnings: function(allwarnings) {
|
||||
// Remove all warning messages, they may not relate to the current document or page anymore.
|
||||
var warningregion = this.get_dialogue_element(SELECTOR.WARNINGMESSAGECONTAINER);
|
||||
if (allwarnings) {
|
||||
warningregion.empty();
|
||||
} else {
|
||||
warningregion.all('.alert-info').remove(true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the image for this pdf page and remove the loading icon (if there).
|
||||
* @protected
|
||||
@@ -1358,6 +1416,7 @@ EDITOR.prototype = {
|
||||
pageselect.removeAttribute('disabled');
|
||||
pageselect.on('change', function() {
|
||||
this.currentpage = pageselect.get('value');
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
}, this);
|
||||
|
||||
@@ -1381,6 +1440,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage < 0) {
|
||||
this.currentpage = 0;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
@@ -1395,6 +1455,7 @@ EDITOR.prototype = {
|
||||
if (this.currentpage >= this.pages.length) {
|
||||
this.currentpage = this.pages.length - 1;
|
||||
}
|
||||
this.clear_warnings(false);
|
||||
this.change_page();
|
||||
},
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ var AJAXBASE = M.cfg.wwwroot + '/mod/assign/feedback/editpdf/ajax.php',
|
||||
COMMENTMENU: '.commentdrawable a',
|
||||
ANNOTATIONCOLOURBUTTON: '.annotationcolourbutton',
|
||||
DELETEANNOTATIONBUTTON: '.deleteannotationbutton',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_unsavedchanges',
|
||||
WARNINGMESSAGECONTAINER: '.warningmessages',
|
||||
ICONMESSAGECONTAINER: '.infoicon',
|
||||
UNSAVEDCHANGESDIV: '.assignfeedback_editpdf_warningmessages',
|
||||
UNSAVEDCHANGESINPUT: 'input[name="assignfeedback_editpdf_haschanges"]',
|
||||
STAMPSBUTTON: '.currentstampbutton',
|
||||
DIALOGUE: '.' + CSS.DIALOGUE
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"querystring-stringify-simple",
|
||||
"moodle-core-notification-dialog",
|
||||
"moodle-core-notification-alert",
|
||||
"moodle-core-notification-warning",
|
||||
"moodle-core-notification-exception",
|
||||
"moodle-core-notification-ajaxexception"
|
||||
]
|
||||
|
||||
@@ -486,7 +486,6 @@
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
background-color: #fff;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.path-mod-assign [data-region="review-panel"] [data-region="review-panel-toggle"] .expand-icon,
|
||||
@@ -978,7 +977,6 @@
|
||||
left: auto;
|
||||
right: 15px;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
@@ -1087,7 +1085,6 @@
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0 0 4px 0;
|
||||
background-color: #fff;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.path-mod-assign [data-region="review-panel"] [data-region="review-panel-toggle"] .expand-icon,
|
||||
|
||||
@@ -642,8 +642,8 @@ $popout-header-height: 4rem;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_widget .label {
|
||||
@extend .tag;
|
||||
@extend .tag-info;
|
||||
@extend .alert;
|
||||
@extend .alert-info;
|
||||
}
|
||||
|
||||
.assignfeedback_editpdf_menu {
|
||||
|
||||
@@ -5792,7 +5792,7 @@ tbody.collapse.show {
|
||||
#page-admin-index .adminwarning,
|
||||
#page-admin-index .adminerror, .que .formulation,
|
||||
.que .outcome,
|
||||
.que .comment {
|
||||
.que .comment, .assignfeedback_editpdf_widget .label {
|
||||
position: relative;
|
||||
padding: 0.75rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
@@ -5841,13 +5841,13 @@ tbody.collapse.show {
|
||||
.alert-success .alert-link, .que .comment .alert-link {
|
||||
color: #1f3e1f; }
|
||||
|
||||
.alert-info, #page-admin-index .releasenoteslink, #adminsettings .form-overridden, .que .formulation {
|
||||
.alert-info, #page-admin-index .releasenoteslink, #adminsettings .form-overridden, .que .formulation, .assignfeedback_editpdf_widget .label {
|
||||
color: #2f6473;
|
||||
background-color: #def2f8;
|
||||
border-color: #d1edf6; }
|
||||
.alert-info hr, #page-admin-index .releasenoteslink hr, #adminsettings .form-overridden hr, .que .formulation hr {
|
||||
.alert-info hr, #page-admin-index .releasenoteslink hr, #adminsettings .form-overridden hr, .que .formulation hr, .assignfeedback_editpdf_widget .label hr {
|
||||
border-top-color: #bce5f2; }
|
||||
.alert-info .alert-link, #page-admin-index .releasenoteslink .alert-link, #adminsettings .form-overridden .alert-link, .que .formulation .alert-link {
|
||||
.alert-info .alert-link, #page-admin-index .releasenoteslink .alert-link, #adminsettings .form-overridden .alert-link, .que .formulation .alert-link, .assignfeedback_editpdf_widget .label .alert-link {
|
||||
color: #20454f; }
|
||||
|
||||
.alert-warning,
|
||||
@@ -8524,7 +8524,7 @@ a.dimmed_text:visited,
|
||||
/* stylelint-disable function-url-scheme-blacklist */
|
||||
/* stylelint-enable function-url-scheme-blacklist */
|
||||
.tag, .statusok, .statuswarning, .statusserious,
|
||||
.statuscritical, .que .correctness, .assignfeedback_editpdf_widget .label, .label, .badge {
|
||||
.statuscritical, .que .correctness, .label, .badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.4em;
|
||||
font-size: 75%;
|
||||
@@ -8570,9 +8570,9 @@ a.dimmed_text:visited,
|
||||
#page-admin-report-backups-index .backup-notyetrun[href]:focus {
|
||||
background-color: #449d44; }
|
||||
|
||||
.tag-info, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release, .assignfeedback_editpdf_widget .label {
|
||||
.tag-info, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release {
|
||||
background-color: #5bc0de; }
|
||||
.tag-info[href]:hover, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release[href]:hover, .assignfeedback_editpdf_widget .label[href]:hover, .tag-info[href]:focus, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release[href]:focus, .assignfeedback_editpdf_widget .label[href]:focus {
|
||||
.tag-info[href]:hover, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release[href]:hover, .tag-info[href]:focus, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release[href]:focus {
|
||||
background-color: #31b0d5; }
|
||||
|
||||
.tag-warning, .statuswarning, #page-admin-report-backups-index .backup-warning, #page-admin-index .updateplugin .updatepluginconfirmexternal, #page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity100 .info.release,
|
||||
@@ -12424,7 +12424,9 @@ span.editinstructions {
|
||||
#course-category-listings .select-a-category .que .outcome,
|
||||
.que #course-category-listings .select-a-category .outcome,
|
||||
#course-category-listings .select-a-category .que .comment,
|
||||
.que #course-category-listings .select-a-category .comment {
|
||||
.que #course-category-listings .select-a-category .comment,
|
||||
#course-category-listings .select-a-category .assignfeedback_editpdf_widget .label,
|
||||
.assignfeedback_editpdf_widget #course-category-listings .select-a-category .label {
|
||||
margin: 1em; }
|
||||
|
||||
#course-category-listings #course-listing .listitem .drag-handle {
|
||||
|
||||
Reference in New Issue
Block a user