diff --git a/CHANGELOG.md b/CHANGELOG.md index f6f87158..c684a37d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ v0.15.0 (?? ??? 2018) - Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276 - Add support for Cell Spacing @dox07 @troosan #1040 - Add parsing of formatting inside lists @atomicalnet @troosan #594 +- Add support for MACROBUTTON field @phryneas @troosan #1021 ### Fixed - Fix reading of docx default style - @troosan #1238 diff --git a/samples/Sample_27_Field.php b/samples/Sample_27_Field.php index ec9dbe25..9c37dffe 100644 --- a/samples/Sample_27_Field.php +++ b/samples/Sample_27_Field.php @@ -20,6 +20,7 @@ $section->addField('PAGE', array('format' => 'Arabic')); $section->addText('Number of pages field:'); $section->addField('NUMPAGES', array('numformat' => '0,00', 'format' => 'Arabic'), array('PreserveFormat')); +$section->addTextBreak(); $textrun = $section->addTextRun(); $textrun->addText('An index field is '); @@ -43,6 +44,19 @@ $textrun = $section->addTextRun(array('alignment' => \PhpOffice\PhpWord\SimpleTy $textrun->addText('This is the date of lunar calendar '); $textrun->addField('DATE', array('dateformat' => 'd-M-yyyy H:mm:ss'), array('PreserveFormat', 'LunarCalendar')); $textrun->addText(' written in a textrun.'); +$section->addTextBreak(); + +$macroText = new TextRun(); +$macroText->addText('Double click', array('bold' => true)); +$macroText->addText(' to '); +$macroText->addText('zoom to 100%', array('italic' => true)); + +$section->addText('A macro button with styled text:'); +$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), $macroText); +$section->addTextBreak(); + +$section->addText('A macro button with simple text:'); +$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), 'double click to zoom'); // Save file echo write($phpWord, basename(__FILE__, '.php'), $writers); diff --git a/src/PhpWord/Element/Field.php b/src/PhpWord/Element/Field.php index 7b33a479..5aeffbc1 100644 --- a/src/PhpWord/Element/Field.php +++ b/src/PhpWord/Element/Field.php @@ -17,6 +17,8 @@ namespace PhpOffice\PhpWord\Element; +use PhpOffice\PhpWord\Style\Font; + /** * Field element * @@ -54,6 +56,9 @@ class Field extends AbstractElement ), 'options' => array('PreserveFormat', 'LunarCalendar', 'SakaEraCalendar', 'LastUsedFormat'), ), + 'MACROBUTTON' => array( + 'properties' => array('macroname' => ''), + ), 'XE' => array( 'properties' => array(), 'options' => array('Bold', 'Italic'), @@ -92,6 +97,13 @@ class Field extends AbstractElement */ protected $options = array(); + /** + * Font style + * + * @var \PhpOffice\PhpWord\Style\Font + */ + protected $fontStyle; + /** * Create a new Field Element * @@ -203,6 +215,46 @@ class Field extends AbstractElement return $this->options; } + /** + * Set Text style + * + * @param \PhpOffice\PhpWord\Style\Font $style + * @return \PhpOffice\PhpWord\Style\Font + */ + public function setFontStyle($style = null) + { + if (!$style instanceof Font) { + throw new \InvalidArgumentException('font style must be of type Font'); + } + + if ($style->isNoProof()) { + $this->fontStyle = $style; + } else { + // make a copy of the font so the original is not altered + $this->fontStyle = clone $style; + $this->fontStyle->setNoProof(true); + } + + return $this->fontStyle; + } + + /** + * Get Text style + * + * @return \PhpOffice\PhpWord\Style\Font + */ + public function getFontStyle() + { + if ($this->fontStyle == null) { + $font = new Font(); + $font->setNoProof(true); + + return $font; + } + + return $this->fontStyle; + } + /** * Set Field text * diff --git a/src/PhpWord/Style/Font.php b/src/PhpWord/Style/Font.php index 8bfb3ac5..03fb692c 100644 --- a/src/PhpWord/Style/Font.php +++ b/src/PhpWord/Style/Font.php @@ -236,6 +236,14 @@ class Font extends AbstractStyle */ private $rtl = false; + /** + * noProof (disables AutoCorrect) + * + * @var bool + * http://www.datypic.com/sc/ooxml/e-w_noProof-1.html + */ + private $noProof = false; + /** * Languages * @var \PhpOffice\PhpWord\Style\Language @@ -706,6 +714,29 @@ class Font extends AbstractStyle return $this; } + /** + * Get noProof (disables autocorrect) + * + * @return bool + */ + public function isNoProof() + { + return $this->noProof; + } + + /** + * Set noProof (disables autocorrect) + * + * @param bool $value + * @return $this + */ + public function setNoProof($value = false) + { + $this->noProof = $value; + + return $this; + } + /** * Get line height * diff --git a/src/PhpWord/Writer/Word2007/Element/Field.php b/src/PhpWord/Writer/Word2007/Element/Field.php index 75d4983f..336a4325 100644 --- a/src/PhpWord/Writer/Word2007/Element/Field.php +++ b/src/PhpWord/Writer/Word2007/Element/Field.php @@ -29,12 +29,22 @@ class Field extends Text */ public function write() { - $xmlWriter = $this->getXmlWriter(); $element = $this->getElement(); if (!$element instanceof \PhpOffice\PhpWord\Element\Field) { return; } + $methodName = 'write' . ucfirst(strtolower($element->getType())); + if (method_exists($this, $methodName)) { + $this->$methodName($element); + } else { + $this->writeDefault($element); + } + } + + private function writeDefault(\PhpOffice\PhpWord\Element\Field $element) + { + $xmlWriter = $this->getXmlWriter(); $this->startElementP(); $xmlWriter->startElement('w:r'); @@ -104,6 +114,51 @@ class Field extends Text $this->endElementP(); // w:p } + /** + * Writes a macrobutton field + * + * //TODO A lot of code duplication with general method, should maybe be refactored + * @param \PhpOffice\PhpWord\Element\Field $element + */ + protected function writeMacrobutton(\PhpOffice\PhpWord\Element\Field $element) + { + $xmlWriter = $this->getXmlWriter(); + $this->startElementP(); + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:fldChar'); + $xmlWriter->writeAttribute('w:fldCharType', 'begin'); + $xmlWriter->endElement(); // w:fldChar + $xmlWriter->endElement(); // w:r + + $instruction = ' ' . $element->getType() . ' ' . $this->buildPropertiesAndOptions($element); + if (is_string($element->getText())) { + $instruction .= $element->getText() . ' '; + } + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:instrText'); + $xmlWriter->writeAttribute('xml:space', 'preserve'); + $xmlWriter->text($instruction); + $xmlWriter->endElement(); // w:instrText + $xmlWriter->endElement(); // w:r + + if ($element->getText() != null) { + if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) { + $containerWriter = new Container($xmlWriter, $element->getText(), true); + $containerWriter->write(); + } + } + + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:fldChar'); + $xmlWriter->writeAttribute('w:fldCharType', 'end'); + $xmlWriter->endElement(); // w:fldChar + $xmlWriter->endElement(); // w:r + + $this->endElementP(); // w:p + } + private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $element) { $propertiesAndOptions = ''; @@ -119,6 +174,9 @@ class Field extends Text case 'dateformat': $propertiesAndOptions .= '\@ "' . $propval . '" '; break; + case 'macroname': + $propertiesAndOptions .= $propval . ' '; + break; } } diff --git a/src/PhpWord/Writer/Word2007/Style/Font.php b/src/PhpWord/Writer/Word2007/Style/Font.php index ecaad416..a13db155 100644 --- a/src/PhpWord/Writer/Word2007/Style/Font.php +++ b/src/PhpWord/Writer/Word2007/Style/Font.php @@ -135,6 +135,9 @@ class Font extends AbstractStyle $xmlWriter->writeElementIf($style->getSpacing() !== null, 'w:spacing', 'w:val', $style->getSpacing()); $xmlWriter->writeElementIf($style->getKerning() !== null, 'w:kern', 'w:val', $style->getKerning() * 2); + // noProof + $xmlWriter->writeElementIf($style->isNoProof() !== false, 'w:noProof'); + // Background-Color $shading = $style->getShading(); if (!is_null($shading)) { diff --git a/tests/PhpWord/Writer/Word2007/ElementTest.php b/tests/PhpWord/Writer/Word2007/ElementTest.php index f91a8479..887e8e58 100644 --- a/tests/PhpWord/Writer/Word2007/ElementTest.php +++ b/tests/PhpWord/Writer/Word2007/ElementTest.php @@ -322,6 +322,37 @@ class ElementTest extends \PHPUnit\Framework\TestCase $this->assertEquals('"\\b \\i ', $doc->getElement($element)->textContent); } + /** + * Test writing the macrobutton field + */ + public function testMacroButtonField() + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + + $macroText = new TextRun(); + $macroText->addText('Double click', array('bold' => true)); + $macroText->addText(' to '); + $macroText->addText('zoom to 100%', array('italic' => true)); + + $section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), $macroText); + $section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), 'double click to zoom'); + $doc = TestHelperDOCX::getDocument($phpWord); + + $element = '/w:document/w:body/w:p[1]/w:r[2]/w:instrText'; + $this->assertTrue($doc->elementExists($element)); + $this->assertEquals(' MACROBUTTON Zoom100 ', $doc->getElement($element)->textContent); + + $element = '/w:document/w:body/w:p[1]/w:r[3]/'; + $this->assertTrue($doc->elementExists($element . 'w:t')); + $this->assertEquals('Double click', $doc->getElement($element . 'w:t')->textContent); + $this->assertTrue($doc->elementExists($element . 'w:rPr/w:b')); + + $element = '/w:document/w:body/w:p[2]/w:r[2]/w:instrText'; + $this->assertTrue($doc->elementExists($element)); + $this->assertEquals(' MACROBUTTON Zoom100 double click to zoom ', $doc->getElement($element)->textContent); + } + /** * Test form fields */