diff --git a/src/Dialog/AbstractDialog.php b/src/Dialog/AbstractDialog.php index 4d12401..b3175c7 100644 --- a/src/Dialog/AbstractDialog.php +++ b/src/Dialog/AbstractDialog.php @@ -201,18 +201,6 @@ protected function decamelize($name) return strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $name)); } - /** - * Parse the given value from the dialog to the appropriate return value for this dialog - * - * @param string $value The raw value received from the dialog window - * @return mixed The logical value presented to the user - * @internal - */ - public function parseValue($value) - { - return $value; - } - /** * Create a dialog handler to process the results for this dialog. * diff --git a/src/Dialog/CalendarDialog.php b/src/Dialog/CalendarDialog.php index 20e0b92..a96139f 100644 --- a/src/Dialog/CalendarDialog.php +++ b/src/Dialog/CalendarDialog.php @@ -3,7 +3,10 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractTextDialog; -use \DateTime; +use DateTime; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\CalendarZen; /** * Use the --calendar option to create a calendar dialog. @@ -83,15 +86,8 @@ public function setDateTime(DateTime $date) return $this; } - /** - * Parses the date string returned from the dialog into a DateTime object - * - * @internal - * @see parent::parseValue() - * @return \DateTime - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - return new DateTime($value); + return new CalendarZen($deferred, $process); } } diff --git a/src/Dialog/ColorSelectionDialog.php b/src/Dialog/ColorSelectionDialog.php index 706c9a7..86f4b19 100644 --- a/src/Dialog/ColorSelectionDialog.php +++ b/src/Dialog/ColorSelectionDialog.php @@ -3,6 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractDialog; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\ColorSelectionZen; /** * Use the --color-selection option to create a color selection dialog. @@ -40,17 +43,8 @@ public function setShowPalette($palette) return $this; } - /** - * Parses the color string returned from the dialog into a #rrggbb string - * - * @internal - * @see parent::parseValue() - * @return string - * @link https://answers.launchpad.net/ubuntu/+source/zenity/+question/204096 - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - // convert zenity's #rrrrggggbbbb to #rrggbb by skipping duplicate info - return '#' . substr($value, 1, 2) . substr($value, 5, 2) . substr($value, 9, 2); + return new ColorSelectionZen($deferred, $process); } } diff --git a/src/Dialog/FileSelectionDialog.php b/src/Dialog/FileSelectionDialog.php index 7a3b962..746d0fb 100644 --- a/src/Dialog/FileSelectionDialog.php +++ b/src/Dialog/FileSelectionDialog.php @@ -3,7 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractDialog; -use SplFileInfo; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\FileSelectionZen; /** * Use the --file-selection option to create a file selection dialog. @@ -120,31 +122,8 @@ public function setFileFilter($filter) return $this; } - /** - * Parses the path string returned from the dialog into a SplFileInfo object - * - * Usually, this will return a single SplFileInfo object. - * - * If the `setMultiple(true)` option is active, this will return an array - * of SplFileInfo objects instead. The size of the array depends on the - * number of files selected by the user. - * - * @internal - * @see parent::parseValue() - * @return SplFileInfo|SplFileInfo[] a single or any number of SplFileInfo objects depending on the multiple setting - * @see self::setMultiple() - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - if ($this->multiple) { - $ret = array(); - - foreach(explode($this->separator, $value) as $path) { - $ret[] = new SplFileInfo($path); - } - - return $ret; - } - return new SplFileInfo($value); + return new FileSelectionZen($deferred, $process, $this->multiple, $this->separator); } } diff --git a/src/Dialog/FormsDialog.php b/src/Dialog/FormsDialog.php index bfe77ec..4414954 100644 --- a/src/Dialog/FormsDialog.php +++ b/src/Dialog/FormsDialog.php @@ -3,6 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractTextDialog; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\FormsZen; /** * Use the --forms option to create a forms dialog. @@ -150,15 +153,8 @@ public function getArgs() return array_merge(parent::getArgs(), $this->fields); } - /** - * Parses the input string returned from the dialog into an array of string values - * - * @return string[] - * @internal - * @see parent::parseValue() - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - return explode($this->separator, $value); + return new FormsZen($deferred, $process, $this->separator); } } diff --git a/src/Dialog/ListDialog.php b/src/Dialog/ListDialog.php index 56e296e..5dc269d 100644 --- a/src/Dialog/ListDialog.php +++ b/src/Dialog/ListDialog.php @@ -3,6 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractTextDialog; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\ListZen; /** * Use the --list option to create a list dialog. @@ -201,33 +204,10 @@ public function getArgs() return array_merge(parent::getArgs(), $this->columns); } - /** - * Parses the string returned from the dialog - * - * Usually, this will return a single string. - * - * If the `setMultiple(true)` option is active or this is a checklist, this - * will return an array of strings instead. The size of the array depends on - * the number of rows selected by the user. - * - * @internal - * @see parent::parseValue() - * @return string|string[] a single or any number of SplFileInfo objects depending on the multiple setting - * @see self::setMultiple() - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - if (trim($value) === '') { - // TODO: move logic - return false; - } + $single = (!$this->multiple && !$this->checklist); - // always split on separator, even if we only return a single value (explicitly or a checklist) - // work around an issue in zenity 3.8: https://bugzilla.gnome.org/show_bug.cgi?id=698683 - $value = explode($this->separator, $value); - if (!$this->multiple && !$this->checklist) { - $value = $value[0]; - } - return $value; + return new ListZen($deferred, $process, $single, $this->separator); } } diff --git a/src/Dialog/PasswordDialog.php b/src/Dialog/PasswordDialog.php index cceb4d3..be06f70 100644 --- a/src/Dialog/PasswordDialog.php +++ b/src/Dialog/PasswordDialog.php @@ -3,6 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractDialog; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\PasswordZen; /** * Use the --password option to create a password entry dialog. @@ -32,9 +35,6 @@ */ class PasswordDialog extends AbstractDialog { - /** @var string */ - const SEPARATOR = '|'; - protected $username = false; /** @@ -50,24 +50,8 @@ public function setUsername($username) return $this; } - /** - * Parses the string returned from the dialog - * - * Usually, this will return a single password string. - * - * If the `setUsername(true)` option is active, this will return an array - * of string username and string password. - * - * @internal - * @see parent::parseValue() - * @return string|string[] a single password string or an array($user, $pass) depending on the username setting - * @see self::setUsername() - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - if ($this->username) { - return explode(self::SEPARATOR, $value, 2); - } - return $value; + return new PasswordZen($deferred, $process, $this->username); } } diff --git a/src/Dialog/ScaleDialog.php b/src/Dialog/ScaleDialog.php index 1ea3120..ec7f781 100644 --- a/src/Dialog/ScaleDialog.php +++ b/src/Dialog/ScaleDialog.php @@ -3,6 +3,9 @@ namespace Clue\React\Zenity\Dialog; use Clue\React\Zenity\Dialog\AbstractTextDialog; +use React\Promise\Deferred; +use Icecave\Mephisto\Process\ProcessInterface; +use Clue\React\Zenity\Zen\ScaleZen; /** * Use the --scale option to create a scale dialog. @@ -87,15 +90,8 @@ public function setHideValue($toggle = true) return $this; } - /** - * Converts the scale string returned from the dialog to an integer - * - * @internal - * @see parent::parseValue() - * @return int - */ - public function parseValue($value) + public function createZen(Deferred $deferred, ProcessInterface $process) { - return (int)$value; + return new ScaleZen($deferred, $process); } } diff --git a/src/Launcher.php b/src/Launcher.php index 025d7d6..ac5b67c 100644 --- a/src/Launcher.php +++ b/src/Launcher.php @@ -58,7 +58,7 @@ public function launch(AbstractDialog $dialog) $zen = $dialog->createZen($deferred, $process); - $process->outputStream()->on('end', function() use ($process, $zen, &$result, $dialog, $deferred) { + $process->outputStream()->on('end', function() use ($process, $zen, &$result, $deferred) { $code = $process->status()->exitCode(); if ($code !== 0) { $deferred->reject($code); @@ -66,7 +66,7 @@ public function launch(AbstractDialog $dialog) if ($result === null) { $result = true; } else { - $result = $dialog->parseValue(trim($result)); + $result = $zen->parseValue(trim($result)); } $deferred->resolve($result); } diff --git a/src/Zen/BaseZen.php b/src/Zen/BaseZen.php index 2f735b6..d3928b3 100644 --- a/src/Zen/BaseZen.php +++ b/src/Zen/BaseZen.php @@ -44,4 +44,16 @@ protected function writeln($line) { $this->process->inputStream()->write($line . PHP_EOL); } + + /** + * Parse the given value from the dialog to the appropriate return value for this dialog + * + * @param string $value The raw value received from the dialog window + * @return mixed The logical value presented to the user + * @internal + */ + public function parseValue($value) + { + return $value; + } } diff --git a/src/Zen/CalendarZen.php b/src/Zen/CalendarZen.php new file mode 100644 index 0000000..dfd161d --- /dev/null +++ b/src/Zen/CalendarZen.php @@ -0,0 +1,21 @@ +multiple = $multiple; + $this->separator = $separator; + } + + /** + * Parses the path string returned from the dialog into a SplFileInfo object + * + * Usually, this will return a single SplFileInfo object. + * + * If the `setMultiple(true)` option is active, this will return an array + * of SplFileInfo objects instead. The size of the array depends on the + * number of files selected by the user. + * + * @internal + * @see parent::parseValue() + * @return SplFileInfo|SplFileInfo[] a single or any number of SplFileInfo objects depending on the multiple setting + * @see FileSelectionDialog::setMultiple() + */ + public function parseValue($value) + { + if ($this->multiple) { + $ret = array(); + + foreach(explode($this->separator, $value) as $path) { + $ret[] = new SplFileInfo($path); + } + + return $ret; + } + return new SplFileInfo($value); + } +} diff --git a/src/Zen/FormsZen.php b/src/Zen/FormsZen.php new file mode 100644 index 0000000..7c13034 --- /dev/null +++ b/src/Zen/FormsZen.php @@ -0,0 +1,31 @@ +separator = $separator; + } + + /** + * Parses the input string returned from the dialog into an array of string values + * + * @return string[] + * @internal + * @see parent::parseValue() + */ + public function parseValue($value) + { + return explode($this->separator, $value); + } +} diff --git a/src/Zen/ListZen.php b/src/Zen/ListZen.php new file mode 100644 index 0000000..d341c70 --- /dev/null +++ b/src/Zen/ListZen.php @@ -0,0 +1,51 @@ +single = $single; + $this->separator = $separator; + } + + /** + * Parses the string returned from the dialog + * + * Usually, this will return a single string. + * + * If the `setMultiple(true)` option is active or this is a checklist, this + * will return an array of strings instead. The size of the array depends on + * the number of rows selected by the user. + * + * @internal + * @see parent::parseValue() + * @return string|string[] a single or any number of strings depending on the multiple setting + * @see ListDialog::setMultiple() + */ + public function parseValue($value) + { + if (trim($value) === '') { + // TODO: move logic + return false; + } + + // always split on separator, even if we only return a single value (explicitly or a checklist) + // work around an issue in zenity 3.8: https://bugzilla.gnome.org/show_bug.cgi?id=698683 + $value = explode($this->separator, $value); + if ($this->single) { + $value = $value[0]; + } + return $value; + } +} diff --git a/src/Zen/PasswordZen.php b/src/Zen/PasswordZen.php new file mode 100644 index 0000000..15ef921 --- /dev/null +++ b/src/Zen/PasswordZen.php @@ -0,0 +1,43 @@ +username = $username; + } + + /** + * Parses the string returned from the dialog + * + * Usually, this will return a single password string. + * + * If the `setUsername(true)` option is active, this will return an array + * of string username and string password. + * + * @internal + * @see parent::parseValue() + * @return string|string[] a single password string or an array($user, $pass) depending on the username setting + * @see PasswordDialog::setUsername() + */ + public function parseValue($value) + { + if ($this->username) { + return explode(self::SEPARATOR, $value, 2); + } + return $value; + } +} diff --git a/src/Zen/ScaleZen.php b/src/Zen/ScaleZen.php new file mode 100644 index 0000000..da0d67b --- /dev/null +++ b/src/Zen/ScaleZen.php @@ -0,0 +1,20 @@ +getMock('Icecave\Mephisto\Process\ProcessInterface'); + $deferred = $this->getMock('React\Promise\Deferred'); + + if ($dialog === null) { + $dialog = $this->createDialog(); + } + + return $dialog->createZen($deferred, $process); + } + abstract protected function getType(); protected function getFixedArgs() @@ -39,13 +51,7 @@ public function testEmptyDialog() public function testCreatesZen() { - $process = $this->getMock('Icecave\Mephisto\Process\ProcessInterface'); - $deferred = $this->getMock('React\Promise\Deferred'); - - $dialog = $this->createDialog(); - $zen = $dialog->createZen($deferred, $process); - - $this->assertInstanceOf('Clue\React\Zenity\Zen\BaseZen', $zen); + $this->assertInstanceOf('Clue\React\Zenity\Zen\BaseZen', $this->createZen()); } public function testDefaultArgs() @@ -78,10 +84,10 @@ public function testDefaultArgs() public function assertParsingValues(array $values) { - $dialog = $this->createDialog(); + $zen = $this->createZen(); foreach ($values as $in => $out) { - $this->assertEquals($out, $dialog->parseValue($in)); + $this->assertEquals($out, $zen->parseValue($in)); } } } diff --git a/tests/Dialog/CalendarDialogTest.php b/tests/Dialog/CalendarDialogTest.php index 1d2d34f..9fe4a45 100644 --- a/tests/Dialog/CalendarDialogTest.php +++ b/tests/Dialog/CalendarDialogTest.php @@ -39,11 +39,4 @@ public function testDateFromDateTime() $this->assertDialogArgs(array('--year=2014', '--month=8', '--day=2'), $dialog); } - - public function testParsingValues() - { - $this->assertParsingValues(array( - '2014-08-02' => new DateTime('2014-08-02') - )); - } } diff --git a/tests/Dialog/ColorSelectionDialogTest.php b/tests/Dialog/ColorSelectionDialogTest.php index f5ce389..7333282 100644 --- a/tests/Dialog/ColorSelectionDialogTest.php +++ b/tests/Dialog/ColorSelectionDialogTest.php @@ -32,11 +32,4 @@ public function testShowPalette() $this->assertDialogArgs(array(), $dialog); } - - public function testParsingValues() - { - $this->assertParsingValues(array( - '#121234345656' => '#123456' - )); - } } diff --git a/tests/Dialog/FileSelectionDialogTest.php b/tests/Dialog/FileSelectionDialogTest.php index 4c9c1a2..4cab531 100644 --- a/tests/Dialog/FileSelectionDialogTest.php +++ b/tests/Dialog/FileSelectionDialogTest.php @@ -74,7 +74,7 @@ public function testParsingMultipleValues() new SplFileInfo('CHANGELOG.md') ); - $this->assertEquals($expected, $dialog->parseValue($selection)); + $this->assertEquals($expected, $this->createZen($dialog)->parseValue($selection)); } public function testParsingSingleValueInMultipleSelection() @@ -87,6 +87,6 @@ public function testParsingSingleValueInMultipleSelection() new SplFileInfo('README.md') ); - $this->assertEquals($expected, $dialog->parseValue($selection)); + $this->assertEquals($expected, $this->createZen($dialog)->parseValue($selection)); } } diff --git a/tests/Dialog/ListDialogTest.php b/tests/Dialog/ListDialogTest.php index b715b44..f1abf9f 100644 --- a/tests/Dialog/ListDialogTest.php +++ b/tests/Dialog/ListDialogTest.php @@ -79,14 +79,14 @@ public function testParsingSingleValue() { $dialog = new ListDialog(); - $this->assertEquals('Nobody', $dialog->parseValue('Nobody')); + $this->assertEquals('Nobody', $this->createZen($dialog)->parseValue('Nobody')); } public function testParsingSingleValueWithBuggedZenity() { $dialog = new ListDialog(); - $this->assertEquals('Nobody', $dialog->parseValue('Nobody|||nobody@example.com|||20')); + $this->assertEquals('Nobody', $this->createZen($dialog)->parseValue('Nobody|||nobody@example.com|||20')); } public function testParsingMultipleValues() @@ -94,13 +94,13 @@ public function testParsingMultipleValues() $dialog = new ListDialog(); $dialog->setMultiple(true); - $this->assertEquals(array('Nobody', 'Somebody'), $dialog->parseValue('Nobody|||Somebody')); + $this->assertEquals(array('Nobody', 'Somebody'), $this->createZen($dialog)->parseValue('Nobody|||Somebody')); } public function testParsingNoValue() { $dialog = new ListDialog(); - $this->assertEquals(false, $dialog->parseValue('')); + $this->assertEquals(false, $this->createZen($dialog)->parseValue('')); } } diff --git a/tests/Dialog/PasswordDialogTest.php b/tests/Dialog/PasswordDialogTest.php index 73e5229..f144903 100644 --- a/tests/Dialog/PasswordDialogTest.php +++ b/tests/Dialog/PasswordDialogTest.php @@ -43,7 +43,7 @@ public function testParsingUsernamePassword() $dialog = new PasswordDialog(); $dialog->setUsername(true); - $this->assertEquals(array('username', 'password'), $dialog->parseValue('username|password')); - $this->assertEquals(array('user', 'name|pass|word'), $dialog->parseValue('user|name|pass|word')); + $this->assertEquals(array('username', 'password'), $this->createZen($dialog)->parseValue('username|password')); + $this->assertEquals(array('user', 'name|pass|word'), $this->createZen($dialog)->parseValue('user|name|pass|word')); } } diff --git a/tests/Zen/CalendarZenTest.php b/tests/Zen/CalendarZenTest.php new file mode 100644 index 0000000..288a077 --- /dev/null +++ b/tests/Zen/CalendarZenTest.php @@ -0,0 +1,13 @@ +deferred, $this->process); + + $this->assertEquals(new DateTime('2014-08-02'), $zen->parseValue('2014-08-02')); + } +} diff --git a/tests/Zen/ColorSelectionZenTest.php b/tests/Zen/ColorSelectionZenTest.php new file mode 100644 index 0000000..3f9d149 --- /dev/null +++ b/tests/Zen/ColorSelectionZenTest.php @@ -0,0 +1,13 @@ +deferred, $this->process); + + $this->assertEquals('#123456', $zen->parseValue('#121234345656')); + } +}