Skip to content

Commit 7fe32e6

Browse files
phryneastroosan
authored andcommitted
Add support for MACROBUTTON Field (#1021)
* add functionality to use MACROBUTTON as Field, use Styles for Field, add noProof to Font Style * code review * refactoring + fixes + unit tests
1 parent f3c73f3 commit 7fe32e6

File tree

7 files changed

+191
-1
lines changed

7 files changed

+191
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ v0.15.0 (?? ??? 2018)
1313
- Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276
1414
- Add support for Cell Spacing @dox07 @troosan #1040
1515
- Add parsing of formatting inside lists @atomicalnet @troosan #594
16+
- Add support for MACROBUTTON field @phryneas @troosan #1021
1617

1718
### Fixed
1819
- Fix reading of docx default style - @troosan #1238

samples/Sample_27_Field.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
$section->addText('Number of pages field:');
2222
$section->addField('NUMPAGES', array('numformat' => '0,00', 'format' => 'Arabic'), array('PreserveFormat'));
23+
$section->addTextBreak();
2324

2425
$textrun = $section->addTextRun();
2526
$textrun->addText('An index field is ');
@@ -43,6 +44,19 @@
4344
$textrun->addText('This is the date of lunar calendar ');
4445
$textrun->addField('DATE', array('dateformat' => 'd-M-yyyy H:mm:ss'), array('PreserveFormat', 'LunarCalendar'));
4546
$textrun->addText(' written in a textrun.');
47+
$section->addTextBreak();
48+
49+
$macroText = new TextRun();
50+
$macroText->addText('Double click', array('bold' => true));
51+
$macroText->addText(' to ');
52+
$macroText->addText('zoom to 100%', array('italic' => true));
53+
54+
$section->addText('A macro button with styled text:');
55+
$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), $macroText);
56+
$section->addTextBreak();
57+
58+
$section->addText('A macro button with simple text:');
59+
$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), 'double click to zoom');
4660

4761
// Save file
4862
echo write($phpWord, basename(__FILE__, '.php'), $writers);

src/PhpWord/Element/Field.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace PhpOffice\PhpWord\Element;
1919

20+
use PhpOffice\PhpWord\Style\Font;
21+
2022
/**
2123
* Field element
2224
*
@@ -54,6 +56,9 @@ class Field extends AbstractElement
5456
),
5557
'options' => array('PreserveFormat', 'LunarCalendar', 'SakaEraCalendar', 'LastUsedFormat'),
5658
),
59+
'MACROBUTTON' => array(
60+
'properties' => array('macroname' => ''),
61+
),
5762
'XE' => array(
5863
'properties' => array(),
5964
'options' => array('Bold', 'Italic'),
@@ -92,6 +97,13 @@ class Field extends AbstractElement
9297
*/
9398
protected $options = array();
9499

100+
/**
101+
* Font style
102+
*
103+
* @var \PhpOffice\PhpWord\Style\Font
104+
*/
105+
protected $fontStyle;
106+
95107
/**
96108
* Create a new Field Element
97109
*
@@ -203,6 +215,46 @@ public function getOptions()
203215
return $this->options;
204216
}
205217

218+
/**
219+
* Set Text style
220+
*
221+
* @param \PhpOffice\PhpWord\Style\Font $style
222+
* @return \PhpOffice\PhpWord\Style\Font
223+
*/
224+
public function setFontStyle($style = null)
225+
{
226+
if (!$style instanceof Font) {
227+
throw new \InvalidArgumentException('font style must be of type Font');
228+
}
229+
230+
if ($style->isNoProof()) {
231+
$this->fontStyle = $style;
232+
} else {
233+
// make a copy of the font so the original is not altered
234+
$this->fontStyle = clone $style;
235+
$this->fontStyle->setNoProof(true);
236+
}
237+
238+
return $this->fontStyle;
239+
}
240+
241+
/**
242+
* Get Text style
243+
*
244+
* @return \PhpOffice\PhpWord\Style\Font
245+
*/
246+
public function getFontStyle()
247+
{
248+
if ($this->fontStyle == null) {
249+
$font = new Font();
250+
$font->setNoProof(true);
251+
252+
return $font;
253+
}
254+
255+
return $this->fontStyle;
256+
}
257+
206258
/**
207259
* Set Field text
208260
*

src/PhpWord/Style/Font.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ class Font extends AbstractStyle
236236
*/
237237
private $rtl = false;
238238

239+
/**
240+
* noProof (disables AutoCorrect)
241+
*
242+
* @var bool
243+
* http://www.datypic.com/sc/ooxml/e-w_noProof-1.html
244+
*/
245+
private $noProof = false;
246+
239247
/**
240248
* Languages
241249
* @var \PhpOffice\PhpWord\Style\Language
@@ -706,6 +714,29 @@ public function setKerning($value = null)
706714
return $this;
707715
}
708716

717+
/**
718+
* Get noProof (disables autocorrect)
719+
*
720+
* @return bool
721+
*/
722+
public function isNoProof()
723+
{
724+
return $this->noProof;
725+
}
726+
727+
/**
728+
* Set noProof (disables autocorrect)
729+
*
730+
* @param bool $value
731+
* @return $this
732+
*/
733+
public function setNoProof($value = false)
734+
{
735+
$this->noProof = $value;
736+
737+
return $this;
738+
}
739+
709740
/**
710741
* Get line height
711742
*

src/PhpWord/Writer/Word2007/Element/Field.php

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,22 @@ class Field extends Text
2929
*/
3030
public function write()
3131
{
32-
$xmlWriter = $this->getXmlWriter();
3332
$element = $this->getElement();
3433
if (!$element instanceof \PhpOffice\PhpWord\Element\Field) {
3534
return;
3635
}
3736

37+
$methodName = 'write' . ucfirst(strtolower($element->getType()));
38+
if (method_exists($this, $methodName)) {
39+
$this->$methodName($element);
40+
} else {
41+
$this->writeDefault($element);
42+
}
43+
}
44+
45+
private function writeDefault(\PhpOffice\PhpWord\Element\Field $element)
46+
{
47+
$xmlWriter = $this->getXmlWriter();
3848
$this->startElementP();
3949

4050
$xmlWriter->startElement('w:r');
@@ -104,6 +114,51 @@ public function write()
104114
$this->endElementP(); // w:p
105115
}
106116

117+
/**
118+
* Writes a macrobutton field
119+
*
120+
* //TODO A lot of code duplication with general method, should maybe be refactored
121+
* @param \PhpOffice\PhpWord\Element\Field $element
122+
*/
123+
protected function writeMacrobutton(\PhpOffice\PhpWord\Element\Field $element)
124+
{
125+
$xmlWriter = $this->getXmlWriter();
126+
$this->startElementP();
127+
128+
$xmlWriter->startElement('w:r');
129+
$xmlWriter->startElement('w:fldChar');
130+
$xmlWriter->writeAttribute('w:fldCharType', 'begin');
131+
$xmlWriter->endElement(); // w:fldChar
132+
$xmlWriter->endElement(); // w:r
133+
134+
$instruction = ' ' . $element->getType() . ' ' . $this->buildPropertiesAndOptions($element);
135+
if (is_string($element->getText())) {
136+
$instruction .= $element->getText() . ' ';
137+
}
138+
139+
$xmlWriter->startElement('w:r');
140+
$xmlWriter->startElement('w:instrText');
141+
$xmlWriter->writeAttribute('xml:space', 'preserve');
142+
$xmlWriter->text($instruction);
143+
$xmlWriter->endElement(); // w:instrText
144+
$xmlWriter->endElement(); // w:r
145+
146+
if ($element->getText() != null) {
147+
if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) {
148+
$containerWriter = new Container($xmlWriter, $element->getText(), true);
149+
$containerWriter->write();
150+
}
151+
}
152+
153+
$xmlWriter->startElement('w:r');
154+
$xmlWriter->startElement('w:fldChar');
155+
$xmlWriter->writeAttribute('w:fldCharType', 'end');
156+
$xmlWriter->endElement(); // w:fldChar
157+
$xmlWriter->endElement(); // w:r
158+
159+
$this->endElementP(); // w:p
160+
}
161+
107162
private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $element)
108163
{
109164
$propertiesAndOptions = '';
@@ -119,6 +174,9 @@ private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $ele
119174
case 'dateformat':
120175
$propertiesAndOptions .= '\@ "' . $propval . '" ';
121176
break;
177+
case 'macroname':
178+
$propertiesAndOptions .= $propval . ' ';
179+
break;
122180
}
123181
}
124182

src/PhpWord/Writer/Word2007/Style/Font.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ private function writeStyle()
135135
$xmlWriter->writeElementIf($style->getSpacing() !== null, 'w:spacing', 'w:val', $style->getSpacing());
136136
$xmlWriter->writeElementIf($style->getKerning() !== null, 'w:kern', 'w:val', $style->getKerning() * 2);
137137

138+
// noProof
139+
$xmlWriter->writeElementIf($style->isNoProof() !== false, 'w:noProof');
140+
138141
// Background-Color
139142
$shading = $style->getShading();
140143
if (!is_null($shading)) {

tests/PhpWord/Writer/Word2007/ElementTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,37 @@ public function testFieldElementWithComplexText()
322322
$this->assertEquals('"\\b \\i ', $doc->getElement($element)->textContent);
323323
}
324324

325+
/**
326+
* Test writing the macrobutton field
327+
*/
328+
public function testMacroButtonField()
329+
{
330+
$phpWord = new PhpWord();
331+
$section = $phpWord->addSection();
332+
333+
$macroText = new TextRun();
334+
$macroText->addText('Double click', array('bold' => true));
335+
$macroText->addText(' to ');
336+
$macroText->addText('zoom to 100%', array('italic' => true));
337+
338+
$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), $macroText);
339+
$section->addField('MACROBUTTON', array('macroname' => 'Zoom100'), array(), 'double click to zoom');
340+
$doc = TestHelperDOCX::getDocument($phpWord);
341+
342+
$element = '/w:document/w:body/w:p[1]/w:r[2]/w:instrText';
343+
$this->assertTrue($doc->elementExists($element));
344+
$this->assertEquals(' MACROBUTTON Zoom100 ', $doc->getElement($element)->textContent);
345+
346+
$element = '/w:document/w:body/w:p[1]/w:r[3]/';
347+
$this->assertTrue($doc->elementExists($element . 'w:t'));
348+
$this->assertEquals('Double click', $doc->getElement($element . 'w:t')->textContent);
349+
$this->assertTrue($doc->elementExists($element . 'w:rPr/w:b'));
350+
351+
$element = '/w:document/w:body/w:p[2]/w:r[2]/w:instrText';
352+
$this->assertTrue($doc->elementExists($element));
353+
$this->assertEquals(' MACROBUTTON Zoom100 double click to zoom ', $doc->getElement($element)->textContent);
354+
}
355+
325356
/**
326357
* Test form fields
327358
*/

0 commit comments

Comments
 (0)