libzypp  17.35.14
promptoptions.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 ----------------------------------------------------------------------*/
9 
10 #include "promptoptions.h"
11 
12 #include <zypp-core/base/Gettext.h>
13 #include <zypp/base/Logger.h>
14 #include <zypp/base/String.h>
15 
16 namespace ztui {
17 
18  // ----------------------------------------------------------------------------
19 
20  PromptOptions::PromptOptions( StrVector options_r, unsigned defaultOpt_r )
21  { setOptions( std::move(options_r), defaultOpt_r ); }
22 
23  PromptOptions::PromptOptions( const std::string & optionstr_r, unsigned defaultOpt_r )
24  { setOptions( optionstr_r, defaultOpt_r ); }
25 
26  // ----------------------------------------------------------------------------
27 
29  {}
30 
31  // ----------------------------------------------------------------------------
32 
33  void PromptOptions::setOptions( StrVector options_r, unsigned defaultOpt_r )
34  {
35  _options.swap( options_r );
36  if ( _options.size() <= defaultOpt_r )
37  {
38  INT << "Invalid default option index " << defaultOpt_r << std::endl;
39  _default = 0;
40  }
41  else
42  _default = defaultOpt_r;
43  }
44 
45  void PromptOptions::setOptions( const std::string & optionstr_r, unsigned defaultOpt_r )
46  {
48  zypp::str::split( optionstr_r, back_inserter(options), "/" );
49  setOptions( std::move(options), defaultOpt_r );
50  }
51 
53  {
54  bool hidden = false; // have enabled options not shown at the prompt (/...)?
55  unsigned shown = 0;
56  unsigned showmax = ( _shown_count < 0 ? _options.size() : (unsigned)_shown_count );
57 
58  std::ostringstream str;
59  str << "[";
60 
61  const char * slash = ""; // "/" after the 1st option
62  for ( unsigned idx = 0; idx < _options.size(); ++idx )
63  {
64  if ( isDisabled(idx) )
65  continue;
66 
67  if ( shown < showmax )
68  {
69  str << slash << ( ColorContext::PROMPT_OPTION << _options[idx] );
70  if ( !shown ) slash = "/";
71  ++shown;
72  }
73  else
74  {
75  hidden = true;
76  break; // don't mind how many
77  }
78  }
79 
80  if ( hidden || !_opt_help.empty() )
81  {
82  str << slash << ( hidden ? "..." : "" ) << ( ColorContext::PROMPT_OPTION << "?" );
83  if ( hidden )
84  // translators: Press '?' to see all options embedded in this prompt: "Continue? [y/n/? shows all options] (y):"
85  str << " " << _("shows all options");
86  }
87 
88  str << "]";
89 
90  if ( !_options.empty() )
91  str << " (" << ( ColorContext::PROMPT_OPTION << _options[_default] ) << ")";
92 
93  return ColorString( str.str() );
94  }
95 
96 
97  void PromptOptions::setOptionHelp( unsigned opt, const std::string & help_str )
98  {
99  if ( help_str.empty() )
100  return;
101 
102  if ( opt >= _options.size() )
103  {
104  WAR << "attempt to set option help for non-existing option."
105  << " text: " << help_str << std::endl;
106  return;
107  }
108 
109  if ( opt >= _opt_help.capacity() )
110  _opt_help.reserve( _options.size() );
111  if ( opt >= _opt_help.size( ))
112  _opt_help.resize( _options.size() );
113 
114  _opt_help[opt] = help_str;
115  }
116 
117  std::vector<int> PromptOptions::getReplyMatches( const std::string & reply_r ) const
118  {
119  std::vector<int> ret;
120 
121  // #NUM ? (direct index into option vector)
122  if ( reply_r[0] == '#' && reply_r[1] != '\0' )
123  {
124  unsigned num = 0; // -1 : if no match
125  for ( const char * cp = reply_r.c_str()+1; *cp; ++cp )
126  {
127  if ( '0' <= *cp && *cp <= '9' )
128  {
129  num *= 10;
130  num += (*cp-'0');
131  }
132  else
133  {
134  num = unsigned(-1);
135  break;
136  }
137  }
138 
139  if ( num != unsigned(-1) )
140  {
141  // userland counting! #1 is the 1st (enabled) option (#0 will never match)
142  if ( num != 0 )
143  {
144  for ( unsigned i = 0; i < _options.size(); ++i )
145  {
146  if ( isDisabled(i) )
147  continue;
148 
149  if ( --num == 0 )
150  {
151  ret.push_back( i );
152  break;
153  }
154  }
155  }
156  return ret; // a match - good or bad - will be eaten
157  }
158  // no match falls through....
159  }
160 
161  const std::string & lreply { zypp::str::toLower( reply_r ) };
162  for ( unsigned i = 0; i < _options.size(); ++i )
163  {
164  if ( isDisabled(i) )
165  continue;
166 
167  const std::string & lopt { zypp::str::toLower( _options[i] ) };
168 
169  if ( lopt == lreply ) { // prefer an exact match ("1/11")
170  ret.clear();
171  ret.push_back( i );
172  break;
173  }
174  else if ( zypp::str::hasPrefix( lopt, lreply ) )
175  ret.push_back( i );
176  }
177 
178  return ret;
179  }
180 
181  std::string PromptOptions::replyMatchesStr( const std::vector<int> & matches_r ) const
182  {
184  const char * sep = "("; // "," after the 1st option
185  for ( unsigned idx : matches_r )
186  {
187  str << sep << _options[idx];
188  if ( *sep != ',' ) sep =",";
189  }
190  return str << ")";
191  }
192 
194  { return _options.size() == 2 && _options[0] == _("yes") && _options[1] == _("no"); }
195 
196 }
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:178
int _shown_count
Number of options to show (the rest will still be available and visible through &#39;?&#39; help).
std::vector< int > getReplyMatches(const std::string &reply_r) const
Return the indices of option string matches (lowercase/prefix or #NUM).
Colored string if do_colors.
Definition: ansi.h:496
#define _(MSG)
Definition: Gettext.h:39
bool isYesNoPrompt() const
#define INT
Definition: Logger.h:104
String related utilities and Regular expression matching.
PromptOptions()
Default c-tor.
Definition: promptoptions.h:46
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:531
const StrVector & options() const
Definition: promptoptions.h:64
unsigned _default
index of the default option
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:211
#define WAR
Definition: Logger.h:101
bool isDisabled(unsigned opt) const
Definition: promptoptions.h:82
void setOptionHelp(unsigned opt, const std::string &help_str)
std::string replyMatchesStr(const std::vector< int > &matches_r) const
The returned reply matches as &#39;(,)&#39; list.
ColorString optionString() const
Option string (may have embedded color codes)
StrVector _opt_help
help strings corresponding to options
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1027
void setOptions(StrVector options_r, unsigned defaultOpt_r)
std::vector< std::string > StrVector
Definition: promptoptions.h:41
StrVector _options
option strings