00001 // column_definition.h -*-c++-*- 00002 // 00003 // Copyright 2000, 2005, 2007 Daniel Burrows 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; see the file COPYING. If not, write to 00017 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 // Boston, MA 02111-1307, USA. 00019 // 00020 // This routine provides a general interface for parsing configuration data 00021 // about a column format and later instantiating that information. The caller 00022 // has to provide some information, in the form of tables and callbacks, that's 00023 // used to do the actual formatting. (the callbacks are actually classes, 00024 // since we need closureish behavior and classes are the best way to hack that 00025 // into C++) 00026 // 00027 // Originally arbitrary strings could be used to represent column information. 00028 // This was cute and readable, but not very flexible. So I've switched to a 00029 // "printf" style; the major reason is that this allows arbitrary strings to 00030 // be embedded in the format. This also means that the "padding" parmeters 00031 // that I used before are no longer necessary, and eliminates various nasty 00032 // hacks. 00033 // 00034 // Column types are integers; -1 is reserved for internal use. Column types 00035 // can take arguments (although this isn't implemented yet, it's used 00036 // internally for the "literal" column type) 00037 00038 #ifndef COLUMN_DEFINITION_H 00039 #define COLUMN_DEFINITION_H 00040 00041 #include <list> 00042 #include <string> 00043 00044 #include <cwidget/generic/util/eassert.h> 00045 00046 #include <cwidget/columnify.h> 00047 00048 namespace cwidget 00049 { 00050 namespace config 00051 { 00053 struct column_type_defaults 00054 { 00055 unsigned int width; 00056 bool expand, shrink; 00057 }; 00058 00060 class column_parameters 00061 { 00062 public: 00063 virtual int param_count()=0; 00064 virtual std::wstring get_param(int n)=0; 00065 00066 virtual ~column_parameters(); 00067 }; 00068 00070 class empty_column_parameters : public column_parameters 00071 { 00072 public: 00073 int param_count(); 00074 std::wstring get_param(int n); 00075 }; 00076 00078 struct column_definition 00079 { 00080 // A literal column is taken from a literal string passed as a 00081 // parameter. A generated one is created by calling a virtual 00082 // method. A parameterized column is taken from a column_parameters 00083 // object passed into the layout method. 00084 enum column_type {COLUMN_LITERAL, COLUMN_GENERATED, COLUMN_PARAM}; 00085 column_type type; 00086 00087 // For parametric columns, this is the parameter number; 00088 // for generated ones, it's the type of column: 00089 int ival; 00090 00091 // For literal columns only: 00092 std::wstring arg; 00093 00094 // For generated or parametric columns: 00095 unsigned int width; 00096 bool expand:1, shrink:1; 00097 00098 // For generated or parametric columns. If \b true, "width" 00099 // will be ignored and the true width of the incoming string will 00100 // be given to the layout algorithm. 00101 bool dynamic_size:1; 00102 00103 column_definition(const std::wstring &_arg, bool _expand, bool _shrink) 00104 :type(COLUMN_LITERAL), arg(_arg), expand(_expand), shrink(_shrink) 00105 { 00106 } 00107 00108 column_definition(column_type _type, 00109 int _ival, int _width, bool _expand, bool _shrink, 00110 bool _dynamic_size) 00111 :type(_type), ival(_ival), width(_width), 00112 expand(_expand), shrink(_shrink), dynamic_size(_dynamic_size) 00113 { 00114 eassert(_width>=0); 00115 } 00116 }; 00117 00118 typedef std::list<column_definition> column_definition_list; 00119 00120 typedef int (*column_parser_func)(char id); 00121 00122 class column_generator 00123 // Stores the information needed to parse and then generate columns. 00124 { 00125 column_definition_list columns; 00126 public: 00127 virtual column_disposition setup_column(int type)=0; 00128 // Sets up a column of the given type (the width field may be overridden?) 00129 00130 column_generator(const column_definition_list &_columns) 00131 :columns(_columns) {} 00132 00133 virtual ~column_generator(); 00134 00135 std::wstring layout_columns(unsigned int width, 00136 column_parameters &p); 00137 // Lays out the columns into columns. 00138 }; 00139 00140 column_definition_list *parse_columns(std::wstring config, 00141 column_parser_func parser, 00142 column_type_defaults *defaults); 00143 // Allocates the array itself; the caller must delete[] it. 00144 } 00145 } 00146 00147 #endif