libzypp 17.37.17
promptoptions.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9
10#include "promptoptions.h"
11
13#include <zypp/base/Logger.h>
14#include <zypp/base/String.h>
15
16namespace 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
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}
unsigned _default
index of the default option
const StrVector & options() const
bool isYesNoPrompt() const
ColorString optionString() const
Option string (may have embedded color codes)
int _shown_count
Number of options to show (the rest will still be available and visible through '?
std::vector< int > getReplyMatches(const std::string &reply_r) const
Return the indices of option string matches (lowercase/prefix or NUM).
std::string replyMatchesStr(const std::vector< int > &matches_r) const
The returned reply matches as '(,)' list.
PromptOptions()
Default c-tor.
StrVector _opt_help
help strings corresponding to options
bool isDisabled(unsigned opt) const
StrVector _options
option strings
std::vector< std::string > StrVector
void setOptionHelp(unsigned opt, const std::string &help_str)
void setOptions(StrVector options_r, unsigned defaultOpt_r)
Colored string if do_colors.
Definition ansi.h:497
String related utilities and Regular expression matching.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1097
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition String.cc:180
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition String.h:602
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
#define _(MSG)
Definition Gettext.h:39
#define WAR
Definition Logger.h:101
#define INT
Definition Logger.h:104