14#ifndef ZYPP_TUI_TABULE_H 
   15#define ZYPP_TUI_TABULE_H 
   25#include <boost/any.hpp> 
   37const char * 
asYesNo( 
bool val_r );  
 
   40using SolvableCSI = std::pair<zypp::sat::Solvable, zypp::ui::Selectable::picklist_size_type>;
 
   50    T l = boost::any_cast<T>(l_r);
 
   51    T r = boost::any_cast<T>(r_r);
 
   52    return ( l < r ? -1 : l > r ?  1 : 0 );
 
 
   61    if ( l.first == r.first )
 
   64    int cmp = l.first.name().compare( r.first.name() );
 
   68    cmp = l.first.kind().compare( r.first.kind() );
 
   72    if ( l.second == r.second )
 
   74    return ( l.second < r.second ? -1 : 1 );    
 
 
 
  103  template<
class Tif_,
class Telse_>
 
  106    ColumnIf( 
bool condition_r, std::function<Tif_()> if_r,  std::function<Telse_()> else_r )
 
  107    { 
if ( condition_r ) 
_if = std::move(if_r); 
else _else = std::move(else_r); }
 
 
  108    std::function<Tif_()> 
_if;
 
 
  115    ColumnIf( 
bool condition_r, std::function<Tif_()> if_r,  std::function<Tif_()> else_r )
 
  116    : 
_ifelse { condition_r ? 
std::move(if_r) : 
std::move(else_r) }
 
 
  118    ColumnIf( 
bool condition_r, std::function<Tif_()> && if_r )
 
  119    { 
if ( condition_r ) 
_ifelse = std::move(if_r); }
 
 
 
 
  140template<
class Tif_, 
class Telse_>
 
  142{ 
return { condition_r, std::forward<Tif_>(if_r), std::forward<Telse_>(else_r) }; }
 
 
  146{ 
return { condition_r, std::forward<Tif_>(if_r) }; }
 
 
  169  std::ostream & 
dumpDetails( std::ostream & stream, 
const Table & parent ) 
const;
 
  215  std::ostream & 
dumbDumpTo( std::ostream & stream ) 
const;
 
  217  std::ostream & 
dumpTo( std::ostream & stream, 
const Table & parent ) 
const;
 
 
  258{ 
return std::move( tr << std::forward<Tp_>(val) ); }
 
 
  268{ 
if ( val._if ) tr.
add( val._if() ); 
else if ( val._else ) tr.
add( val._else() ); 
return tr; }
 
 
  272{ 
if ( val._ifelse ) tr.
add( val._ifelse() ); 
return tr; }
 
 
  275{ 
if ( val._ifelse ) tr.
add( val._ifelse() ); 
return tr; }
 
 
  278{ 
if ( val._ifelse ) tr.
add( val._ifelse() ); 
return tr; }
 
 
  300    std::set<unsigned> ret;
 
  301    for ( 
const auto & [c,s] : 
_cstyle ) {
 
  302      if ( s == CStyle::Edition )
 
 
 
  315{ 
static_cast<TableRow&
>(th) << std::forward<Tp_>(val); 
return th; }
 
 
  319{ 
return std::move( th << std::forward<Tp_>(val) ); }
 
 
  328    for ( 
unsigned curr_column : by_columns_r ) {
 
 
  337      if ( (c = 
compCol( sortParam, a_r, b_r )) )
 
 
  346    const auto & [ byColumn, sortCI ] { sortParam_r };
 
  347    bool noL = byColumn >= a_r.
_columns.size();
 
  348    bool noR = byColumn >= b_r.
_columns.size();
 
  354        const boost::any &lUserData = a_r.
userData();
 
  355        const boost::any &rUserData = b_r.
userData();
 
  357        if ( lUserData.empty() && !rUserData.empty() )
 
  360        else if ( !lUserData.empty() && rUserData.empty() )
 
  363        else if ( lUserData.empty() && rUserData.empty() )
 
  366        else if ( lUserData.type() != rUserData.type() ) {
 
  369        } 
else if ( lUserData.type() == 
typeid(
SolvableCSI) ) {
 
  370          return simpleAnyTypeComp<SolvableCSI> ( lUserData, rUserData );
 
  372        } 
else if ( lUserData.type() == 
typeid(std::string) ) {
 
  373          return simpleAnyTypeComp<std::string>( lUserData, rUserData );
 
  375        } 
else if ( lUserData.type() == 
typeid(
unsigned) ) {
 
  376          return simpleAnyTypeComp<unsigned>( lUserData, rUserData );
 
  378        } 
else if ( lUserData.type() == 
typeid(
int) ) {
 
  379          return simpleAnyTypeComp<int>( lUserData, rUserData );
 
  384        return ( noL && ! noR ? -1 : ! noL && noR ?  1 : 0);
 
 
  390  static int defaultStrComp( 
bool ci_r, 
const std::string & lhs, 
const std::string & rhs );
 
 
  409  std::ostream & 
dumpTo( std::ostream & stream ) 
const;
 
  433  template<
class TCompare, std::enable_if_t<!std::is_
integral_v<TCompare>, 
int> = 0>
 
  434  void sort( TCompare && less_r )           { 
_rows.sort( std::forward<TCompare>(less_r) ); }
 
  437  void wrap( 
int force_break_after = -1 );
 
  451  void dumpRule( std::ostream & stream ) 
const;
 
 
  504  { th.
style( th.
cols(), obj._style ); 
return th << std::move(obj._header); }
 
  507  { 
return std::move( th << std::move(obj) ); }
 
  512{ 
return table.add( std::move(tr) ); }
 
 
  515{ 
return table.setHeader( std::move(tr) ); }
 
 
  519{ 
return table.dumpTo( stream ); }
 
 
  544  template <
class KeyType>
 
  548  template <
class KeyType, 
class ValueType>
 
  552  template <
class KeyType>
 
  558  template <
class ValueType>
 
  562  template <
class KeyType, 
class ValueType>
 
  568  template <
class KeyType, 
class Iterator_ >
 
  569  PropertyTable & 
add( 
const KeyType & key_r, Iterator_ begin_r, Iterator_ end_r, 
bool forceDetails_r = 
false  )
 
  573    if ( begin_r != end_r )
 
  576      Iterator_ first = begin_r++;
 
  577      if ( begin_r == end_r && ! forceDetails_r )
 
  582        while ( begin_r != end_r )
 
 
  596  template <
class KeyType, 
class ContainerType>
 
  597  PropertyTable & 
lst( 
const KeyType & key_r, 
const ContainerType & lst_r, 
bool forceDetails_r = 
false )
 
  598  { 
return add( key_r, lst_r.begin(), lst_r.end(), forceDetails_r ); }
 
 
  600  template <
class KeyType, 
class ValueType>
 
  601  PropertyTable & 
add( 
const KeyType & key_r, 
const std::set<ValueType> & lst_r, 
bool forceDetails_r = 
false  )
 
  602  { 
return lst( key_r, lst_r, forceDetails_r );  }
 
 
  603  template <
class KeyType, 
class ValueType>
 
  604  PropertyTable & 
add( 
const KeyType & key_r, 
const std::list<ValueType> & lst_r, 
bool forceDetails_r = 
false  )
 
  605  { 
return lst( key_r, lst_r, forceDetails_r );  }
 
 
  606  template <
class KeyType, 
class ValueType>
 
  607  PropertyTable & 
add( 
const KeyType & key_r, 
const std::vector<ValueType> & lst_r, 
bool forceDetails_r = 
false  )
 
  608  { 
return lst( key_r, lst_r, forceDetails_r ); }
 
 
  617      std::string & lastval( 
_table.rows().back().columns().back() );
 
 
  624  { 
return _table.rows().back(); }
 
 
 
PropertyTable & add(const KeyType &key_r, const std::set< ValueType > &lst_r, bool forceDetails_r=false)
std::string & lastValue()
PropertyTable & add(const KeyType &key_r, const ValueType &val_r)
PropertyTable & add(const KeyType &key_r, const std::vector< ValueType > &lst_r, bool forceDetails_r=false)
PropertyTable & addDetail(const KeyType &key_r, const ValueType &val_r)
PropertyTable & add(const KeyType &key_r, Iterator_ begin_r, Iterator_ end_r, bool forceDetails_r=false)
PropertyTable & lst(const KeyType &key_r, const ContainerType &lst_r, bool forceDetails_r=false)
PropertyTable & addDetail(const ValueType &val_r)
static const char * emptyListTag()
friend std::ostream & operator<<(std::ostream &str, const PropertyTable &obj)
PropertyTable & add(const KeyType &key_r)
PropertyTable & add(const KeyType &key_r, bool val_r)
PropertyTable & paint(ansi::Color color_r, bool cond_r=true)
PropertyTable & add(const KeyType &key_r, const std::list< ValueType > &lst_r, bool forceDetails_r=false)
TableRow & add(const Tp_ &val_r)
TableRow(ColorContext ctxt_r)
TableRow & add(std::string s)
container & columnsNoTr()
container _translatedColumns
std::vector< std::string > container
std::ostream & dumpDetails(std::ostream &stream, const Table &parent) const
TableRow & addDetail(std::string s)
const container & columnsNoTr() const
TableRow & addDetail(const Tp_ &val_r)
boost::any _userData
user defined sort index, e.g. if string values don't work due to coloring
TableRow(unsigned c, ColorContext ctxt_r)
TableRow & operator<<(TableRow &tr, Tp_ &&val)
Add colummn.
std::ostream & dumpTo(std::ostream &stream, const Table &parent) const
output with parent table attributes
std::ostream & dumbDumpTo(std::ostream &stream) const
tab separated output
void userData(const boost::any &n_r)
const boost::any & userData() const
TableRow()
Binary predicate for sorting.
const container & columns() const
void sort(std::list< unsigned > &&byColumns_r)
void dumpRule(std::ostream &stream) const
Table & setHeader(TableHeader tr)
void updateColWidths(const TableRow &tr) const
void sort(TCompare &&less_r)
Custom sort.
std::list< TableRow > container
const container & rows() const
std::ostream & dumpTo(std::ostream &stream) const
int _width
table width (columns)
void lineStyle(TableLineStyle st)
void wrap(int force_break_after=-1)
const TableHeader & header() const
unsigned defaultSortColumn() const
Get the default sort column or Unsorted (default)
std::vector< bool > _abbrev_col
whether to abbreviate the respective column if needed
std::vector< unsigned > _max_width
maximum width of respective columns
void sort(const std::list< unsigned > &byColumns_r)
TableLineStyle _style
table line drawing style
void margin(unsigned margin)
static constexpr unsigned Unsorted
Unsorted - pseudo sort column indicating not to sort.
void defaultSortColumn(unsigned byColumn_r)
Set a defaultSortColumn.
void sort(unsigned byColumn_r)
Sort by byColumn_r.
int _screen_width
amount of space we have to print this table
unsigned _max_col
maximum column index seen in this table
int _force_break_after
if _do_wrap is set, first break the table at this column; If negative, wrap as needed.
static constexpr unsigned UserData
UserData - sort column using a custom sort index.
zypp::DefaultIntegral< unsigned, Unsorted > _defaultSortColumn
unsigned _margin
left/right margin in number of spaces
bool _do_wrap
Whether to wrap the table if it exceeds _screen_width.
void allowAbbrev(unsigned column)
static TableLineStyle defaultStyle
void sort()
Sort by defaultSortColumn.
Colored string if do_colors.
std::string str() const
Return the colored string if do_colors.
Various ways to define ansi SGR sequences.
Integral type with defined initial value when default constructed.
Base class for Exception.
String related utilities and Regular expression matching.
int simpleAnyTypeComp< SolvableCSI >(const boost::any &l_r, const boost::any &r_r)
int simpleAnyTypeComp(const boost::any &l_r, const boost::any &r_r)
Default comparator for custom sort indices (std::compare semantic).
CStyle
Table column styles.
@ Edition
Editions with v-r setparator highlighted.
@ SortCi
String values to be sorted case insensitive.
const char * asYesNo(bool val_r)
auto ColumnIf(bool condition_r, Tif_ &&if_r, Telse_ &&else_r) -> ctcdetail::ColumnIf< decltype(if_r()), decltype(else_r())>
Conditional Table column factory.
TableLineStyle
table drawing style
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).
std::string numstring(char n, int w=0)
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
std::string asString(const Patch::Category &obj)
std::list< SortParam > _by_columns
std::tuple< unsigned, bool > SortParam
column and sortCI
int compCol(const SortParam &sortParam_r, const TableRow &a_r, const TableRow &b_r) const
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.
bool operator()(const TableRow &a_r, const TableRow &b_r) const
Less(const TableHeader &header_r, const std::list< unsigned > &by_columns_r)
ColumnIf(bool condition_r, std::function< Tif_()> if_r, std::function< Tif_()> else_r)
ColumnIf(bool condition_r, std::function< Tif_()> &&if_r)
std::function< Tif_()> _ifelse
Remember either _if or _else function.
ColumnIf(bool condition_r, std::function< Tif_()> if_r, std::function< Telse_()> else_r)
std::function< Telse_()> _else
std::function< Tif_()> _if
Table column style setter.
Column(std::string header_r, CStyle style_r=CStyle::Default)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.