From 3070ed6005ff9155e6599fd6436c49584a015df9 Mon Sep 17 00:00:00 2001 From: mfaber Date: Thu, 22 Aug 2013 20:03:17 +0200 Subject: [PATCH 1/2] DEV: updated quexml class (file provided by Adam Zammit) --- application/libraries/admin/quexmlpdf.php | 1371 +++++++++++++-------- 1 file changed, 871 insertions(+), 500 deletions(-) diff --git a/application/libraries/admin/quexmlpdf.php b/application/libraries/admin/quexmlpdf.php index d3bbdd44a1a..bddda024520 100644 --- a/application/libraries/admin/quexmlpdf.php +++ b/application/libraries/admin/quexmlpdf.php @@ -10,6 +10,7 @@ * other free or open source software licenses. * See COPYRIGHT.php for copyright notices and details. * + * $Id$ */ /** @@ -41,7 +42,7 @@ class quexmlpdf extends pdf { /** * Pixels per inch of exported document - * + * * @var int Defaults to 300. */ protected $ppi = 300; @@ -55,24 +56,24 @@ class quexmlpdf extends pdf { /** * Corner border (the number of mm between the edge of the page and the start of the document) - * - * @var int Defaults to 15. + * + * @var int Defaults to 15. * @since 2010-09-02 */ - protected $cornerBorder = 13; + protected $cornerBorder = 14; /** * The length in MM of a corner line - * - * @var mixed Defaults to 20. + * + * @var mixed Defaults to 20. * @since 2010-09-20 */ protected $cornerLength = 20; /** * The width in MM of a corner line - * - * @var mixed Defaults to 0.5. + * + * @var mixed Defaults to 0.5. * @since 2010-09-20 */ protected $cornerWidth = 0.5; @@ -80,8 +81,8 @@ class quexmlpdf extends pdf { /** * The TCPDF barcode type - * - * @var bool Defaults to 'I25'. + * + * @var bool Defaults to 'I25'. * @since 2010-09-20 * @see write1DBarcode */ @@ -89,8 +90,8 @@ class quexmlpdf extends pdf { /** * The x position in MM of the barcode - * - * @var bool Defaults to 138. + * + * @var bool Defaults to 138. * @since 2010-09-20 * @deprecated * @see $barcodeMarginX @@ -100,48 +101,48 @@ class quexmlpdf extends pdf { /** * The distance between the right hand page border and * the end of the barcode in MM - * - * @var bool Defaults to 23. + * + * @var bool Defaults to 23. * @since 2011-10-25 */ protected $barcodeMarginX = 23; /** * Y position of barcode in mm - * - * @var bool Defaults to 6. + * + * @var bool Defaults to 6. * @since 2010-09-20 */ protected $barcodeY = 6; /** * Width of the barcode in mm - * - * @var bool Defaults to 49. + * + * @var bool Defaults to 49. * @since 2010-09-20 */ protected $barcodeW = 49; /** * Height of the barcode in mm - * - * @var bool Defaults to 6. + * + * @var bool Defaults to 6. * @since 2010-09-20 */ protected $barcodeH = 6; /** * The questionnaire ID of this form - * - * @var mixed Defaults to 1. + * + * @var mixed Defaults to 1. * @since 2010-09-20 */ protected $questionnaireId = 1; /** * The length of a the id portion barcode - * - * @var int Defaults to 6. + * + * @var int Defaults to 6. * @since 2010-09-20 * @see $pageLength */ @@ -149,8 +150,8 @@ class quexmlpdf extends pdf { /** * The length of the page portion of the barcode - * - * @var mixed Defaults to 2. + * + * @var mixed Defaults to 2. * @since 2010-09-20 * @see $idLength */ @@ -158,24 +159,24 @@ class quexmlpdf extends pdf { /** * width of the question title column in MM - * - * @var mixed Defaults to 14. + * + * @var mixed Defaults to 14. * @since 2010-09-20 */ protected $questionTitleWidth = 14; /** * The suffix of the question title. i.e. A15. (the . is the suffix) - * - * @var mixed Defaults to ".". + * + * @var mixed Defaults to ".". * @since 2012-01-31 */ protected $questionTitleSuffix = "."; /** * Width of question text in MM - * - * @var mixed Defaults to 120. + * + * @var mixed Defaults to 120. * @since 2010-09-20 * @deprecated */ @@ -183,8 +184,8 @@ class quexmlpdf extends pdf { /** * Right margin of question text in MM - * - * @var mixed Defaults to 40. + * + * @var mixed Defaults to 40. * @since 2012-01-11 * @see $questionTextWidth */ @@ -192,36 +193,42 @@ class quexmlpdf extends pdf { /** * Height of the border between questions in MM - * - * @var mixed Defaults to 1. + * + * @var mixed Defaults to 1. * @since 2010-09-20 */ protected $questionBorderBottom = 1; - + /** * Border after a help before directive - * - * @var mixed Defaults to 3. + * + * @var mixed Defaults to 3. * @since 2012-01-31 */ protected $helpBeforeBorderBottom = 3; /** * Border before a help before directive - * - * @var mixed Defaults to 3. + * + * @var mixed Defaults to 3. * @since 2012-01-31 */ protected $helpBeforeBorderTop = 3; /** * Width of the skip column area (where skip text is written) - * - * @var string Defaults to 20. + * + * @var string Defaults to 20. * @since 2010-09-20 */ protected $skipColumnWidth = 20; + /** + * The default style for the text of the questionnaire + * + * @var string Defaults to "". + * @since 2010-09-16 + */ protected $style = ""; - - /** - * Width of the area of each single response - * - * @var string Defaults to 10. + * Width of the area of each single response + * + * @var string Defaults to 10. * @since 2010-09-20 * Height of the area of a single response where displayed horizontally - * - * @var string Defaults to 10.5. + * + * @var string Defaults to 10.5. * @since 2011-12-20 */ - protected $singleResponseHorizontalHeight = 10.5; + protected $singleResponseHorizontalHeight = 11; /** * Height of the are of each single response (includes guiding lines) - * - * @var string Defaults to 9. + * + * @var string Defaults to 9. * @since 2010-09-20 */ protected $singleResponseAreaHeight = 9; /** * Width of a single response box - * - * @var string Defaults to 5. + * + * @var string Defaults to 5. * @since 2010-09-20 */ protected $singleResponseBoxWidth = 5; /** * Height of a single response box - * - * @var string Defaults to 5. + * + * @var string Defaults to 5. * @since 2010-09-20 */ protected $singleResponseBoxHeight = 5; /** * Width of a response boxes border - * - * @var string Defaults to 0.1. + * + * @var string Defaults to 0.1. * @since 2010-09-20 */ protected $singleResponseBoxBorder = 0.15; /** * Length of the "eye guide" for a vertical response box - * - * @var string Defaults to 1. + * + * @var string Defaults to 1. * @since 2010-09-20 */ protected $singleResponseBoxLineLength = 1; /** * Vertical area taken up by a response box - * - * @var string Defaults to 15. + * + * @var string Defaults to 15. * @since 2010-09-20 */ protected $singleResponseVerticalAreaWidth = 13; /** * Vertical area taken up by a "small" vertical response area - * - * @var string Defaults to 9. + * + * @var string Defaults to 9. * @since 2010-09-20 */ protected $singleResponseVerticalAreaWidthSmall = 9; /** * Maximum number of horizontal boxes to display normally before shrinking horizontal area width - * - * @var int Defaults to 10. + * + * @var int Defaults to 10. * @since 2010-09-08 */ protected $singleResponseHorizontalMax = 10; + /** + * Allow single choice horizontal arrays to be split over multiple pages/columns + * + * @var array Defaults to false. + * @since 2012-08-10 + */ + protected $allowSplittingSingleChoiceHorizontal = true; + /** * The height of an arrow - * - * @var array Defaults to 3. + * + * @var array Defaults to 3. * @since 2010-09-20 */ protected $arrowHeight = 3; /** * The width of a text response box - * - * @var mixed Defaults to 6. + * + * @var mixed Defaults to 6. * @since 2010-09-20 */ protected $textResponseWidth = 6; /** * The border width of a text response box - * + * * @var mixed Defaults to 0.15. Any less than this may produce printing problems * @since 2010-09-20 */ @@ -342,16 +355,24 @@ class quexmlpdf extends pdf { /** * The height of a text response box - * - * @var mixed Defaults to 8. + * + * @var mixed Defaults to 8. * @since 2010-09-20 */ protected $textResponseHeight = 8; + /** + * The height of a pre-filled response barcode + * + * @var bool Defaults to 6. + * @since 2012-06-22 + */ + protected $barcodeResponseHeight = 6; + /** * The maximum number of text responses per line - * - * @var mixed Defaults to 24. + * + * @var mixed Defaults to 24. * @since 2010-09-20 * @deprecated * @see $textResponseMarginX @@ -361,16 +382,16 @@ class quexmlpdf extends pdf { /** * The left hand margin of text responses to auto calculate responses * per line (mm) - * - * @var mixed Defaults to 13. + * + * @var mixed Defaults to 13. * @since 2011-10-25 */ protected $textResponseMarginX = 13; /** * Maximum number of text responses boxes where the label should appear on the same line - * - * @var mixed Defaults to 16. + * + * @var mixed Defaults to 16. * @since 2010-09-20 * @deprecated * @see $labelTextResponsesSameLineMarginX @@ -380,52 +401,69 @@ class quexmlpdf extends pdf { /** * The left hand margin of text responses to auto calculated responses * per line where the label should appear on the same line (mm) - * - * @var mixed Defaults to 62. + * + * @var mixed Defaults to 62. * @since 2011-10-25 */ protected $labelTextResponsesSameLineMarginX = 62; /** * The gap between multi line text responses - * - * @var mixed Defaults to 1. + * + * @var mixed Defaults to 1. * @since 2010-09-20 */ protected $textResponseLineSpacing = 1; /** * The vertical gap between subquestions in mm - * - * @var string Defaults to 2. + * + * @var string Defaults to 2. * @since 2010-09-02 */ protected $subQuestionLineSpacing = 2; /** * The multiplier from long text response width specified to the height in mm - * - * @var mixed Defaults to 1. + * + * @var mixed Defaults to 1. * @since 2010-09-20 */ protected $longTextResponseHeightMultiplier = 1; /** * Width of a long text response box - * - * @var mixed Defaults to 145. + * + * @var mixed Defaults to 145. * @since 2010-09-20 + * @deprecated + * @see drawLongText() for the new calculation of long text box width */ - protected $longTextResponseWidth = 145; + //protected $longTextResponseWidth = 145; /** * Default number of characters to store in a long text field - * + * * @var int Default is 1024; * @since 2010-09-02 */ protected $longTextStorageWidth = 1024; + /** + * The number of columns to display the sections/questions in on each page + * + * @var int Defaults to 1. + * @since 2012-05-30 + */ + protected $columns = 1; + + /** + * The width of the border between columns + * + * @var int Defaults to 1. + * @since 2012-05-31 + */ + protected $columnBorder = 1; /** * The layout of the form for importing in to queXF @@ -433,238 +471,254 @@ class quexmlpdf extends pdf { * @var array Defaults to empty array * @link http://quexf.sourceforge.net/ */ - protected $layout = array(); + protected $layout = array(); /** * Array to store section information for layout - * + * * @var array Defaults to empty array * @since 2010-09-02 */ protected $section = array(); /** - * An array of key: skip target, value: last originating question + * An array of key: skip target, value: last originating question * that skips to the target - * - * @var string Defaults to array(). + * + * @var string Defaults to array(). * @since 2012-01-31 */ protected $skipToRegistry = array(); /** * Page counter pointer (links to barcode id of page) - * - * @var mixed Defaults to "". + * + * @var mixed Defaults to "". * @since 2010-09-02 */ protected $layoutCP = ""; /** * Section counter pointer - * - * @var string Defaults to 0. + * + * @var string Defaults to 0. * @since 2010-09-02 */ protected $sectionCP = 0; /** * Box group counter pointer - * - * @var bool Defaults to 0. + * + * @var bool Defaults to 0. * @since 2010-09-02 */ protected $boxGroupCP = 0; /** * Box counter pointer - * - * @var int Defaults to 0. + * + * @var int Defaults to 0. */ protected $boxCP = 0; + /** + * Column counter pointer (current column) + * + * @var mixed Defaults to 0. + * @since 2012-05-30 + */ + protected $columnCP = 0; + /** * Background colour of a question - * - * @var bool Defaults to array(220,220,220). + * + * @var bool Defaults to array(220,220,220). * @since 2010-09-15 */ protected $backgroundColourQuestion = array(241); /** * The bacground colour of a section - * - * @var bool Defaults to array(200,200,200). + * + * @var bool Defaults to array(200,200,200). * @since 2010-09-20 */ protected $backgroundColourSection = array(221); /** * Empty background colour - * - * @var bool Defaults to array(255,255,255). + * + * @var bool Defaults to array(255,255,255). * @since 2010-09-20 */ protected $backgroundColourEmpty = array(255); /** * The colour of a line/fill - * - * @var mixed Defaults to array(0,0,0). + * + * @var mixed Defaults to array(0,0,0). * @since 2010-09-20 */ protected $lineColour = array(0); /** * Text colour in grayscale - * - * @var mixed Defaults to 0. + * + * @var mixed Defaults to 0. * @since 2012-04-16 */ protected $textColour = 0; /** - * The text to display before a skip - * - * @var string Defaults to "Skip to ". + * The text to display before a skip + * + * @var string Defaults to "Skip to ". * @since 2010-09-16 */ protected $skipToText = "Skip to "; /** * Should fonts be embedded in the document? - * - * @var mixed Defaults to true. + * + * @var mixed Defaults to true. * @since 2010-09-20 */ protected $embedFonts = true; /** * Height in MM of a VAS response - * - * @var mixed Defaults to 8. + * + * @var mixed Defaults to 8. * @since 2010-09-20 */ protected $vasAreaHeight = 8; /** * Width of a VAS line - * - * @var mixed Defaults to 0.5. + * + * @var mixed Defaults to 0.5. * @since 2010-09-20 */ protected $vasLineWidth = 0.5; + /** + * The width of a line for the default value + * + * @var double Defaults to 0.5. + * @since 2012-06-14 + */ + protected $defaultValueLineWidth = 0.5; + /** * Height of the VAS ending lines in mm - * - * @var mixed Defaults to 4. + * + * @var mixed Defaults to 4. * @since 2010-09-20 */ protected $vasHeight = 4; /** * Length of the vas line itself - * - * @var mixed Defaults to 100. + * + * @var mixed Defaults to 100. * @since 2010-09-20 */ protected $vasLength = 100; /** * The number of increments stored on a vas line - * - * @var mixed Defaults to 100. + * + * @var mixed Defaults to 100. * @since 2010-09-20 */ protected $vasIncrements = 100; /** * The text to separate parent text and subquestion text - * - * @var string Defaults to " : ". + * + * @var string Defaults to " : ". * @since 2010-09-22 */ protected $subQuestionTextSeparator = " : "; /** * The top margin for questionnaireInfo section - * - * @var mixed Defaults to 5. + * + * @var mixed Defaults to 5. * @since 2010-10-29 */ protected $questionnaireInfoMargin = 20; /** * Height of a response label - * - * @var resource Defaults to 10. + * + * @var resource Defaults to 10. * @since 2010-11-05 */ protected $responseLabelHeight = 10; /** * Font size for response label - * - * @var resource Defaults to 8. + * + * @var resource Defaults to 8. * @since 2010-11-05 */ protected $responseLabelFontSize = 7.5; /** * A smaller font size for response labels where otherwise will break the line - * - * @var resource Defaults to 6. + * + * @var resource Defaults to 6. * @since 2012-03-30 */ protected $responseLabelFontSizeSmall = 6.5; /** * Reduce the font size of a response label if any words are longer than this - * - * @var resource Defaults to 7. + * + * @var resource Defaults to 7. * @since 2012-03-30 */ protected $responseLabelSmallWordLength = 7; - + /** * Font size for response text - * - * @var resource Defaults to 10. + * + * @var resource Defaults to 10. * @since 2010-11-05 */ protected $responseTextFontSize = 10; /** * Font size of the skip to text - * - * @var string Defaults to 8. + * + * @var string Defaults to 8. * @since 2010-11-05 */ protected $skipToTextFontSize = 8; /** * Default font - * - * @var string Defaults to 'freeserif'. + * + * @var string Defaults to 'freeserif'. * @since 2010-11-05 */ protected $defaultFont = 'freeserif'; /** * Height of a section break in mm - * - * @var string Defaults to 18. + * + * @var string Defaults to 18. * @since 2010-11-05 */ protected $sectionHeight = 18; /** * Return the length of the longest word - * - * @param mixed $txt - * + * + * @param mixed $txt + * * @return int Length of longest word * @author Adam Zammit * @since 2012-03-30 @@ -691,20 +745,20 @@ protected function wordLength($txt) * VALUES(4, 'Number'); * VALUES(5, 'Barcode'); * VALUES(6, 'Long text'); - * + * * @param int $type The type of box group for verification purposes * @param string $varname The variable name - * @param string $label The label for the box group Optional, defaults to "". - * @param int $width The width of this group Optional, defaults to 1. - * + * @param string $label The label for the box group Optional, defaults to "". + * @param int $width The width of this group Optional, defaults to 1. + * * @author Adam Zammit * @since 2010-09-02 */ protected function addBoxGroup($type,$varname,$label = "", $width = 1) { $this->boxGroupCP++; - $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP] = - array( 'type' => $type, + $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP] = + array( 'type' => $type, 'width' => $width, 'varname' => $varname, 'sortorder' => $this->boxGroupCP, @@ -715,12 +769,12 @@ protected function addBoxGroup($type,$varname,$label = "", $width = 1) /** * Add a new box group which is a copy of the previous one (if exists) - * + * * @author Adam Zammit * @since 2012-03-26 */ protected function addBoxGroupCopyPrevious() - { + { if (isset($this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP])) { $a = $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]; @@ -731,19 +785,19 @@ protected function addBoxGroupCopyPrevious() /** * Add a box to the page layout system - * + * * @param int $tlx Top left X * @param int $tly Top left Y * @param int $brx Bottom right X * @param int $bry Bottom right Y - * @param string $value Optional, defaults to "". - * @param string $label Optional, defaults to "". - * + * @param string $value Optional, defaults to "". + * @param string $label Optional, defaults to "". + * */ protected function addBox($tlx,$tly,$brx,$bry,$value = "",$label = "") { $this->boxCP++; - $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]['box'][] = + $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]['box'][] = array( 'tlx' => $this->mm2px($tlx), 'tly' => $this->mm2px($tly), 'brx' => $this->mm2px($brx), @@ -756,9 +810,9 @@ protected function addBox($tlx,$tly,$brx,$bry,$value = "",$label = "") $type = $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]['type']; $count = count($this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]['box']); $width = $this->layout[$this->layoutCP]['boxgroup'][$this->boxGroupCP]['width']; - + switch($type){ - case 1: //Single choice + case 1: //Single choice case 2: //Multiple choice if (strlen($value) > $width) $width = strlen($value); if (strlen($count) > $width) $width = strlen($count); @@ -775,9 +829,86 @@ protected function addBox($tlx,$tly,$brx,$bry,$value = "",$label = "") } + /** + * Get the response label font sizes (normal and small) + * + * @return array containing the normal font size as the first element and small as second + * @author Adam Zammit + * @since 2013-04-10 + */ + public function getResponseLabelFontSize() + { + return array($this->responseLabelFontSize,$this->responseLabelFontSizeSmall); + } + + /** + * Set the response label font sizes + * + * @param array $sizes normal font size first then small + * + * @author Adam Zammit + * @since 2013-04-10 + */ + public function setResponseLabelFontSize($sizes) + { + $this->responseLabelFontSize = intval($sizes[0]); + $this->responseLabelFontSizeSmall = intval($sizes[1]); + } + + /** + * Get the response text font size + * + * @return int The response text font size + * @author Adam Zammit + * @since 2013-04-10 + */ + public function getResponseTextFontSize() + { + return $this->responseTextFontSize; + } + + /** + * Set the response text font size + * + * @param int $size + * + * @author Adam Zammit + * @since 2013-04-10 + */ + public function setResponseTextFontSize($size) + { + $this->responseTextFontSize = intval($size); + } + + /** + * Get the style without any HTML/etc formatting + * + * @return string The style without HTML or tabs + * @author Adam Zammit + * @since 2013-04-10 + */ + public function getStyle() + { + return strip_tags(str_replace("\t","",$this->style)); + } + + /** + * Set the CSS styling of some questionnaire elements + * + * @param string $style The CSS styling of some questionnire elements + * + * @return none + * @author Adam Zammit + * @since 2013-04-10 + */ + public function setStyle($style) + { + $this->style = ""; + } + /** * Export the layout as an XML file - * + * * @return string The XML layout in queXF Banding XML format * @author Adam Zammit * @since 2010-09-20 @@ -814,7 +945,7 @@ public function getLayout() foreach ($val as $pk => $pv) { if ($pk != 'boxgroup') - { + { $tmpe = $doc->createElement($pk); $tmpv = $doc->createTextNode($pv); $tmpe->appendChild($tmpv); @@ -866,10 +997,10 @@ public function getLayout() /** * Set font size and style - * + * * @param string $size Optional, defaults to 12 - * @param string $style Optional, defaults to ''. - * + * @param string $style Optional, defaults to ''. + * * @return TODO * @author Adam Zammit * @since 2010-11-05 @@ -882,7 +1013,7 @@ protected function setDefaultFont($size = 12,$style = '') /** * Initialise TCPDF width some default values and embedded fonts - * + * * @return TODO * @author Adam Zammit * @since 2010-09-20 @@ -900,10 +1031,10 @@ protected function init() $this->AddFont('freeserif','B'); $this->AddFont('freeserif','I'); $this->AddFont('freeserif','BI'); - + $this->SetFont($this->defaultFont); } - + // set document information $this->SetCreator('queXMLPDF (http://quexml.sourceforge.net)'); $this->SetAuthor('Adam Zammit '); @@ -913,11 +1044,14 @@ protected function init() //set text colour $this->SetTextColor($this->textColour); + + //set column pointer + $this->columnCP = -1; } /** * Override of TCPDF Header function to blank - * + * * @author Adam Zammit * @since 2010-09-20 */ @@ -926,7 +1060,7 @@ public function Header(){ /** * Override of TCPDF Footer function to blank - * + * * @author Adam Zammit */ public function Footer(){ @@ -934,9 +1068,9 @@ public function Footer(){ /** * Set the background wash of the page - * - * @param mixed $type Optional, defaults to 'empty'. - * + * + * @param mixed $type Optional, defaults to 'empty'. + * * @author Adam Zammit * @since 2010-09-02 */ @@ -958,7 +1092,7 @@ protected function setBackground($type = 'empty') /* * The X coordinate of the start of the page proper - * + * * @return int The X coordinate of the start of the page * @author Adam Zammit * @since 2010-09-02 @@ -968,9 +1102,24 @@ public function getMainPageX() return ($this->cornerBorder + $this->cornerWidth); } + /** + * The X coordinate of the start of the column + * + * @return int The X coordinate of the start of the current column + * @author Adam Zammit + * @since 2012-05-30 + */ + public function getColumnX() + { + $border = 0; + if ($this->columnCP > 0) + $border = $this->columnBorder; + return $this->getMainPageX() + ($this->columnCP * ($this->getColumnWidth() + $border)) + $border; + } + /** * The width of the writeable page - * + * * @return int The width of the writeable page * @author Adam Zammit * @since 2010-09-02 @@ -980,18 +1129,34 @@ public function getMainPageWidth() return ($this->getPageWidth() - (($this->cornerBorder * 2.0) + ($this->cornerWidth * 2.0))); } + /** + * The width of the writable column + * + * @return int The width of the current column + * @author Adam Zammit + * @since 2012-05-30 + */ + public function getColumnWidth() + { + $border = 0; + if ($this->columnCP > 0) + $border = $this->columnBorder; + return ((1 / $this->columns) * $this->getMainPageWidth()) - $border; + } + /** * Draw a horizontal response box with possible eye guides and arrows - * + * * @param int $x The x position of the box area (top left) * @param int $y The y position of the box area (top left) * @param string $position What position the box is in for the eye guides * @param bool $downarrow Draw a down arrow? * @param bool $rightarrow Draw an arrow to the right? * @param bool $smallwidth Whether or not to use the small width + * @param bool $filled Whether or not to have the box pre-filled * */ - protected function drawHorizontalResponseBox($x,$y,$position = 'only',$downarrow = false, $rightarrow = false, $smallwidth = false) + protected function drawHorizontalResponseBox($x,$y,$position = 'only',$downarrow = false, $rightarrow = false, $smallwidth = false, $filled =false) { $this->SetDrawColor($this->lineColour[0]); $this->SetLineWidth($this->singleResponseBoxBorder); @@ -1001,10 +1166,10 @@ protected function drawHorizontalResponseBox($x,$y,$position = 'only',$downarrow //centre on y $y = $y + (($this->singleResponseHorizontalHeight - $this->singleResponseBoxHeight) / 2.0); - - if ($smallwidth) + + if ($smallwidth) $areawidth = $this->singleResponseVerticalAreaWidthSmall; - else + else $areawidth = $this->singleResponseVerticalAreaWidth; @@ -1012,7 +1177,7 @@ protected function drawHorizontalResponseBox($x,$y,$position = 'only',$downarrow $this->SetLineStyle(array('dash' => '1')); - if ($position == 'last' || $position == 'middle') + if ($position == 'last' || $position == 'middle') { $this->Line($x, $boxmid, $x + $linelength,$boxmid); } @@ -1024,32 +1189,42 @@ protected function drawHorizontalResponseBox($x,$y,$position = 'only',$downarrow $this->SetLineStyle(array('dash' => '0')); $this->Rect($x + $linelength,$y,$this->singleResponseBoxWidth,$this->singleResponseBoxHeight,'DF',array(),$this->backgroundColourEmpty); - $this->setBackground('question'); + + if ($filled) + { + //draw a cross + $this->SetLineWidth($this->defaultValueLineWidth); + $this->Line($x + $linelength, $y, $x + $linelength + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight); + $this->Line($x + $linelength + $this->singleResponseBoxWidth, $y, $x + $linelength, $y + $this->singleResponseBoxHeight); + } + + $this->setBackground('question'); return array($x + $linelength,$y,$x + $linelength + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight); //return the posistion for banding } /** * Draw a vertical response box with possible eye guides and arrows - * + * * @param int $x The x position of the box area (top left) * @param int $y The y position of the box area (top left) * @param string $position What position the box is in for the eye guides * @param bool $downarrow Draw a down arrow? * @param bool $rightarrow Draw an arrow to the right? + * @param bool $filled Whether or not to have the box pre-filled * */ - protected function drawVerticalResponseBox($x,$y,$position = 'only',$downarrow = false, $rightarrow = false) + protected function drawVerticalResponseBox($x,$y,$position = 'only',$downarrow = false, $rightarrow = false, $filled = false) { $this->SetDrawColor($this->lineColour[0]); $this->SetLineWidth($this->singleResponseBoxBorder); - + if (!$downarrow) { $y = $y + (($this->singleResponseAreaHeight - $this->singleResponseBoxHeight) / 2.0); } $boxmid = ($x + ($this->singleResponseBoxWidth / 2.0)); - if ($position == 'first' || $position == 'middle') + if ($position == 'first' || $position == 'middle') { $this->Line($boxmid, ($y + $this->singleResponseBoxHeight), $boxmid, ($y + $this->singleResponseBoxHeight + $this->singleResponseBoxLineLength)); } @@ -1062,7 +1237,7 @@ protected function drawVerticalResponseBox($x,$y,$position = 'only',$downarrow = { $this->SetFillColor($this->lineColour[0]); $this->Polygon(array($x, $y + $this->singleResponseBoxHeight, $boxmid, $y + $this->singleResponseBoxHeight + $this->arrowHeight, $x + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight),'DF',array(),$this->lineColour); - $this->setBackground('empty'); + $this->setBackground('empty'); } if ($rightarrow !== false) @@ -1070,18 +1245,18 @@ protected function drawVerticalResponseBox($x,$y,$position = 'only',$downarrow = //Draw skipto $boxymid = ($y + ($this->singleResponseBoxHeight / 2.0)); $this->SetFillColor($this->lineColour[0]); - $this->Polygon(array($x + $this->singleResponseBoxWidth, $y, $x + $this->singleResponseBoxWidth + $this->arrowHeight, $boxymid, $x + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight),'DF',array(),$this->lineColour); - $this->setBackground('empty'); + $this->Polygon(array($x + $this->singleResponseBoxWidth, $y, $x + $this->singleResponseBoxWidth + $this->arrowHeight, $boxymid, $x + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight),'DF',array(),$this->lineColour); + $this->setBackground('empty'); //Now draw the text //Start at $x + singleResponseboxWidth + arrowHeight, $y - siongleresponseboxlinelength and go to $skipcolumnwidth wide and singleresponseareHeight high - $this->setBackground('question'); + $this->setBackground('question'); $text = $this->skipToText . $rightarrow; $ypos = $this->GetY(); $this->setDefaultFont($this->skipToTextFontSize,'B'); - $this->MultiCell($this->skipColumnWidth,$this->singleResponseBoxHeight,$text,0,'L',false,0,($this->getPageWidth() - $this->getMainPageX() - $this->skipColumnWidth),$y,true,0,false,true,$this->singleResponseBoxHeight,'M',true); + $this->MultiCell($this->skipColumnWidth,$this->singleResponseBoxHeight,$text,0,'L',false,0,(($this->getColumnWidth() + $this->getColumnX()) - $this->skipColumnWidth),$y,true,0,false,true,$this->singleResponseBoxHeight,'M',true); //Reset to non bold as causing problems with TCPDF HTML CSS conversion $this->setDefaultFont($this->skipToTextFontSize,''); @@ -1091,16 +1266,25 @@ protected function drawVerticalResponseBox($x,$y,$position = 'only',$downarrow = } $this->Rect($x,$y,$this->singleResponseBoxWidth,$this->singleResponseBoxHeight,'DF',array(),$this->backgroundColourEmpty); - $this->setBackground('question'); + + if ($filled) + { + //draw a cross + $this->SetLineWidth($this->defaultValueLineWidth); + $this->Line($x, $y, $x + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight); + $this->Line($x + $this->singleResponseBoxWidth, $y, $x, $y + $this->singleResponseBoxHeight); + } + + $this->setBackground('question'); return array($x,$y,$x + $this->singleResponseBoxWidth, $y + $this->singleResponseBoxHeight); //return the posistion for banding } /** * Return capital letter(s) corresponding to the given number - * - * @param integer $number - * + * + * @param integer $number + * * @return string Letter(s) corresponding to the number * @author Adam Zammit * @since 2010-09-08 @@ -1118,7 +1302,7 @@ public function numberToLetter($number) /** * Get the questionnaire id - * + * * @return int The questionnaire Id * @author Adam Zammit * @since 2010-09-23 @@ -1130,10 +1314,10 @@ public function getQuestionnaireId() /** * Converts a queXML file to the array format required for the create function - * + * * @param string $quexml The queXML file * - * @return array An array readable by create + * @return array An array readable by create * @author Adam Zammit * @since 2010-09-08 * @see create @@ -1141,7 +1325,7 @@ public function getQuestionnaireId() public function createqueXML($quexml) { $xml = new SimpleXMLElement($quexml); - + $q = array(); $scount = 1; @@ -1166,7 +1350,7 @@ public function createqueXML($quexml) $q['infobefore'] .= $qitmp->text . "

"; } } - + foreach($xml->section as $s) { $stmp = array(); @@ -1174,7 +1358,7 @@ public function createqueXML($quexml) $stmp['title'] = "Section " . $sl; $stmp['info'] = ""; $stmp['text'] = ""; - + foreach ($s->sectionInfo as $sitmp) { if ($sitmp->position == 'title') @@ -1186,24 +1370,24 @@ public function createqueXML($quexml) $stmp['info'] .= $sitmp->text . "
"; } } - + $qcount = 1; foreach ($s->question as $qu) { $qtmp = array(); $rstmp = array(); - + $qtmp['title'] = $sl . $qcount . $this->questionTitleSuffix; $qtmp['text'] = ""; foreach ($qu->text as $ttmp) { //Add a new line if we aren't at the end - if ($ttmp != end($qu->text)){ $qtmp['text'] .= "
"; } - + if ($ttmp != end($qu->text)){ $qtmp['text'] .= "
"; } + $qtmp['text'] .= $ttmp; } - + foreach ($qu->specifier as $ttmp) { if (!isset($qtmp['specifier'])) @@ -1211,7 +1395,7 @@ public function createqueXML($quexml) $qtmp['specifier'] .= $ttmp; } - + foreach ($qu->directive as $ttmp) { if ($ttmp->administration == 'self' && $ttmp->position == 'during') @@ -1246,6 +1430,10 @@ public function createqueXML($quexml) $sqtmp['text'] .= $ttmp; } $sqtmp['varname'] = $sq['varName']; + + if (isset($sq['defaultValue'])) + $sqtmp['defaultvalue'] = $sq['defaultValue']; + $rstmp['subquestions'][] = $sqtmp; } @@ -1253,11 +1441,15 @@ public function createqueXML($quexml) { $rtmp = array(); $rstmp['varname'] = $r['varName']; + + if (isset($r['defaultValue'])) + $rstmp['defaultvalue'] = $r['defaultValue']; + if (isset($r->fixed)) { $rtmp['type'] = 'fixed'; $rtmp['width'] = count($r->fixed->category); - if ($r->fixed['rotate'] == "true") + if ($r->fixed['rotate'] == "true") $rtmp['rotate'] = "true"; $ctmp = array(); foreach ($r->fixed->category as $c) @@ -1266,7 +1458,7 @@ public function createqueXML($quexml) $cat['text'] = current($c->label); $cat['value'] = current($c->value); if (isset($c->skipTo)) - { + { $cat['skipto'] = current($c->skipTo); //save a skip $this->skipToRegistry[current($c->skipTo) . $this->questionTitleSuffix] = $qtmp['title']; @@ -1277,10 +1469,14 @@ public function createqueXML($quexml) $oarr = array(); $oarr['width'] = current($c->contingentQuestion->length); $oarr['text'] = current($c->contingentQuestion->text); + + if (isset($c->contingentQuestion['defaultValue'])) + $oarr['defaultvalue'] = $c->contingentQuestion['defaultValue']; + $oarr['varname'] = $c->contingentQuestion['varName']; $cat['other'] = $oarr; - } - $ctmp[] = $cat; + } + $ctmp[] = $cat; } $rtmp['categories'] = $ctmp; } @@ -1291,6 +1487,10 @@ public function createqueXML($quexml) $rtmp['type'] = 'longtext'; else if ($format == 'number' || $format == 'numeric' || $format == 'integer') $rtmp['type'] = 'number'; + else if ($format == 'i25') + $rtmp['type'] = 'i25'; + else if ($format == 'codabar') + $rtmp['type'] = 'codabar'; else $rtmp['type'] = 'text'; $rtmp['width'] = current($r->free->length); @@ -1299,7 +1499,7 @@ public function createqueXML($quexml) else if (isset($r->vas)) { $rtmp['type'] = 'vas'; - $rtmp['width'] = 100; + $rtmp['width'] = 100; $rtmp['labelleft'] = current($r->vas->labelleft); $rtmp['labelright'] = current($r->vas->labelright); } @@ -1319,7 +1519,7 @@ public function createqueXML($quexml) /** * Create a queXML PDF document based on an array * that is structured like a queXML document - * + * * sections (title, text, info) * questions (title, text, varname, helptext, helptextafter) * responses (varname) @@ -1333,7 +1533,7 @@ public function create($questionnaire) { $this->init(); $this->questionnaireId = intval($questionnaire['id']); - $this->newPage(); + $this->newPage(true); //first page //Draw questionnaireInfo before if exists if (isset($questionnaire['infobefore'])) @@ -1345,7 +1545,7 @@ public function create($questionnaire) { //link the section title with the first question for pagination purposes $questions = count($sv['questions']); - + $this->startTransaction(); $this->addSection($sv['text'],$sv['title'],$sv['info']); if ($questions != 0) $this->createQuestion($sv['questions'][0]); @@ -1365,28 +1565,28 @@ public function create($questionnaire) //start from the second question as first is linked to the section (if there is a question in this section) if ($questions != 0) { - foreach(array_slice($sv['questions'], 1) as $qk => $qv) - { - $this->startTransaction(); - //add question here - $this->createQuestion($qv); - if ($this->pageBreakOccured) + foreach(array_slice($sv['questions'], 1) as $qk => $qv) { - $this->pageBreakOccured = false; - $this->rollBackTransaction(true); - $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break - //now draw a background to the bottom of the page - $this->fillPageBackground(); - - $this->newPage(); - //retry question here + $this->startTransaction(); + //add question here $this->createQuestion($qv); + if ($this->pageBreakOccured) + { + $this->pageBreakOccured = false; + $this->rollBackTransaction(true); + $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break + //now draw a background to the bottom of the page + $this->fillPageBackground(); + + $this->newPage(); + //retry question here + $this->createQuestion($qv); + } + else + $this->commitTransaction(); } - else - $this->commitTransaction(); } } - } //Draw questionnaireInfo after if exists @@ -1403,7 +1603,7 @@ public function create($questionnaire) $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break //now draw a background to the bottom of the page $this->fillPageBackground(); - + $this->newPage(); //retry question here $this->drawInfo($questionnaire['infoafter']); @@ -1415,13 +1615,13 @@ public function create($questionnaire) //fill to the end of the last page - $this->fillPageBackground(); + $this->fillLastPageBackground(); } /** * Draw the questionnaire info specified - * + * * @param string $text The text to draw in info style * @author Adam Zammit * @since 2011-12-21 @@ -1429,9 +1629,9 @@ public function create($questionnaire) protected function drawInfo($info) { $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->questionnaireInfoMargin, $this->getMainPageX(), $this->GetY() - $this->questionBorderBottom, "
",0,1,true,true); - $html = "
getMainPageWidth() . "mm\" class=\"questionnaireInfo\">{$info}
"; - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $this->questionnaireInfoMargin, $this->getColumnX(), $this->GetY() - $this->questionBorderBottom, "
",0,1,true,true); + $html = "
getColumnWidth() . "mm\" class=\"questionnaireInfo\">{$info}
"; + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); } /** @@ -1439,10 +1639,10 @@ protected function drawInfo($info) * * questions (title, text, specifier, helptext, helptextafter) * responses (varname) - * subquestions + * subquestions * subquestion(text, varname) * response (type, width, text, rotate) - * categories + * categories * category(text, value, skipto, other) * * @param array $question The questions portion of the array @@ -1461,10 +1661,10 @@ protected function createQuestion($question) //Leave a border at the top of the Help Before text if ($this->helpBeforeBorderTop > 0) //question border $this->SetY($this->GetY() + $this->helpBeforeBorderTop,false); //new line - + $this->setBackground('question'); - $html = "
getMainPageWidth() . "mm\" class=\"questionHelpBefore\">{$question['helptextbefore']}
"; - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $html = "
getColumnWidth() . "mm\" class=\"questionHelpBefore\">{$question['helptextbefore']}
"; + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); //Leave a border at the bottom of the Help Before text if ($this->helpBeforeBorderBottom > 0) //question border @@ -1472,7 +1672,6 @@ protected function createQuestion($question) } //Question header - if (isset($question['text'])) $question['text'] = FlattenText($question['text']); $this->drawQuestionHead($question['title'], $question['text'],$help,$specifier); $text = ""; @@ -1481,7 +1680,7 @@ protected function createQuestion($question) //Loop over response groups and produce questions of various types if (isset($question['responses'])) { foreach($question['responses'] as $r) { - $varname = $r['varname']; + $varname = $r['varname']; if (isset($r['subquestions'])) { @@ -1495,12 +1694,12 @@ protected function createQuestion($question) { case 'fixed': $categories = $response['categories']; - + if (isset($response['rotate'])) $this->drawSingleChoiceVertical($categories,$subquestions,$text); else $this->drawSingleChoiceHorizontal($categories,$subquestions,$text); - + break; case 'number': $bgtype = 4; @@ -1514,7 +1713,12 @@ protected function createQuestion($question) case 'vas': $this->drawMatrixVas($subquestions,$text,$response['labelleft'],$response['labelright']); break; - + case 'i25': + $this->drawMatrixBarcode($subquestions, 'I25'); + break; + case 'codabar': + $this->drawMatrixBarcode($subquestions, 'CODABAR'); + break; } } else @@ -1522,7 +1726,11 @@ protected function createQuestion($question) $response = $r['response']; $type = $response['type']; - if (isset($response['text']) && !empty($response['text'])) + $defaultvalue = false; + if (isset($r['defaultvalue'])) + $defaultvalue = $r['defaultvalue']; + + if (isset($response['text']) && !empty($response['text'])) $rtext = $text . $this->subQuestionTextSeparator . $response['text']; else $rtext = $text; @@ -1533,28 +1741,34 @@ protected function createQuestion($question) { case 'fixed': if (isset($response['rotate'])) - $this->drawSingleChoiceHorizontal($response['categories'],array(array('text' => '', 'varname' => $varname)),$rtext); + $this->drawSingleChoiceHorizontal($response['categories'],array(array('text' => '', 'varname' => $varname, 'defaultvalue' => $defaultvalue)),$rtext); else - $this->drawSingleChoiceVertical($response['categories'],array(array('text' => '', 'varname' => $varname)),$rtext); + $this->drawSingleChoiceVertical($response['categories'],array(array('text' => '', 'varname' => $varname, 'defaultvalue' => $defaultvalue)),$rtext); break; case 'longtext': $this->addBoxGroup(6,$varname,$rtext); - $this->drawLongText($response['width']); + $this->drawLongText($response['width'],$defaultvalue); break; case 'number': $bgtype = 4; case 'currency': case 'text': - $this->addBoxGroup($bgtype,$varname,$rtext,$response['width']); - $this->drawText($response['text'],$response['width']); + $this->addBoxGroup($bgtype,$varname,$rtext,$response['width']); + $this->drawText($response['text'],$response['width'],$defaultvalue); //Insert a gap here - $this->Rect($this->getMainPageX(),$this->GetY(),$this->getMainPageWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); + $this->Rect($this->getColumnX(),$this->GetY(),$this->getColumnWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); $this->SetY($this->GetY() + $this->subQuestionLineSpacing,false); break; case 'vas': $this->addBoxGroup(1,$varname,$rtext,strlen($this->vasIncrements)); $this->drawVas("",$response['labelleft'],$response['labelright']); break; + case 'i25': + $this->drawMatrixBarcode(array(array('text' => $rtext, 'varname' => $varname, 'defaultvalue' => $defaultvalue)),'I25'); + break; + case 'codabar': + $this->drawMatrixBarcode(array(array('text' => $rtext, 'varname' => $varname, 'defaultvalue' => $defaultvalue)),'CODABAR'); + break; } } @@ -1564,26 +1778,26 @@ protected function createQuestion($question) if (isset($question['helptextafter'])) { $this->setBackground('question'); - $html = "
getMainPageWidth() . "mm\" class=\"questionHelpAfter\">{$question['helptextafter']}
"; - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $html = "
getColumnWidth() . "mm\" class=\"questionHelpAfter\">{$question['helptextafter']}
"; + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); } - //Leave a border at the bottom of the question + //Leave a border at the bottom of the question if ($this->questionBorderBottom > 0) //question border $this->SetY($this->GetY() + $this->questionBorderBottom,false); //new line } - + /** * Draw text responses line by line - * + * * @param array $subquestions The subquestions containing text and varname * @param int $width The width of the text element * @param string|bool $parenttext The question text of the parent or false if not specified * @param int $bgtype The box group type (default is 3 - text) - * + * * @author Adam Zammit * @since 2010-09-02 */ @@ -1596,37 +1810,84 @@ protected function drawMatrixTextVertical($subquestions,$width,$parenttext = fal if ($parenttext == false) $this->addBoxGroup($bgtype,$s['varname'],$s['text'],$width); - else + else $this->addBoxGroup($bgtype,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text'],$width); + $defaultvalue = false; + if (isset($s['defaultvalue'])) + $defaultvalue = $s['defaultvalue']; + + $this->drawText($s['text'],$width,$defaultvalue); + + $currentY = $this->GetY(); + + //Insert a gap here + $this->Rect($this->getColumnX(),$this->GetY(),$this->getColumnWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); + $this->SetY($currentY + $this->subQuestionLineSpacing,false); + $heading=false; + } + } + + + /** + * Draw a barcode as a "question" + * + * @param string $subquestions + * @param mixed $type + * + * @author Adam Zammit + * @since 2012-06-22 + */ + protected function drawMatrixBarcode($subquestions, $type) + { + $c = count($subquestions); + for ($i = 0; $i < $c; $i++) + { + $s = $subquestions[$i]; - $this->drawText($s['text'],$width); + $this->addBoxGroup(5,$s['varname'],$s['text'],strlen($s['defaultvalue'])); - $currentY = $this->GetY(); + $x = $this->getColumnX(); + $y = $this->GetY(); + $html = "
"; + $this->setBackground('question'); + $this->writeHTMLCell($this->getColumnWidth(), $this->barcodeResponseHeight, $this->getColumnX(), $this->GetY() , $this->style . $html,0,1,true,false); + + //draw the barcode + $barcodeStyle = array('align' => 'R', 'border' => false, 'padding' => '0', 'bgcolor' => $this->backgroundColourQuestion, 'text' => false, 'stretch' => false); + $this->write1DBarcode($s['defaultvalue'], $type, $x, $y, $this->getColumnWidth() - $this->skipColumnWidth,$this->barcodeResponseHeight,'', $barcodeStyle, 'B'); + + //pointer should now be at the bottom right - but make the box the width of the whole column for better reading + $this->addBox($x,$y,$this->GetX(),$this->getColumnWidth() + $this->getColumnX()); + + $currentY = $this->GetY(); + //Insert a gap here - $this->Rect($this->getMainPageX(),$this->GetY(),$this->getMainPageWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); + $this->Rect($this->getColumnX(),$this->GetY(),$this->getColumnWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); $this->SetY($currentY + $this->subQuestionLineSpacing,false); + } + } /** * Draw multiple VAS items - * + * * @param array $subquestions The subquestions containing text and varname * @param string|bool $parenttext The question text of the parent or false if not specified * @param string $labelleft The left hand side label * @param string $labelright The right hand side label - * + * * @author Adam Zammit * @since 2010-09-20 */ protected function drawMatrixVas($subquestions,$parenttext = false,$labelleft,$labelright) { $c = count($subquestions); - - $width = strlen($this->vasIncrements); + + $width = strlen($this->vasIncrements); $heading = true; for ($i = 0; $i < $c; $i++) @@ -1635,51 +1896,60 @@ protected function drawMatrixVas($subquestions,$parenttext = false,$labelleft,$l if ($parenttext == false) $this->addBoxGroup(1,$s['varname'],$s['text'],$width); - else + else $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text'],$width); $this->drawVas($s['text'],$labelleft,$labelright,$heading); - + $currentY = $this->GetY(); - + //Insert a gap here - $this->Rect($this->getMainPageX(),$this->GetY(),$this->getMainPageWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); + $this->Rect($this->getColumnX(),$this->GetY(),$this->getColumnWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); $this->SetY($currentY + $this->subQuestionLineSpacing,false); - + $heading = false; } - + } /** * Draw a large empty box for writing in text - * + * * @param mixed $width The "width" of the box. This relates to the number of "lines" high - * + * @param bool|string $defaultvalue The default text to print in the box (if any) + * * @author Adam Zammit * @since 2010-09-02 */ - protected function drawLongText($width) + protected function drawLongText($width,$defaultvalue = false) { + //Calculate long text box width as the width of the available column minus the skip column and question title area + $rwidth = $this->getColumnWidth() - $this->skipColumnWidth - $this->questionTitleWidth; + $currentY = $this->GetY(); $height = $width * $this->longTextResponseHeightMultiplier; $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $height, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $height, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); $this->SetY($currentY,false); $this->setBackground('empty'); $border = array('LTRB' => array('width' => $this->textResponseBorder, 'dash' => 0)); //Align to skip column on right - $this->SetX(($this->getPageWidth() - $this->getMainPageX() - $this->skipColumnWidth - $this->longTextResponseWidth),false); + $this->SetX((($this->getColumnWidth() + $this->getColumnX()) - $this->skipColumnWidth - $rwidth),false); //Add to pay layout - $this->addBox($this->GetX(),$this->GetY(),$this->GetX() + $this->longTextResponseWidth, $this->GetY() + $height); + $this->addBox($this->GetX(),$this->GetY(),$this->GetX() + $rwidth, $this->GetY() + $height); $this->SetDrawColor($this->lineColour[0]); - $this->Cell($this->longTextResponseWidth,$height,'',$border,0,'',true,'',0,false,'T','C'); + + $text = ""; + if ($defaultvalue !== false) + $text = $defaultvalue; + + $this->Cell($rwidth,$height,$text,$border,0,'',true,'',0,false,'T','T'); $currentY = $currentY + $height; $this->SetY($currentY,false); } @@ -1687,18 +1957,18 @@ protected function drawLongText($width) /** * Draw a VAS - * + * * @param string $text The text of this item * @param string $labelleft The left hand side label * @param string $labelright The right hand side label * @param bool $heading Whether to draw a heading or not - * + * * @author Adam Zammit * @since 2010-09-20 */ protected function drawVas($text, $labelleft,$labelright,$heading = true) { - $textwidth = $this->getMainPageWidth() - $this->skipColumnWidth - ($this->vasLength + ($this->vasLineWidth * 2.0)) - 2; + $textwidth = $this->getColumnWidth() - $this->skipColumnWidth - ($this->vasLength + ($this->vasLineWidth * 2.0)) - 2; $this->setBackground('question'); if ($heading) @@ -1707,49 +1977,49 @@ protected function drawVas($text, $labelleft,$labelright,$heading = true) $lwidth = 20; $slwidth = $textwidth - ($lwidth / 2); $gapwidth = ($this->vasLength + ($this->vasLineWidth * 2.0)) - $lwidth; - - + + $html = "
$labelleft$labelright
"; - - - $this->writeHTMLCell($this->getMainPageWidth(), 0, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,false); + + + $this->writeHTMLCell($this->getColumnWidth(), 0, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,false); } $currentY = $this->GetY(); $html = "
$text
"; - + $textwidth += 2; - $this->writeHTMLCell($this->getMainPageWidth(), $this->vasAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,false); + $this->writeHTMLCell($this->getColumnWidth(), $this->vasAreaHeight, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,false); $ncurrentY = $this->GetY(); $this->SetY($currentY,false); - $this->SetX($textwidth + $this->getMainPageX(),false); - + $this->SetX($textwidth + $this->getColumnX(),false); + $this->SetLineWidth($this->vasLineWidth); $this->SetDrawColor($this->lineColour[0]); - + //Draw the VAS left vert line - $ly = (($this->vasAreaHeight - $this->vasHeight) / 2.0) + $currentY; - $lx = $textwidth + $this->getMainPageX(); + $ly = (($this->vasAreaHeight - $this->vasHeight) / 2.0) + $currentY; + $lx = $textwidth + $this->getColumnX(); $this->Line($lx,$ly,$lx,$ly + $this->vasHeight); - + //Right vert line - $lx = $textwidth + $this->getMainPageX() + $this->vasLength + $this->vasLineWidth; + $lx = $textwidth + $this->getColumnX() + $this->vasLength + $this->vasLineWidth; $this->Line($lx,$ly,$lx,$ly + $this->vasHeight); - + //Line itself $ly = ($this->vasAreaHeight / 2.0) + $currentY; - $lx = $textwidth + $this->getMainPageX() + ($this->vasLineWidth / 2.0); + $lx = $textwidth + $this->getColumnX() + ($this->vasLineWidth / 2.0); $this->Line($lx,$ly,$lx + $this->vasLength,$ly); //Add to layout system $bw = ($this->vasLength / $this->vasIncrements); - $ly = (($this->vasAreaHeight - $this->vasHeight) / 2.0) + $currentY; + $ly = (($this->vasAreaHeight - $this->vasHeight) / 2.0) + $currentY; for ($i = 0; $i < $this->vasIncrements; $i++) { $this->addBox($lx,$ly,$lx + $bw,$ly + $this->vasHeight, $i + 1, $i + 1); @@ -1758,21 +2028,22 @@ protected function drawVas($text, $labelleft,$labelright,$heading = true) //Go back to the right Y position $this->SetY($ncurrentY,false); - } + } /** * Draw a text response * * @param string $text The text label if any (can be HTML) * @param int $width The number of boxes to draw + * @param bool|string $defaultvalue The default text to include or false if none */ - protected function drawText($text,$width) + protected function drawText($text,$width,$defaultvalue = false) { $this->SetDrawColor($this->lineColour[0]); //calculate text responses per line - $textResponsesPerLine = round(($this->getMainPageWidth() - $this->skipColumnWidth - $this->textResponseMarginX) / ($this->textResponseWidth + $this->textResponseBorder)); - $labelTextResponsesSameLine = round(($this->getMainPageWidth() - $this->skipColumnWidth - $this->labelTextResponsesSameLineMarginX) / ($this->textResponseWidth + $this->textResponseBorder)); + $textResponsesPerLine = round(($this->getColumnWidth() - $this->skipColumnWidth - $this->textResponseMarginX) / ($this->textResponseWidth + $this->textResponseBorder)); + $labelTextResponsesSameLine = round(($this->getColumnWidth() - $this->skipColumnWidth - $this->labelTextResponsesSameLineMarginX) / ($this->textResponseWidth + $this->textResponseBorder)); //draw boxes - can draw up to $textResponsesPerLine for each line $lines = ceil($width / $textResponsesPerLine); @@ -1781,83 +2052,93 @@ protected function drawText($text,$width) if ($width > $labelTextResponsesSameLine && !empty($text)) { $this->setBackground('question'); - $html = "
questionTitleWidth}mm\">getMainPageWidth() - $this->skipColumnWidth - $this->questionTitleWidth) . "mm\" class=\"responseAboveText\">$text
"; - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $html = "
questionTitleWidth}mm\">getColumnWidth() - $this->skipColumnWidth - $this->questionTitleWidth) . "mm\" class=\"responseAboveText\">$text
"; + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); } $currentY = $this->GetY(); + $startstring = 0; + for ($i = 0; $i < $lines; $i++) { if ($lines == 1) $cells = $width; //one line only else if (($i + 1 == $lines)) $cells = ($width - ($textResponsesPerLine * $i)); //last line else $cells = $textResponsesPerLine; //middle line + //add another box group if moving on to another line if ($i >= 1) $this->addBoxGroupCopyPrevious(); - $textwidth = ($this->getMainPageWidth() - $this->skipColumnWidth) - (($this->textResponseWidth + $this->textResponseBorder ) * $cells); + $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - (($this->textResponseWidth + $this->textResponseBorder ) * $cells); //print "textwidth: $textwidth cells: $cells mainpagex: " . $this->getMainPageX() . "
"; //First draw a background of height $this->responseLabelHeight $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->textResponseHeight, $this->getMainPageX(), $this->GetY() , $this->style . $html,0,1,true,false); + $this->writeHTMLCell($this->getColumnWidth(), $this->textResponseHeight, $this->getColumnX(), $this->GetY() , $this->style . $html,0,1,true,false); if ($lines == 1 && $cells <= $labelTextResponsesSameLine && !empty($text)) { - $this->setDefaultFont($this->responseTextFontSize); + $this->setDefaultFont($this->responseTextFontSize); - $this->MultiCell($textwidth,$this->textResponseHeight,$text,0,'R',false,1,$this->getMainPageX(),$currentY,true,0,false,true,$this->textResponseHeight,'M',true); + $this->MultiCell($textwidth,$this->textResponseHeight,$text,0,'R',false,1,$this->getColumnX(),$currentY,true,0,false,true,$this->textResponseHeight,'M',true); //$html = "
$text
"; } - + $ncurrentY = $this->GetY(); $this->SetY($currentY,false); - $this->SetX($textwidth + $this->getMainPageX() + 2,false); //set the X position to the first cell + $this->SetX($textwidth + $this->getColumnX() + 2,false); //set the X position to the first cell + + $string = false; + if ($defaultvalue !== false) + $string = substr($defaultvalue,$startstring,$cells); + + $this->drawCells($cells,$string); - $this->drawCells($cells); + $startstring += $cells; $currentY = $ncurrentY; //New line $this->SetY($currentY,false); //new line - + if (!(($i + 1) == $lines) && $this->textResponseLineSpacing > 0) //if there should be a gap between text responses and not the last { - $this->SetX($this->getMainPageX(),false); + $this->SetX($this->getColumnX(),false); $this->setBackground('question'); - $this->Cell($this->getMainPageWidth(),$this->textResponseLineSpacing,'','',0,'',true,'',0,false,'T','C'); + $this->Cell($this->getColumnWidth(),$this->textResponseLineSpacing,'','',0,'',true,'',0,false,'T','C'); $currentY += $this->textResponseLineSpacing; $this->SetY($currentY,false); //new line } - + } - + } /** * Draw X number of cells at the current X Y position - * + * * @param int $cells The number of text cells to draw - * + * @param string $string A string to draw if set + * * @author Adam Zammit * @since 2010-09-08 */ - protected function drawCells($cells) + protected function drawCells($cells, $string) { $this->setBackground('empty'); $this->SetDrawColor($this->lineColour[0]); for ($j = 0; $j < $cells; $j++) { - //draw text cells + //draw text cells if ($cells == 1) //only $border = array('LTR' => array('width' => $this->textResponseBorder, 'dash' => 0), 'B' => array('width' => ($this->textResponseBorder * 2), 'dash' => 0)); else if ($j == 0) //first @@ -1879,9 +2160,13 @@ protected function drawCells($cells) //Add the box to the layout scheme $this->addBox($this->GetX(),$this->GetY(),$this->GetX() + $this->textResponseWidth,$this->GetY() + $this->textResponseHeight); - //Draw the box - $this->Cell($this->textResponseWidth,$this->textResponseHeight,'',$border,0,'',true,'',0,false,'T','C'); + $text = ''; + if (isset($string[$j])) + $text = $string[$j]; + //Draw the box + $this->Cell($this->textResponseWidth,$this->textResponseHeight,$text,$border,0,'',true,'',0,false,'T','C'); + } //add some spacing for the bottom border @@ -1890,7 +2175,7 @@ protected function drawCells($cells) /** * Draw a horizontal table of text boxes - * + * * @param array $subquestions The subquestions * @param int $width The width * @param string|bool $parenttext The question text of the parent or false if not specified @@ -1904,9 +2189,9 @@ protected function drawMatrixTextHorizontal($subquestions,$width,$parenttext = f $total = count($subquestions); $currentY = $this->GetY(); - $rwidth = ($width * ($this->textResponseWidth + $this->textResponseBorder + $this->textResponseLineSpacing)); + $rwidth = ($width * ($this->textResponseWidth + $this->textResponseBorder + $this->textResponseLineSpacing)); - $textwidth = ($this->getMainPageWidth() - $this->skipColumnWidth) - ($rwidth * $total); + $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - ($rwidth * $total); $html = ""; foreach ($subquestions as $r) @@ -1914,18 +2199,18 @@ protected function drawMatrixTextHorizontal($subquestions,$width,$parenttext = f $html .= ""; } $html .= "
{$r['text']}
"; - $this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseAreaHeight, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); $currentY = $this->GetY(); $html = "
"; - $this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseAreaHeight, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); $ncurrentY = $this->GetY(); - $this->SetY($currentY,false); + $this->SetY($currentY,false); //Set X position - $this->SetX($this->getMainPageX() + $textwidth,false); + $this->SetX($this->getColumnX() + $textwidth,false); foreach ($subquestions as $s) @@ -1933,135 +2218,186 @@ protected function drawMatrixTextHorizontal($subquestions,$width,$parenttext = f //Add box group to current layout if ($parenttext == false) $this->addBoxGroup($bgtype,$s['varname'],$s['text']); - else + else $this->addBoxGroup($bgtype,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); - + $string = false; + if (isset($s['defaultvalue'])) + $string = substr($defaultvalue,0,$width); //Draw the cells - $this->drawCells($width); + $this->drawCells($width,$string); //Move X for a gap $this->SetX($this->GetX() + $this->textResponseLineSpacing,false); - $this->SetY($currentY,false); + $this->SetY($currentY,false); } //Move cursor back to the right spot $this->SetY($ncurrentY,false); } + /** - * Draw a horizontal table of respones including "eye guides" - * + * Draw the head of a single choice horizontal table of responses + * * @param array $categories The response categories - * @param array $subquestions The subquestions if any - * @param string|bool $parenttext The question text of the parent or false if not specified - * + * * @author Adam Zammit - * @since 2010-09-08 + * @since 2012-06-05 */ - protected function drawSingleChoiceHorizontal($categories, $subquestions = array(array('text' => '')),$parenttext = false) + protected function drawSingleChoiceHorizontalHead($categories) { $total = count($categories); $currentY = $this->GetY(); if ($total > $this->singleResponseHorizontalMax) //change if too many cats $rwidth = $this->singleResponseVerticalAreaWidthSmall; - else + else $rwidth = $this->singleResponseVerticalAreaWidth; - $textwidth = ($this->getMainPageWidth() - $this->skipColumnWidth) - ($rwidth * $total); + $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - ($rwidth * $total); //First draw a background of height $this->responseLabelHeight $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->responseLabelHeight, $this->getMainPageX(), $currentY , $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $this->responseLabelHeight, $this->getColumnX(), $currentY , $this->style . $html,0,1,true,true); - $this->setDefaultFont($this->responseLabelFontSize); + $this->setDefaultFont($this->responseLabelFontSize); $count = 0; - //Draw a Cell for each rwidth from $textwidth + $this->getMainPageX(),currentY + //Draw a Cell for each rwidth from $textwidth + $this->getColumnX(),currentY foreach ($categories as $r) { $y = $currentY; - $x = ($textwidth + $this->getMainPageX() + ($rwidth * $count)); - + $x = ($textwidth + $this->getColumnX() + ($rwidth * $count)); + // Going to break the line because of long word if ($this->wordLength($r['text']) > $this->responseLabelSmallWordLength) - $this->setDefaultFont($this->responseLabelFontSizeSmall); + $this->setDefaultFont($this->responseLabelFontSizeSmall); $this->MultiCell($rwidth,$this->responseLabelHeight,$r['text'],0,'C',false,0,$x,$y,true,0,false,true,$this->responseLabelHeight,'B',true); //reset font if ($this->wordLength($r['text']) > $this->responseLabelSmallWordLength) - $this->setDefaultFont($this->responseLabelFontSize); + $this->setDefaultFont($this->responseLabelFontSize); $count++; } - $currentY += $this->responseLabelHeight; - - //reset font size - - - foreach ($subquestions as $s) - { - //Add box group to current layout - if ($parenttext == false) - $this->addBoxGroup(1,$s['varname'],$s['text']); - else - $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); - - //$html = "
" . $s['text'] . "
"; - //$this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + } - //Draw background - $html = "
"; - $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseHorizontalHeight, $this->getMainPageX(), $currentY, $this->style . $html,0,1,true,true); - $this->setDefaultFont($this->responseTextFontSize); + /** + * Draw a horizontal table of respones including "eye guides" + * + * @param array $categories The response categories + * @param array $subquestions The subquestions if any + * @param string|bool $parenttext The question text of the parent or false if not specified + * + * @author Adam Zammit + * @since 2010-09-08 + */ + protected function drawSingleChoiceHorizontal($categories, $subquestions = array(array('text' => '')),$parenttext = false) + { + $total = count($categories); + $currentY = $this->GetY(); - $this->MultiCell($textwidth,$this->singleResponseHorizontalHeight,$s['text'],0,'R',false,0,$this->getMainPageX(),$currentY,true,0,false,true,$this->singleResponseHorizontalHeight,'M',true); + if ($total > $this->singleResponseHorizontalMax) //change if too many cats + $rwidth = $this->singleResponseVerticalAreaWidthSmall; + else + $rwidth = $this->singleResponseVerticalAreaWidth; + $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - ($rwidth * $total); + //draw the header + $this->drawSingleChoiceHorizontalHead($categories); + $currentY += $this->responseLabelHeight; + if ($this->allowSplittingSingleChoiceHorizontal) $this->startTransaction(); //start a transaction + for ($i = 0; $i < count($subquestions); $i++) + { + $s = $subquestions[$i]; - //Draw the categories horizontally - $rnum = 1; - foreach ($categories as $r) + if ($this->allowSplittingSingleChoiceHorizontal && $this->pageBreakOccured) { - if ($total == 1) $num = 'only'; - else if ($rnum == 1) $num = 'first'; - else if ($rnum < $total) $num = 'middle'; - else if ($rnum == $total) $num = 'last'; - - $position = $this->drawHorizontalResponseBox(($this->getMainPageX() + $textwidth + (($rnum - 1) * $rwidth)),$currentY, $num,false,false,($total > $this->singleResponseHorizontalMax)); - - //Add box to the current layout - $this->addBox($position[0],$position[1],$position[2],$position[3],$r['value'],$r['text']); - - $rnum++; + $this->pageBreakOccured = false; + $this->rollBackTransaction(true); + $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break + $this->fillPageBackground(); + $this->newPage(); + $this->drawSingleChoiceHorizontalHead($categories); + + //reset currentY + $currentY = $this->GetY() + $this->responseLabelHeight; + + $i = $i - 2; //go back and draw subquestions on the new page } - - if (($this->GetY() - $currentY) > $this->singleResponseHorizontalHeight) - $currentY = $this->GetY(); else - $currentY = $currentY + $this->singleResponseHorizontalHeight; - - $this->SetY($currentY,false); - + { + if ($this->allowSplittingSingleChoiceHorizontal) + { + $this->commitTransaction(); + $this->startTransaction(); //start a transaction to allow for splitting over pages if necessary + } + + //Add box group to current layout + if ($parenttext == false) + $this->addBoxGroup(1,$s['varname'],$s['text']); + else + $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); + + //$html = "
" . $s['text'] . "
"; + //$this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + + //Draw background + $html = "
"; + $this->setBackground('question'); + $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseHorizontalHeight, $this->getColumnX(), $currentY, $this->style . $html,0,1,true,true); + $this->setDefaultFont($this->responseTextFontSize); + + $this->MultiCell($textwidth,$this->singleResponseHorizontalHeight,$s['text'],0,'R',false,0,$this->getColumnX(),$currentY,true,0,false,true,$this->singleResponseHorizontalHeight,'M',true); + + + //Draw the categories horizontally + $rnum = 1; + foreach ($categories as $r) + { + if ($total == 1) $num = 'only'; + else if ($rnum == 1) $num = 'first'; + else if ($rnum < $total) $num = 'middle'; + else if ($rnum == $total) $num = 'last'; + + $bfilled = false; + if (isset($s['defaultvalue']) && $s['defaultvalue'] !== false && $s['defaultvalue'] == $r['value']) + $bfilled = true; + + $position = $this->drawHorizontalResponseBox(($this->getColumnX() + $textwidth + (($rnum - 1) * $rwidth)),$currentY, $num,false,false,($total > $this->singleResponseHorizontalMax),$bfilled); + + //Add box to the current layout + $this->addBox($position[0],$position[1],$position[2],$position[3],$r['value'],$r['text']); + + $rnum++; + } + + if (($this->GetY() - $currentY) > $this->singleResponseHorizontalHeight) + $currentY = $this->GetY(); + else + $currentY = $currentY + $this->singleResponseHorizontalHeight; + + $this->SetY($currentY,false); + + } } - } /** * Draw a vertical table of single choice responses including "eye guides" - * + * * @param array $categories An array containing the category text, value, skipto and other * @param array $subquestions An array containing the subquestions if any * @param string|bool $parenttext The question text of the parent or false if not specified - * + * * @author Adam Zammit * @since 2010-09-02 */ @@ -2072,7 +2408,7 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a $rwidth = $this->singleResponseVerticalAreaWidth; - $textwidth = ($this->getMainPageWidth() - $this->skipColumnWidth) - ($rwidth * $total); + $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - ($rwidth * $total); if (count($categories) > 1) { @@ -2082,25 +2418,25 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a //First draw a background of height $this->responseLabelHeight $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->responseLabelHeight, $this->getMainPageX(), $currentY , $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $this->responseLabelHeight, $this->getColumnX(), $currentY , $this->style . $html,0,1,true,true); - $this->setDefaultFont($this->responseLabelFontSize); + $this->setDefaultFont($this->responseLabelFontSize); - //Draw a Cell for each rwidth from $textwidth + $this->getMainPageX(),currentY + //Draw a Cell for each rwidth from $textwidth + $this->getColumnX(),currentY foreach ($subquestions as $r) { $y = $currentY; - $x = ($textwidth + $this->getMainPageX() + ($rwidth * $count)); + $x = ($textwidth + $this->getColumnX() + ($rwidth * $count)); // Going to break the line because of long word if ($this->wordLength($r['text']) > $this->responseLabelSmallWordLength) - $this->setDefaultFont($this->responseLabelFontSizeSmall); + $this->setDefaultFont($this->responseLabelFontSizeSmall); $this->MultiCell($rwidth,$this->responseLabelHeight,$r['text'],0,'C',false,0,$x,$y,true,0,false,true,$this->responseLabelHeight,'B',true); if ($this->wordLength($r['text']) > $this->responseLabelSmallWordLength) - $this->setDefaultFont($this->responseLabelFontSize); - + $this->setDefaultFont($this->responseLabelFontSize); + if (!empty($r['text'])) $isempty = false; $count++; } @@ -2125,13 +2461,13 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a $this->SetY($firstY, false); $currentY = $firstY; - + if ($parenttext == false) $this->addBoxGroup(1,$s['varname'],$s['text']); else $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); - $x = $this->getMainPageX() + $textwidth + ($rwidth * $snum) + ((($rwidth - $this->singleResponseBoxWidth) / 2.0 )); + $x = $this->getColumnX() + $textwidth + ($rwidth * $snum) + ((($rwidth - $this->singleResponseBoxWidth) / 2.0 )); $other = false; @@ -2149,10 +2485,10 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a //Draw background $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); - $this->setDefaultFont($this->responseTextFontSize); + $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseAreaHeight, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->setDefaultFont($this->responseTextFontSize); - $this->MultiCell($textwidth,$this->singleResponseAreaHeight,$r['text'],0,'R',false,0,$this->getMainPageX(),$currentY,true,0,false,true,$this->singleResponseAreaHeight,'M',true); + $this->MultiCell($textwidth,$this->singleResponseAreaHeight,$r['text'],0,'R',false,0,$this->getColumnX(),$currentY,true,0,false,true,$this->singleResponseAreaHeight,'M',true); } @@ -2162,8 +2498,12 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a if (isset($r['skipto'])) $skipto = $r['skipto']; if (isset($r['other']) && $rnum == $total) $other = $r['other']; //only set for last in set + $bfilled = false; + if (isset($s['defaultvalue']) && $s['defaultvalue'] !== false && $s['defaultvalue'] == $r['value']) + $bfilled = true; + //Draw the box over the top - $position = $this->drawVerticalResponseBox($x,$currentY, $num, $other, $skipto); + $position = $this->drawVerticalResponseBox($x,$currentY, $num, $other, $skipto, $bfilled); //Add box to the current layout $this->addBox($position[0],$position[1],$position[2],$position[3],$r['value'],$r['text']); @@ -2175,12 +2515,12 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a $currentY = $this->GetY(); else $currentY = $currentY + $this->singleResponseAreaHeight; - + $ypos[$rnum] = $currentY; } else $currentY = $ypos[$rnum]; - + $this->SetY($currentY,false); $rnum++; @@ -2189,10 +2529,15 @@ protected function drawSingleChoiceVertical($categories, $subquestions = array(a if ($other !== false) { //Display the "other" variable - $this->addBoxGroup(3,$other['varname'],$other['text'],$other['width']); - $this->drawText($other['text'],$other['width']); + $this->addBoxGroup(3,$other['varname'],$other['text'],$other['width']); + + $defaultvalue = false; + if (isset($other['defaultvalue']) && $other['defaultvalue'] !== false) + $defaultvalue = $other['defaultvalue']; + + $this->drawText($other['text'],$other['width'],$defaultvalue); //Insert a gap here - $this->Rect($this->getMainPageX(),$this->GetY(),$this->getMainPageWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); + $this->Rect($this->getColumnX(),$this->GetY(),$this->getColumnWidth(),$this->subQuestionLineSpacing,'F',array(),$this->backgroundColourQuestion); $this->SetY($this->GetY() + $this->subQuestionLineSpacing,false); } @@ -2212,28 +2557,29 @@ protected function drawQuestionHead($title,$text,$help = false,$specifier = fals { $this->setBackground('question'); //Cell for question number (title) and text including a white border at the bottom - + $class = "questionTitle"; //If there is a skip to this question, make the question title bigger if (isset($this->skipToRegistry[$title])) $class = "questionTitleSkipTo"; - $html = ""; + $html = "
questionTitleWidth . "mm\">$titlegetMainPageWidth() - $this->questionTextRightMargin - $this->questionTitleWidth) . "mm\">$text
"; if ($specifier !== false) { - $html .= ""; + $html .= ""; } $html .= "
questionTitleWidth . "mm\">$titlegetColumnWidth() - $this->questionTextRightMargin - $this->questionTitleWidth) . "mm\">$text
questionTitleWidth . "mm\"> getMainPageWidth() - $this->questionTextRightMargin - $this->questionTitleWidth) . "mm\">$specifier
questionTitleWidth . "mm\"> getColumnWidth() - $this->questionTextRightMargin - $this->questionTitleWidth) . "mm\">$specifier
"; + - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); if ($help != false) { - $html = "
getMainPageWidth() - $this->skipColumnWidth) . "mm\" class=\"questionHelp\">$help
"; - $this->writeHTMLCell($this->getMainPageWidth(), 1, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + $html = "
getColumnWidth() - $this->skipColumnWidth) . "mm\" class=\"questionHelp\">$help
"; + $this->writeHTMLCell($this->getColumnWidth(), 1, $this->getColumnX(), $this->GetY(), $this->style . $html,0,1,true,true); } } @@ -2260,7 +2606,7 @@ protected function addSection($desc = 'queXMLPDF Section',$title = false,$info = $html .= "
$info
"; $this->setBackground('section'); - $this->writeHTMLCell($this->getPageWidth() - (($this->cornerBorder *2) + ($this->cornerWidth * 2)),$this->sectionHeight,$this->getMainPageX(),$this->getY(),$this->style . $html,array('B' => array('width' => 1, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->backgroundColourEmpty)),1,true,true,''); + $this->writeHTMLCell($this->getColumnWidth(),$this->sectionHeight,$this->getColumnX(),$this->getY(),$this->style . $html,array('B' => array('width' => 1, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->backgroundColourEmpty)),1,true,true,''); $this->setBackground('empty'); } @@ -2275,93 +2621,118 @@ public function mm2px($mm) return round($mm * ($this->ppi / self::INCH_IN_MM)); } + /** + * Make sure to fill the remaining columns on the last page + * + * @author Adam Zammit + * @since 2012-05-31 + */ + protected function fillLastPageBackground() + { + while ($this->columnCP < $this->columns) + { + $this->fillPageBackground(); + $this->SetXY($this->getColumnX(),($this->cornerBorder + $this->cornerWidth)); + $this->columnCP++; + } + } + /** * Draw the background from the current Y position to the bottom of the page - * - * @param bool $last Optional, defaults to false. If this is the last page - * + * * @author Adam Zammit * @since 2010-09-15 */ - protected function fillPageBackground($last = false) + protected function fillPageBackground() { $height = $this->getPageHeight() - $this->cornerBorder - $this->GetY() + $this->questionBorderBottom; $html = "
"; $this->setBackground('question'); - $this->writeHTMLCell($this->getMainPageWidth(), $height, $this->getMainPageX(), $this->GetY() - $this->questionBorderBottom, $this->style . $html,0,1,true,true); + $this->writeHTMLCell($this->getColumnWidth(), $height, $this->getColumnX(), $this->GetY() - $this->questionBorderBottom, $this->style . $html,0,1,true,true); } /** * Create a new queXML PDF page * * Draw the barcode and page corners - * + * */ - protected function newPage() + protected function newPage($init = false) { - $this->AddPage(); - - //Set Auto page break to false - $this->SetAutoPageBreak(false); - - $this->SetMargins(0,0,0); - $this->SetHeaderMargin(0); - $this->SetFooterMargin(0); + $this->columnCP++; //increment the column pointer - //Shortcuts to make the code (a bit) nicer - $width = $this->getPageWidth(); - $height = $this->getPageHeight(); - $cb = $this->cornerBorder; - $cl = $this->cornerLength; - - $this->SetDrawColor($this->lineColour[0]); + if ($init || ($this->columnCP >= $this->columns)) // if it is time for a new page + { + $this->AddPage(); + + //Set Auto page break to false + $this->SetAutoPageBreak(false); + + $this->SetMargins(0,0,0); + $this->SetHeaderMargin(0); + $this->SetFooterMargin(0); + + //Shortcuts to make the code (a bit) nicer + $width = $this->getPageWidth(); + $height = $this->getPageHeight(); + $cb = $this->cornerBorder; + $cl = $this->cornerLength; + + $this->SetDrawColor($this->lineColour[0]); + + $barcodeStyle = array('border' => false, 'padding' => '0', 'bgcolor' => false, 'text' => false, 'stretch' => true); + $lineStyle = array('width' => $this->cornerWidth, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)); + + //Top left + $this->Line($cb,$cb,$cb + $cl,$cb,$lineStyle); + $this->Line($cb,$cb,$cb,$cb + $cl,$lineStyle); + + //Top right + $this->Line($width - $cb,$cb,$width - $cb - $cl,$cb,$lineStyle); + $this->Line($width - $cb,$cb,$width - $cb,$cb + $cl,$lineStyle); + + //Bottom left + $this->Line($cb,$height - $cb,$cb + $cl,$height - $cb,$lineStyle); + $this->Line($cb,$height - $cb,$cb,$height - ($cb + $cl),$lineStyle); + + //Bottom right + $this->Line($width - $cb,$height - $cb,$width - $cb - $cl,$height - $cb,$lineStyle); + $this->Line($width - $cb,$height - $cb,$width - $cb,$height - ($cb + $cl),$lineStyle); + + $barcodeValue = substr(str_pad($this->questionnaireId,$this->idLength,"0",STR_PAD_LEFT),0,$this->idLength) . substr(str_pad($this->getPage(),$this->pageLength,"0",STR_PAD_LEFT),0,$this->pageLength); + + //Calc X position of barcode from page width + $barcodeX = $width - ($this->barcodeMarginX + $this->barcodeW); + + $this->write1DBarcode($barcodeValue, $this->barcodeType, $barcodeX, $this->barcodeY, $this->barcodeW, $this->barcodeH,'', $barcodeStyle, 'N'); + + //Add this page to the layout system + $b = $this->cornerBorder + ($this->cornerWidth / 2.0); //temp calc for middle of line + $this->layout[$barcodeValue] = array( 'id' => $barcodeValue, + 'tlx' => $this->mm2px($b), + 'tly' => $this->mm2px($b), + 'trx' => $this->mm2px($width - $b), + 'try' => $this->mm2px($b), + 'brx' => $this->mm2px($width - $b), + 'bry' => $this->mm2px($height - $b), + 'blx' => $this->mm2px($b), + 'bly' => $this->mm2px($height - $b), + 'rotation' => 0, + 'boxgroup' => array() + ); + $this->layoutCP = $barcodeValue; + + $this->SetXY($cb + $this->cornerWidth, $cb + $this->cornerWidth); + + $this->setBackground('empty'); - $barcodeStyle = array('border' => false, 'padding' => '0', 'bgcolor' => false, 'text' => false, 'stretch' => true); - $lineStyle = array('width' => $this->cornerWidth, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)); - - //Top left - $this->Line($cb,$cb,$cb + $cl,$cb,$lineStyle); - $this->Line($cb,$cb,$cb,$cb + $cl,$lineStyle); - - //Top right - $this->Line($width - $cb,$cb,$width - $cb - $cl,$cb,$lineStyle); - $this->Line($width - $cb,$cb,$width - $cb,$cb + $cl,$lineStyle); - - //Bottom left - $this->Line($cb,$height - $cb,$cb + $cl,$height - $cb,$lineStyle); - $this->Line($cb,$height - $cb,$cb,$height - ($cb + $cl),$lineStyle); - - //Bottom right - $this->Line($width - $cb,$height - $cb,$width - $cb - $cl,$height - $cb,$lineStyle); - $this->Line($width - $cb,$height - $cb,$width - $cb,$height - ($cb + $cl),$lineStyle); - - $barcodeValue = substr(str_pad($this->questionnaireId,$this->idLength,"0",STR_PAD_LEFT),0,$this->idLength) . substr(str_pad($this->getPage(),$this->pageLength,"0",STR_PAD_LEFT),0,$this->pageLength); - - //Calc X position of barcode from page width - $barcodeX = $width - ($this->barcodeMarginX + $this->barcodeW); - - $this->write1DBarcode($barcodeValue, $this->barcodeType, $barcodeX, $this->barcodeY, $this->barcodeW, $this->barcodeH,'', $barcodeStyle, 'N'); - - //Add this page to the layout system - $b = $this->cornerBorder + ($this->cornerWidth / 2.0); //temp calc for middle of line - $this->layout[$barcodeValue] = array( 'id' => $barcodeValue, - 'tlx' => $this->mm2px($b), - 'tly' => $this->mm2px($b), - 'trx' => $this->mm2px($width - $b), - 'try' => $this->mm2px($b), - 'brx' => $this->mm2px($width - $b), - 'bry' => $this->mm2px($height - $b), - 'blx' => $this->mm2px($b), - 'bly' => $this->mm2px($height - $b), - 'rotation' => 0, - 'boxgroup' => array() - ); - $this->layoutCP = $barcodeValue; - - $this->SetXY($cb + $this->cornerWidth, $cb + $this->cornerWidth); + $this->columnCP = 0; //reset column pointer + } + else // move to a new column + { + $this->SetXY($this->getColumnX(),($this->cornerBorder + $this->cornerWidth)); + } $this->SetAutoPageBreak(true,$this->getMainPageX()); - - $this->setBackground('empty'); } /** From dae85d0ecdc901942954b475aee9a8005c28308a Mon Sep 17 00:00:00 2001 From: mfaber Date: Sat, 31 Aug 2013 19:48:17 +0200 Subject: [PATCH 2/2] DEV: fixed some pagination issues + cosmetics --- application/libraries/admin/quexmlpdf.php | 161 +++++++++++----------- 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/application/libraries/admin/quexmlpdf.php b/application/libraries/admin/quexmlpdf.php index bddda024520..04cb35204c3 100644 --- a/application/libraries/admin/quexmlpdf.php +++ b/application/libraries/admin/quexmlpdf.php @@ -242,7 +242,7 @@ class quexmlpdf extends pdf { span.sectionTitle {font-size:18pt; font-weight:bold;} span.sectionDescription {font-size:14pt; font-weight:bold;} div.sectionInfo {font-style:normal; font-size:10pt; text-align:left; font-weight:normal;} - td.questionnaireInfo {font-size:16pt; text-align:center; font-weight:bold;} + td.questionnaireInfo {font-size:14pt; text-align:center; font-weight:bold;} "; /** @@ -648,7 +648,7 @@ class quexmlpdf extends pdf { * @var mixed Defaults to 5. * @since 2010-10-29 */ - protected $questionnaireInfoMargin = 20; + protected $questionnaireInfoMargin = 5; /** * Height of a response label @@ -2302,92 +2302,89 @@ protected function drawSingleChoiceHorizontal($categories, $subquestions = array $total = count($categories); $currentY = $this->GetY(); - if ($total > $this->singleResponseHorizontalMax) //change if too many cats + if ($total > $this->singleResponseHorizontalMax) //change if too many categories $rwidth = $this->singleResponseVerticalAreaWidthSmall; else $rwidth = $this->singleResponseVerticalAreaWidth; $textwidth = ($this->getColumnWidth() - $this->skipColumnWidth) - ($rwidth * $total); - //draw the header + if ($this->allowSplittingSingleChoiceHorizontal) $this->startTransaction(); //start a transaction + + //draw the header $this->drawSingleChoiceHorizontalHead($categories); - $currentY += $this->responseLabelHeight; - - if ($this->allowSplittingSingleChoiceHorizontal) $this->startTransaction(); //start a transaction - for ($i = 0; $i < count($subquestions); $i++) + + for ($i = 0; $i < count($subquestions); $i++) { - $s = $subquestions[$i]; - - if ($this->allowSplittingSingleChoiceHorizontal && $this->pageBreakOccured) - { - $this->pageBreakOccured = false; - $this->rollBackTransaction(true); - $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break - $this->fillPageBackground(); - $this->newPage(); - $this->drawSingleChoiceHorizontalHead($categories); - - //reset currentY - $currentY = $this->GetY() + $this->responseLabelHeight; - - $i = $i - 2; //go back and draw subquestions on the new page - } - else - { - if ($this->allowSplittingSingleChoiceHorizontal) - { - $this->commitTransaction(); - $this->startTransaction(); //start a transaction to allow for splitting over pages if necessary - } - - //Add box group to current layout - if ($parenttext == false) - $this->addBoxGroup(1,$s['varname'],$s['text']); - else - $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); - - //$html = "
" . $s['text'] . "
"; - //$this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); - - //Draw background - $html = "
"; - $this->setBackground('question'); - $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseHorizontalHeight, $this->getColumnX(), $currentY, $this->style . $html,0,1,true,true); - $this->setDefaultFont($this->responseTextFontSize); - - $this->MultiCell($textwidth,$this->singleResponseHorizontalHeight,$s['text'],0,'R',false,0,$this->getColumnX(),$currentY,true,0,false,true,$this->singleResponseHorizontalHeight,'M',true); - - - //Draw the categories horizontally - $rnum = 1; - foreach ($categories as $r) - { - if ($total == 1) $num = 'only'; - else if ($rnum == 1) $num = 'first'; - else if ($rnum < $total) $num = 'middle'; - else if ($rnum == $total) $num = 'last'; - - $bfilled = false; - if (isset($s['defaultvalue']) && $s['defaultvalue'] !== false && $s['defaultvalue'] == $r['value']) - $bfilled = true; - - $position = $this->drawHorizontalResponseBox(($this->getColumnX() + $textwidth + (($rnum - 1) * $rwidth)),$currentY, $num,false,false,($total > $this->singleResponseHorizontalMax),$bfilled); - - //Add box to the current layout - $this->addBox($position[0],$position[1],$position[2],$position[3],$r['value'],$r['text']); - - $rnum++; - } - - if (($this->GetY() - $currentY) > $this->singleResponseHorizontalHeight) - $currentY = $this->GetY(); - else - $currentY = $currentY + $this->singleResponseHorizontalHeight; - - $this->SetY($currentY,false); - - } + $s = $subquestions[$i]; + + //Add box group to current layout + if ($parenttext == false) + $this->addBoxGroup(1,$s['varname'],$s['text']); + else + $this->addBoxGroup(1,$s['varname'],$parenttext . $this->subQuestionTextSeparator . $s['text']); + + //$html = "
" . $s['text'] . "
"; + //$this->writeHTMLCell($this->getMainPageWidth(), $this->singleResponseAreaHeight, $this->getMainPageX(), $this->GetY(), $this->style . $html,0,1,true,true); + + //Draw background + $html = "
"; + $this->setBackground('question'); + $this->writeHTMLCell($this->getColumnWidth(), $this->singleResponseHorizontalHeight, $this->getColumnX(), $currentY, $this->style . $html,0,1,true,true); + $this->setDefaultFont($this->responseTextFontSize); + + $this->MultiCell($textwidth,$this->singleResponseHorizontalHeight,$s['text'],0,'R',false,0,$this->getColumnX(),$currentY,true,0,false,true,$this->singleResponseHorizontalHeight,'M',true); + + //Draw the categories horizontally + $rnum = 1; + foreach ($categories as $r) + { + if ($total == 1) $num = 'only'; + else if ($rnum == 1) $num = 'first'; + else if ($rnum < $total) $num = 'middle'; + else if ($rnum == $total) $num = 'last'; + + $bfilled = false; + if (isset($s['defaultvalue']) && $s['defaultvalue'] !== false && $s['defaultvalue'] == $r['value']) + $bfilled = true; + + $position = $this->drawHorizontalResponseBox(($this->getColumnX() + $textwidth + (($rnum - 1) * $rwidth)),$currentY, $num,false,false,($total > $this->singleResponseHorizontalMax),$bfilled); + + //Add box to the current layout + $this->addBox($position[0],$position[1],$position[2],$position[3],$r['value'],$r['text']); + + $rnum++; + } + if (($this->GetY() - $currentY) > $this->singleResponseHorizontalHeight) + $currentY = $this->GetY(); + else + $currentY = $currentY + $this->singleResponseHorizontalHeight; + + $this->SetY($currentY,false); + + if ($this->allowSplittingSingleChoiceHorizontal && $this->pageBreakOccured) + { + $this->pageBreakOccured = false; + $this->rollBackTransaction(true); + $this->SetAutoPageBreak(false); //Temporarily set so we don't trigger a page break + $this->fillPageBackground(); + $this->newPage(); + $this->drawSingleChoiceHorizontalHead($categories); + + //reset currentY + $currentY = $this->GetY() + $this->responseLabelHeight; + + $i = $i - 1; //go back and draw subquestions on the new page + } + else + { + if ($this->allowSplittingSingleChoiceHorizontal) + { + $this->commitTransaction(); + $this->startTransaction(); //start a transaction to allow for splitting over pages if necessary + } + } } } @@ -2727,12 +2724,16 @@ protected function newPage($init = false) $this->setBackground('empty'); $this->columnCP = 0; //reset column pointer - } + + } else // move to a new column { $this->SetXY($this->getColumnX(),($this->cornerBorder + $this->cornerWidth)); } $this->SetAutoPageBreak(true,$this->getMainPageX()); + + //after a new page was begun....page should not have already ended + $this->pageBreakOccured = false; } /**