1
0

Dialog.pm 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. # BEGIN COPYRIGHT BLOCK
  2. # This Program is free software; you can redistribute it and/or modify it under
  3. # the terms of the GNU General Public License as published by the Free Software
  4. # Foundation; version 2 of the License.
  5. #
  6. # This Program is distributed in the hope that it will be useful, but WITHOUT
  7. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. #
  10. # You should have received a copy of the GNU General Public License along with
  11. # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. # Place, Suite 330, Boston, MA 02111-1307 USA.
  13. #
  14. # In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. # right to link the code of this Program with code not covered under the GNU
  16. # General Public License ("Non-GPL Code") and to distribute linked combinations
  17. # including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. # permitted under this exception must only link to the code of this Program
  19. # through those well defined interfaces identified in the file named EXCEPTION
  20. # found in the source code files (the "Approved Interfaces"). The files of
  21. # Non-GPL Code may instantiate templates or use macros or inline functions from
  22. # the Approved Interfaces without causing the resulting work to be covered by
  23. # the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. # additions to the list of Approved Interfaces. You must obey the GNU General
  25. # Public License in all respects for all of the Program code and other code used
  26. # in conjunction with the Program except the Non-GPL Code covered by this
  27. # exception. If you modify this file, you may extend this exception to your
  28. # version of the file, but you are not obligated to do so. If you do not wish to
  29. # provide this exception without modification, you must delete this exception
  30. # statement from your version and license this file solely under the GPL without
  31. # exception.
  32. #
  33. #
  34. # Copyright (C) 2007 Red Hat, Inc.
  35. # All rights reserved.
  36. # END COPYRIGHT BLOCK
  37. #
  38. package Dialog;
  39. use DialogManager;
  40. #require Exporter;
  41. #@ISA = qw(Exporter);
  42. #@EXPORT = qw();
  43. # NOTE: This "class" is an "abstract" class. There are two methods which
  44. # must be provided by subclasses:
  45. # $ans = $dialog->defaultAns($promptindex);
  46. # where $promptindex is the index into the array of prompts given when
  47. # constructing the Dialog object
  48. # The dialog will typically use a default answer either hardcoded in
  49. # or from some key in the setup cache (.inf) file
  50. #
  51. # $resp = $dialog->handleResponse($ans, $index);
  52. # The dialog uses this method to perform validation of the input, set the value
  53. # in the setup cache, display errors or warnings, and tell the dialog manager
  54. # if the prompt needs to be redisplayed, or if there was an unrecoverable error
  55. # $resp should be $SAME to reprompt, $ERR to abort, or $NEXT to continue
  56. # the $ans and defaultAns should be in the native charset, so the dialog
  57. # may have to convert to/from utf8 as needed.
  58. # a dialog consists of a title, some explanatory text, and one or more prompts
  59. # each prompt has a default value. An example of a dialog with more than
  60. # one prompt would be a dialog asking the user for the new root DN and password -
  61. # in that case, there would be 3 prompts - one for the DN, one for the password,
  62. # and one to verify the password
  63. # The text and prompts are given as resource keys. Usually the resource value
  64. # will be a simple string, in which case the resource key is passed in as a simple
  65. # string. However, if the resource string contains replaceable parameters, the
  66. # resource key is passed as an array ref consisting of the resource key as the
  67. # first element and the parameters to use for replacement as the subsequent
  68. # array elements e.g.
  69. # $foo = new Dialog(['RESOURCE_KEY_CONFIG_LDAP_URL', $secure, $host, $port, $suffix], ...);
  70. # but usually for simple cases like this:
  71. # $foo = new Dialog('RESOURCE_KEY_WELCOME', ...);
  72. # The manager contains the context for all of the dialogs - the setup type, the resource
  73. # file, setup log, other context shared among the dialogs
  74. # the type is the setup type - 1, 2, or 3 for express, typical, or custom
  75. # type is used to say which types use this dialog
  76. sub new {
  77. my $type = shift;
  78. my $self = {};
  79. $self->{type} = shift;
  80. $self->{text} = shift;
  81. $self->{defaultAns} = shift;
  82. $self->{handleResp} = shift;
  83. $self->{prompts} = \@_;
  84. $self = bless $self, $type;
  85. return $self;
  86. }
  87. sub setManager {
  88. my $self = shift;
  89. $self->{"manager"} = shift;
  90. }
  91. # returns true if this dialog is to be displayed for the current setup type
  92. # false otherwise
  93. sub isDisplayed {
  94. my $self = shift;
  95. return $self->{type} <= $self->{"manager"}->{type};
  96. }
  97. # each prompt looks like this:
  98. # [ 'resource key', is pwd, hide ]
  99. # The resource key is the string key of the resource
  100. # is pwd is optional - if present, the prompt is for a password
  101. # and should not echo the answer
  102. # hide is optional - if present and true, the prompt will not be displayed - this
  103. # is useful in cases where you may want to display or hide a subprompt depending
  104. # on the response to a main prompt
  105. # e.g.
  106. # ['RESOURCE_USERNAME'], ['RESOURCE_PASSWORD', 1], ['RESOURCE_PASSWORD_AGAIN', 1]
  107. # e.g.
  108. # ['USE_SECURITY'], ['CA_CERTIFICATE', 0, 0]
  109. # you can set the 0 to a 1 if the user has chosen to use security
  110. sub run {
  111. my $self = shift;
  112. my $resp = $DialogManager::SAME;
  113. # display the dialog text
  114. if ($self->isDisplayed()) {
  115. $self->{manager}->showText($self->{text});
  116. }
  117. # display each prompt for this dialog
  118. my $index = 0;
  119. my @prompts = @{$self->{prompts}};
  120. for (my $index = 0; $index < @prompts; ++$index) {
  121. my $prompt = $prompts[$index];
  122. my $defaultans = $self->{defaultAns}($self, $index);
  123. my $ans;
  124. if ($self->isDisplayed() && !$promtpt->[2]) {
  125. $ans = $self->{manager}->showPrompt($prompt->[0], $defaultans, $prompt->[1]);
  126. } else {
  127. $ans = $defaultans;
  128. }
  129. # see if this is the special BACK response, and finish if so
  130. if ($self->{"manager"}->isBack($ans)) {
  131. $resp = $DialogManager::BACK;
  132. last;
  133. }
  134. # figure out what action to take based on the users response
  135. # this will set values in the setup info file
  136. # this will also validate input, and display errors if the
  137. # input is not correct - in that case, the resp will be
  138. # SAME to reprompt, or ERR if unrecoverable
  139. # NOTE: user cannot BACK from prompt to prompt - BACK
  140. # always means BACK to the previous dialog
  141. $resp = $self->{handleResp}($self, $ans, $index);
  142. if ($resp == $DialogManager::SAME) {
  143. if (!$self->isDisplayed()) {
  144. $self->{manager}->alert('dialog_use_different_type');
  145. $resp = $DialogManager::ERR;
  146. } else {
  147. $index--; # reprompt
  148. }
  149. } elsif ($resp == $DialogManager::ERR) {
  150. last;
  151. }
  152. }
  153. return $resp;
  154. }
  155. package DialogYesNo;
  156. @ISA = qw(Dialog);
  157. sub new {
  158. my $type = shift;
  159. my $setuptype = shift;
  160. my $text = shift;
  161. my $defaultIsYes = shift;
  162. my $handler = shift || \&handleResponse;
  163. my $prompt = shift || ['prompt_yes_no'];
  164. my $self = Dialog->new($setuptype, $text,
  165. \&defaultAns, $handler, $prompt);
  166. $self->{defaultIsYes} = $defaultIsYes;
  167. $self = bless $self, $type;
  168. return $self;
  169. }
  170. sub setDefaultYes {
  171. my $self = shift;
  172. $self->{default} = $self->{"manager"}->getText("yes");
  173. }
  174. sub setDefaultNo {
  175. my $self = shift;
  176. $self->{default} = $self->{"manager"}->getText("no");
  177. }
  178. sub defaultAns {
  179. my $self = shift;
  180. if (exists($self->{ans})) {
  181. return $self->{ans};
  182. }
  183. if (!exists($self->{default})) {
  184. my $isyes;
  185. if (ref($self->{defaultIsYes}) eq 'CODE') {
  186. $isyes = &{$self->{defaultIsYes}}($self);
  187. } else {
  188. $isyes = $self->{defaultIsYes};
  189. }
  190. if ($isyes) {
  191. $self->{default} = $self->{"manager"}->getText("yes");
  192. } else {
  193. $self->{default} = $self->{"manager"}->getText("no");
  194. }
  195. }
  196. return $self->{default};
  197. }
  198. sub isYes {
  199. my $self = shift;
  200. return $self->{ans} eq $self->{"manager"}->getText("yes");
  201. }
  202. sub handleResponse {
  203. my $self = shift;
  204. my $ans = shift;
  205. my $resp = $DialogManager::SAME;
  206. my $yes = $self->{"manager"}->getText("yes");
  207. my $nno = $self->{"manager"}->getText("no");
  208. # the regexp allows us to use y or ye or yes for "yes"
  209. if ($nno =~ /^$ans/i) {
  210. $resp = $DialogManager::NEXT;
  211. $self->{ans} = $nno;
  212. } elsif ($yes =~ /^$ans/i) {
  213. $resp = $DialogManager::NEXT;
  214. $self->{ans} = $yes;
  215. } else {
  216. $self->{"manager"}->alert("yes_no_error");
  217. }
  218. return $resp;
  219. }
  220. #############################################################################
  221. # Mandatory TRUE return value.
  222. #
  223. 1;