// $Id: const_contained_iterator.cc,v 1.40 2002/12/19 10:38:23 christof Exp $ /* glade--: C++ frontend for glade (Gtk+ User Interface Builder) * Copyright (C) 1998 Christof Petig * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Widget.hh" #include #include "writers/WriterBase.hh" #include "Widget_type.hh" #ifdef WIDGET_CCI_DEBUG_ON_DEMAND #define DEBUG(x) ({ if ((Configuration.debug && Configuration.verbose>1) || print_debug) { x; } }) #else //#define DEBUG(x) x #define DEBUG(x) #endif #define PARANOIA #ifdef WIDGET_CCI_DEBUG_ON_DEMAND std::ostream &operator<<(std::ostream &o,Subwidget sub) { switch(sub) { case no_Subwidgets: return o << "no_Subwidgets"; case not_Subwidget: return o << "not_Subwidget"; case is_Subwidget_only: return o << "is_Subwidget_only"; case is_Subwidget_all: return o << "is_Subwidget_all"; case is_Subwidget: return o << "is_Subwidget"; case SW_Unknown: return o << "SW_Unknown"; default: return o << "?"; } } std::ostream &operator<<(std::ostream &o,const Widget::const_contained_iterator::stack &sub) { if (sub.first==sub.second) o << '$'; else o << Widget(*(sub.first)).Name(); return o << ',' << Widget(*(sub.third)).Name() << ',' << sub.fourth << ',' << Widget(*(sub.fifth)).Name() << ',' << sub.sixth->Type(); } std::ostream &operator<<(std::ostream &o,const std::list &l) { for (std::list::const_iterator i=l.begin(); i!=l.end();++i) o << '{' << (*i) << "}, "; return o; } #endif void Widget::const_contained_iterator::dive() { if (Widget(*ti_w).getBoolProperty(CXX_SEPERATE_CLASS)) { DEBUG(std::cerr << "dive(): stopped at topmost seperate class " << Widget(*ti).Name() << '\n'); return; } #ifdef PARANOIA if (Widget(*ti_w).getBoolProperty(CXX_SEPERATE_FILE)) std::cerr << "Code error\n"; #endif while (1) // dive into tree, remember parents { T child=find(ti_w->begin(),ti_w->end(),type); if (child==ti_w->end() || !need_recurse()) { DEBUG(std::cerr << "stopped diving sub="<end(); if (sub2==no_Subwidgets || sub2==not_Subwidget) { internal_determining_widget=parent; DEBUG(std::cerr << "set internal_determining_widget="<Type()=="widget" || i->Type()=="placeholder") ti_w=i; } if (ti_w==ti) std::cerr << "Oops. Unexpected: no widget as child\n"; } // end=parent->end(); DEBUG(std::cerr << "@" << Widget(*child).Name() << " new_sub=" << sub << " parent="<end()), ti_w(t), parent(_parent) , internal_determining_widget(_parent), internal(_internal) #ifdef WIDGET_CCI_DEBUG_ON_DEMAND , print_debug(debug) #endif { if (ti!=end) { if (t->Type()!=type) std::cerr << "const_contained_iterator:ctor: t has type " << t->Type() << '\n'; if (Configuration.glade2) { FOR_EACH_CONST_TAG(i,*ti) { if (i->Type()=="widget" || i->Type()=="placeholder") ti_w=i; } if (ti_w==ti) std::cerr << "Oops. Unexpected: no widget as child\n"; } if (parent==internal_determining_widget) sub=not_Subwidget; // test each child individually else sub=Widget(*internal_determining_widget).subwidgettype(Widget(*parent)); DEBUG(std::cerr << "const_contained_iterator:ctor @"<< Widget(*t).Name()<<" sub="<getString("class")=="Placeholder") return false; if (internal==Internal_Both) return true; else if (internal==OnlyInternal) // we are looking for internal Widgets { Subwidget s=getSWType(); if (s==is_Subwidget_only || s==is_Subwidget_all || s==is_Subwidget || s==all_Subwidgets) return true; } else // we are looking for real widgets contained { Subwidget s=getSWType(); if (s==no_Subwidgets || s==not_Subwidget) return true; } return false; } bool Widget::const_contained_iterator::need_recurse() const { assert(ti!=end); if (Widget(*ti_w).getBoolProperty(CXX_SEPERATE_CLASS)) return false; #ifdef PARANOIA if (Widget(*ti_w).getBoolProperty(CXX_SEPERATE_FILE)) std::cerr << "Code error\n"; #endif if (internal==Internal_Both) { // always ok } else if (internal==OnlyInternal) { Subwidget s=getSWType(); if (s==no_Subwidgets || s==not_Subwidget || s==is_Subwidget_only || s==all_Subwidgets) return false; } else { if (getSWType()==is_Subwidget_all) return false; } return true; } Widget::const_contained_iterator &Widget::const_contained_iterator::operator++() { if (internal==OnlyInternal && sub==no_Subwidgets) // short cut { ti=ti_w=end; } reiterate: DEBUG(std::cerr << "\t++\n"); if (ti!=end) { ti=ti_w=find(ti+1,end,type); if (ti==end) goto reiterate; if (Configuration.glade2) { FOR_EACH_CONST_TAG(i,*ti) { if (i->Type()=="widget" || i->Type()=="placeholder") ti_w=i; } if (ti_w==ti) { std::cerr << "Oops. Unexpected: no widget as child\n"; goto reiterate; } } // if this widget is a tree dive first if (find(ti_w->begin(),ti_w->end(),type)!=ti_w->end()) { DEBUG(std::cerr << "++: started diving @" << Widget(*ti).Name() << '/' \ << Widget(*internal_determining_widget).Name() << " sub=" \ << sub << '\n'); dive(); } if (!acceptable()) goto reiterate; } else if (pushed.size()) // ti==end { stack &p=pushed.back(); DEBUG(std::cerr << "diving up to "<< Widget(*(p.first)).Name() \ << " sub="<< p.fourth << " parent=" << Widget(*p.third).Name() \ << '/' << Widget(*p.fifth).Name()<< '\n'); ti=p.first; end=p.second; parent=p.third; sub=p.fourth; internal_determining_widget=p.fifth; ti_w=p.sixth; pushed.pop_back(); if (!acceptable()) goto reiterate; } if (ti!=end) DEBUG(std::cerr << "accepted "<< Widget(*ti).Name() << " sub=" << sub \ << " parent="<< Widget(*parent).Name() << '/' \ << Widget(*internal_determining_widget).Name() << '\n'); else DEBUG(std::cerr << "accepted end\n"); return *this; } const char * Widget::const_contained_iterator::type="widget"; void Widget::const_contained_iterator::init() { if (Configuration.glade2) type="child"; } Subwidget Widget::const_contained_iterator::getSWType() const { switch (sub) { case is_Subwidget_all: return is_Subwidget_all; case no_Subwidgets: return not_Subwidget; case is_Subwidget_only: return no_Subwidgets; case all_Subwidgets: return is_Subwidget; default: case is_Subwidget: case not_Subwidget: if (internal_determining_widget==&*ti) return not_Subwidget; return Widget(*internal_determining_widget).subwidgettype(*ti); // SW_Unknown; ?? } }