14 #ifndef ZYPP_TUI_TABULE_H 15 #define ZYPP_TUI_TABULE_H 25 #include <boost/any.hpp> 38 inline const char *
asYesNo(
bool val_r ) {
return val_r ?
_(
"Yes") :
_(
"No"); }
41 using SolvableCSI = std::pair<zypp::sat::Solvable, zypp::ui::Selectable::picklist_size_type>;
51 T l = boost::any_cast<T>(l_r);
52 T r = boost::any_cast<T>(r_r);
53 return ( l < r ? -1 : l > r ? 1 : 0 );
62 if ( l.first == r.first )
65 int cmp = l.first.name().compare( r.first.name() );
69 cmp = l.first.kind().compare( r.first.kind() );
73 if ( l.second == r.second )
75 return ( l.second < r.second ? -1 : 1 );
104 template<
class Tif_,
class Telse_>
107 ColumnIf(
bool condition_r, std::function<Tif_()> if_r, std::function<Telse_()> else_r )
108 {
if ( condition_r )
_if = std::move(if_r);
else _else = std::move(else_r); }
109 std::function<Tif_()>
_if;
116 ColumnIf(
bool condition_r, std::function<Tif_()> if_r, std::function<Tif_()> else_r )
117 : _ifelse { condition_r ? std::move(if_r) : std::move(else_r) }
119 ColumnIf(
bool condition_r, std::function<Tif_()> && if_r )
120 {
if ( condition_r ) _ifelse = std::move(if_r); }
141 template<
class Tif_,
class Telse_>
143 {
return { condition_r, std::forward<Tif_>(if_r), std::forward<Telse_>(else_r) }; }
147 {
return { condition_r, std::forward<Tif_>(if_r) }; }
170 std::ostream &
dumpDetails( std::ostream & stream,
const Table & parent )
const;
216 std::ostream &
dumbDumpTo( std::ostream & stream )
const;
218 std::ostream &
dumpTo( std::ostream & stream,
const Table & parent )
const;
259 {
return std::move( tr << std::forward<Tp_>(val) ); }
262 template<
class Tif_,
class Telse_>
TableRow & operator<<( TableRow & tr, const ctcdetail::ColumnIf<Tif_,Telse_> & val )
263 {
if ( val._if ) tr.
add( val._if() );
else if ( val._else ) tr.
add( val._else() );
return tr; }
265 template<
class Tif_,
class Telse_>
TableRow & operator<<( TableRow & tr, ctcdetail::ColumnIf<Tif_,Telse_> & val )
266 {
if ( val._if ) tr.
add( val._if() );
else if ( val._else ) tr.
add( val._else() );
return tr; }
268 template<
class Tif_,
class Telse_>
TableRow & operator<<( TableRow & tr, ctcdetail::ColumnIf<Tif_,Telse_> && val )
269 {
if ( val._if ) tr.
add( val._if() );
else if ( val._else ) tr.
add( val._else() );
return tr; }
272 template<
class Tif_>
TableRow & operator<<( TableRow & tr, const ctcdetail::ColumnIf<Tif_,Tif_> & val )
273 {
if ( val._ifelse ) tr.
add( val._ifelse() );
return tr; }
275 template<
class Tif_>
TableRow & operator<<( TableRow & tr, ctcdetail::ColumnIf<Tif_,Tif_> & val )
276 {
if ( val._ifelse ) tr.
add( val._ifelse() );
return tr; }
278 template<
class Tif_>
TableRow & operator<<( TableRow & tr, ctcdetail::ColumnIf<Tif_,Tif_> && val )
279 {
if ( val._ifelse ) tr.
add( val._ifelse() );
return tr; }
301 std::set<unsigned> ret;
302 for (
const auto & [c,s] :
_cstyle ) {
316 {
static_cast<TableRow&
>(th) << std::forward<Tp_>(val);
return th; }
320 {
return std::move( th << std::forward<Tp_>(val) ); }
329 for (
unsigned curr_column : by_columns_r ) {
338 if ( (c =
compCol( sortParam, a_r, b_r )) )
347 const auto & [ byColumn, sortCI ] { sortParam_r };
348 bool noL = byColumn >= a_r.
_columns.size();
349 bool noR = byColumn >= b_r.
_columns.size();
355 const boost::any &lUserData = a_r.
userData();
356 const boost::any &rUserData = b_r.
userData();
358 if ( lUserData.empty() && !rUserData.empty() )
361 else if ( !lUserData.empty() && rUserData.empty() )
364 else if ( lUserData.empty() && rUserData.empty() )
367 else if ( lUserData.type() != rUserData.type() ) {
370 }
else if ( lUserData.type() ==
typeid(
SolvableCSI) ) {
373 }
else if ( lUserData.type() ==
typeid(std::string) ) {
374 return simpleAnyTypeComp<std::string>( lUserData, rUserData );
376 }
else if ( lUserData.type() ==
typeid(unsigned) ) {
377 return simpleAnyTypeComp<unsigned>( lUserData, rUserData );
379 }
else if ( lUserData.type() ==
typeid(int) ) {
380 return simpleAnyTypeComp<int>( lUserData, rUserData );
385 return ( noL && ! noR ? -1 : ! noL && noR ? 1 : 0);
391 static int defaultStrComp(
bool ci_r,
const std::string & lhs,
const std::string & rhs );
410 std::ostream &
dumpTo( std::ostream & stream )
const;
434 template<
class TCompare, std::enable_if_t<!std::is_
integral_v<TCompare>,
int> = 0>
435 void sort( TCompare && less_r ) {
_rows.sort( std::forward<TCompare>(less_r) ); }
438 void wrap(
int force_break_after = -1 );
452 void dumpRule( std::ostream & stream )
const;
505 { th.
style( th.
cols(), obj._style );
return th << std::move(obj._header); }
508 {
return std::move( th << std::move(obj) ); }
513 {
return table.
add( std::move(tr) ); }
516 {
return table.
setHeader( std::move(tr) ); }
520 {
return table.
dumpTo( stream ); }
545 template <
class KeyType>
549 template <
class KeyType,
class ValueType>
553 template <
class KeyType>
559 template <
class ValueType>
563 template <
class KeyType,
class ValueType>
569 template <
class KeyType,
class Iterator_ >
570 PropertyTable &
add(
const KeyType & key_r, Iterator_ begin_r, Iterator_ end_r,
bool forceDetails_r =
false )
574 if ( begin_r != end_r )
577 Iterator_ first = begin_r++;
578 if ( begin_r == end_r && ! forceDetails_r )
583 while ( begin_r != end_r )
597 template <
class KeyType,
class ContainerType>
598 PropertyTable &
lst(
const KeyType & key_r,
const ContainerType & lst_r,
bool forceDetails_r =
false )
599 {
return add( key_r, lst_r.begin(), lst_r.end(), forceDetails_r ); }
601 template <
class KeyType,
class ValueType>
602 PropertyTable &
add(
const KeyType & key_r,
const std::set<ValueType> & lst_r,
bool forceDetails_r =
false )
603 {
return lst( key_r, lst_r, forceDetails_r ); }
604 template <
class KeyType,
class ValueType>
605 PropertyTable &
add(
const KeyType & key_r,
const std::list<ValueType> & lst_r,
bool forceDetails_r =
false )
606 {
return lst( key_r, lst_r, forceDetails_r ); }
607 template <
class KeyType,
class ValueType>
608 PropertyTable &
add(
const KeyType & key_r,
const std::vector<ValueType> & lst_r,
bool forceDetails_r =
false )
609 {
return lst( key_r, lst_r, forceDetails_r ); }
618 std::string & lastval(
_table.
rows().back().columns().back() );
void defaultSortColumn(unsigned byColumn_r)
Set a defaultSortColumn.
std::string asString(const Patch::Category &obj)
TableRow & add(std::string s)
void userData(const boost::any &n_r)
std::tuple< unsigned, bool > SortParam
column and sortCI
int _width
table width (columns)
std::function< Tif_()> _ifelse
Aligned key/value with multiline support Key : value 1 LongKey : value 2 Multiline : line 1 line 2 Ne...
static int defaultStrComp(bool ci_r, const std::string &lhs, const std::string &rhs)
Natural('sort -V' like) [case insensitive] compare ignoring ANSI SGR chars.
std::ostream & dumbDumpTo(std::ostream &stream) const
tab separated output
Colored string if do_colors.
void margin(unsigned margin)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
PropertyTable & add(const KeyType &key_r, bool val_r)
PropertyTable & lst(const KeyType &key_r, const ContainerType &lst_r, bool forceDetails_r=false)
TableHeader && operator<<(TableHeader &&th, Column &&obj)
Column(std::string header_r, CStyle style_r=CStyle::Default)
void allowAbbrev(unsigned column)
std::vector< bool > _abbrev_col
whether to abbreviate the respective column if needed
PropertyTable & add(const KeyType &key_r, const std::set< ValueType > &lst_r, bool forceDetails_r=false)
String related utilities and Regular expression matching.
TableLineStyle
table drawing style
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
std::list< SortParam > _by_columns
std::list< TableRow > container
const container & rows() const
int compCol(const SortParam &sortParam_r, const TableRow &a_r, const TableRow &b_r) const
int _screen_width
amount of space we have to print this table
PropertyTable & add(const KeyType &key_r, const std::vector< ValueType > &lst_r, bool forceDetails_r=false)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool _do_wrap
Whether to wrap the table if it exceeds _screen_width.
PropertyTable & paint(ansi::Color color_r, bool cond_r=true)
int simpleAnyTypeComp(const boost::any &l_r, const boost::any &r_r)
Default comparator for custom sort indices (std::compare semantic).
TableLineStyle _style
table line drawing style
const container & columnsNoTr() const
std::string str() const
Return the colored string if do_colors.
PropertyTable & add(const KeyType &key_r)
void sort()
Sort by defaultSortColumn.
Table column style setter.
std::function< Telse_()> _else
std::ostream & dumpTo(std::ostream &stream) const
unsigned defaultSortColumn() const
Get the default sort column or Unsorted (default)
const container & columns() const
int _force_break_after
if _do_wrap is set, first break the table at this column; If negative, wrap as needed.
const boost::any & userData() const
TableRow(unsigned c, ColorContext ctxt_r)
Various ways to define ansi SGR sequences.
std::vector< std::string > container
std::string & lastValue()
PropertyTable & addDetail(const ValueType &val_r)
unsigned _margin
left/right margin in number of spaces
PropertyTable & addDetail(const KeyType &key_r, const ValueType &val_r)
container _translatedColumns
std::vector< unsigned > _max_width
maximum width of respective columns
Table & setHeader(TableHeader tr)
std::ostream & dumpDetails(std::ostream &stream, const Table &parent) const
void updateColWidths(const TableRow &tr) const
TableRow && operator<<(TableRow &&tr, Tp_ &&val)
static const char * emptyListTag()
void sort(std::list< unsigned > &&byColumns_r)
std::function< Tif_()> _if
CStyle
Table column styles.
std::ostream & dumpTo(std::ostream &stream, const Table &parent) const
output with parent table attributes
void sort(TCompare &&less_r)
Custom sort.
std::string numstring(char n, int w=0)
boost::any _userData
user defined sort index, e.g. if string values don't work due to coloring
Editions with v-r setparator highlighted.
void lineStyle(TableLineStyle st)
Less(const TableHeader &header_r, const std::list< unsigned > &by_columns_r)
bool operator()(const TableRow &a_r, const TableRow &b_r) const
container & columnsNoTr()
zypp::DefaultIntegral< unsigned, Unsorted > _defaultSortColumn
ColumnIf(bool condition_r, std::function< Tif_()> if_r, std::function< Telse_()> else_r)
const TableHeader & header() const
PropertyTable & add(const KeyType &key_r, const std::list< ValueType > &lst_r, bool forceDetails_r=false)
TableRow()
Binary predicate for sorting.
String values to be sorted case insensitive.
Base class for Exception.
unsigned _max_col
maximum column index seen in this table
PropertyTable & add(const KeyType &key_r, const ValueType &val_r)
TableRow & addDetail(std::string s)
TableRow(ColorContext ctxt_r)
TableHeader & operator<<(TableHeader &th, Column &&obj)
TableRow & operator<<(TableRow &tr, Tp_ &&val)
void dumpRule(std::ostream &stream) const
TableRow & add(const Tp_ &val_r)
TableRow & addDetail(const Tp_ &val_r)
int simpleAnyTypeComp< SolvableCSI >(const boost::any &l_r, const boost::any &r_r)
static constexpr unsigned UserData
UserData - sort column using a custom sort index.
static constexpr unsigned Unsorted
Unsorted - pseudo sort column indicating not to sort.
friend std::ostream & operator<<(std::ostream &str, const PropertyTable &obj)
void sort(unsigned byColumn_r)
Sort by byColumn_r.
Remember either _if or _else function.
void wrap(int force_break_after=-1)
static TableLineStyle defaultStyle
ColumnIf(bool condition_r, std::function< Tif_()> if_r, std::function< Tif_()> else_r)
std::pair< zypp::sat::Solvable, zypp::ui::Selectable::picklist_size_type > SolvableCSI
Custom sort index type for table rows representing solvables (like detailed search results)...
auto ColumnIf(bool condition_r, Tif_ &&if_r, Telse_ &&else_r) -> ctcdetail::ColumnIf< decltype(if_r()), decltype(else_r())>
Conditional Table column factory.
const char * asYesNo(bool val_r)
PropertyTable & add(const KeyType &key_r, Iterator_ begin_r, Iterator_ end_r, bool forceDetails_r=false)
ColumnIf(bool condition_r, std::function< Tif_()> &&if_r)
void sort(const std::list< unsigned > &byColumns_r)