COOPY » Guide
version 0.6.5
|
00001 #ifndef COOPY_MERGEOUTPUTFILTER 00002 #define COOPY_MERGEOUTPUTFILTER 00003 00004 #include <coopy/MergeOutput.h> 00005 00006 #include <string> 00007 #include <list> 00008 #include <map> 00009 00010 namespace coopy { 00011 namespace cmp { 00012 class MergeOutputFilter; 00013 class SheetUnit; 00014 class RowUnit; 00015 } 00016 } 00017 00018 class coopy::cmp::SheetUnit { 00019 public: 00020 std::string sheet_name; 00021 NameChange name0, name1; 00022 bool have_name0, have_name1; 00023 std::list<OrderChange> orders; 00024 std::list<PoolChange> pools; 00025 //std::list<RowUnit *> rows; 00026 int row_count; 00027 00028 SheetUnit() { 00029 have_name0 = have_name1 = false; 00030 row_count = 0; 00031 } 00032 00033 SheetUnit(const std::string& name) : sheet_name(name) { 00034 have_name0 = have_name1 = false; 00035 row_count = 0; 00036 } 00037 }; 00038 00039 class coopy::cmp::RowUnit { 00040 public: 00041 std::string sheet_name; 00042 RowChange change; 00043 00044 RowUnit(const std::string& sheet_name, const RowChange& change) : 00045 sheet_name(sheet_name), 00046 change(change) { 00047 } 00048 }; 00049 00050 /* 00051 changeConfig: pass through 00052 changePool, changeColumn, changeName: cache verbatim per sheet 00053 order - changename1 changecolumns changename2 changepools 00054 changeRow: stack + release 00055 */ 00056 class coopy::cmp::MergeOutputFilter : public MergeOutput { 00057 private: 00058 std::string sheet_name; 00059 std::string last_sheet_name; 00060 Patcher *chain; 00061 std::map<std::string,SheetUnit> sheet_units; 00062 std::list<RowUnit> rows; 00063 std::list<std::string> sheet_order; 00064 std::map<std::string, int> started_sheets; 00065 std::map<std::string, int> desired_sheets; 00066 bool active_pool; 00067 00068 SheetUnit& getSheetUnit() { 00069 std::map<std::string,SheetUnit>::iterator it = sheet_units.find(sheet_name); 00070 if (it!=sheet_units.end()) { 00071 return it->second; 00072 } 00073 sheet_order.push_back(sheet_name); 00074 return sheet_units[sheet_name] = SheetUnit(sheet_name); 00075 } 00076 00077 public: 00078 MergeOutputFilter(Patcher *next) { 00079 chain = next; 00080 last_sheet_name = "[[ COOPY - SHEET NOT SET ]]"; 00081 active_pool = false; 00082 } 00083 00084 virtual bool setSheet(const char *name) { 00085 sheet_name = name; 00086 getSheetUnit(); 00087 return true; 00088 } 00089 00090 virtual bool changeConfig(const ConfigChange& change) { 00091 return chain->changeConfig(change); 00092 } 00093 00094 virtual bool changeColumn(const OrderChange& change) { 00095 if (!isActiveTable()) return false; 00096 getSheetUnit().orders.push_back(change); 00097 return true; 00098 } 00099 00100 virtual bool changeRow(const RowChange& change); 00101 00102 virtual bool changePool(const PoolChange& change) { 00103 if (!isActiveTable()) return false; 00104 if (!getFlags().canSchema()) return false; 00105 getSheetUnit().pools.push_back(change); 00106 applyPool(change); 00107 active_pool = true; 00108 return true; 00109 } 00110 00111 virtual bool changeName(const NameChange& change) { 00112 if (!isActiveTable()) return false; 00113 SheetUnit& unit = getSheetUnit(); 00114 if (change.final) { 00115 unit.name1 = change; 00116 unit.have_name1 = true; 00117 } else { 00118 unit.name0 = change; 00119 unit.have_name0 = true; 00120 } 00121 return true; 00122 } 00123 00124 virtual bool mergeStart(); 00125 00126 virtual bool mergeDone() { 00127 return true; 00128 } 00129 00130 virtual bool mergeAllDone(); 00131 00132 bool emitPreamble(const SheetUnit& preamble); 00133 00134 bool emitPreambleIfNeeded(const SheetUnit& preamble); 00135 00136 bool emitRow(const RowUnit& row); 00137 00138 bool isActiveTable() { 00139 if (desired_sheets.size()==0) return true; 00140 return desired_sheets.find(sheet_name)!=desired_sheets.end(); 00141 } 00142 00143 virtual bool wantDiff() { return true; } 00144 00145 virtual void setConflicted() { 00146 chain->setConflicted(); 00147 } 00148 00149 bool isConflicted() const { 00150 return chain->isConflicted(); 00151 } 00152 00153 virtual bool wantLinks() { 00154 if (chain) return chain->wantLinks(); 00155 return false; 00156 } 00157 00158 virtual bool declareLink(const LinkDeclare& decl) { 00159 if (chain) return chain->declareLink(decl); 00160 return false; 00161 } 00162 }; 00163 00164 #endif