/********************************************************************** ** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved. ** ** This file is part of Qt/Embedded. ** ** This file may be used under the terms of the GNU General ** Public License versions 2.0 or 3.0 as published by the Free ** Software Foundation and appearing in the files LICENSE.GPL2 ** and LICENSE.GPL3 included in the packaging of this file. ** Alternatively you may (at your option) use any later version ** of the GNU General Public License if such license has been ** publicly approved by Trolltech ASA (or its successors, if any) ** and the KDE Free Qt Foundation. ** ** Please review the following information to ensure GNU General ** Public Licensing requirements will be met: ** http://trolltech.com/products/qt/licenses/licensing/opensource/. ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview ** or contact the sales department at sales@trolltech.com. ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with ** the Software. ** ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted ** herein. ** **********************************************************************/ #include "main.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(Q_OS_WIN32) #include #else #include #endif #include /* XPM */ static const char * const logo_xpm[] = { /* width height ncolors chars_per_pixel */ "50 50 17 1", /* colors */ " c #000000", ". c #495808", "X c #2A3304", "o c #242B04", "O c #030401", "+ c #9EC011", "@ c #93B310", "# c #748E0C", "$ c #A2C511", "% c #8BA90E", "& c #99BA10", "* c #060701", "= c #181D02", "- c #212804", "; c #61770A", ": c #0B0D01", "/ c None", /* pixels */ "/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$", "$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$", "$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$", "$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$", "$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$", "$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$", "$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$", "$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$", "$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$", "$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$", "$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$", "$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$", "$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$", "$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$", "$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$", "$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$", "$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$", "$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$", "$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$", "$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$", "$$$$$$$;* Oo+$$;O*O:OO-- Oo@+= *;$$$$$$$", "$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$", "$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$", "$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$", "$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$", "$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$", "$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$", "$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$", "$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$", "$$$$$$$$$$$$@XOO OO O*X+$$$$$$", "$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$", "$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$", "$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", }; #define FIXED_LAYOUT static const char*back_xpm[]={ "16 16 5 1", "# c #000000", "a c #ffffff", "c c #808080", "b c #c0c0c0", ". c None", "................", ".......#........", "......##........", ".....#a#........", "....#aa########.", "...#aabaaaaaaa#.", "..#aabbbbbbbbb#.", "...#abbbbbbbbb#.", "...c#ab########.", "....c#a#ccccccc.", ".....c##c.......", "......c#c.......", ".......cc.......", "........c.......", "................", "......................"}; static const char*forward_xpm[]={ "16 16 5 1", "# c #000000", "a c #ffffff", "c c #808080", "b c #c0c0c0", ". c None", "................", "................", ".........#......", ".........##.....", ".........#a#....", "..########aa#...", "..#aaaaaaabaa#..", "..#bbbbbbbbbaa#.", "..#bbbbbbbbba#..", "..########ba#c..", "..ccccccc#a#c...", "........c##c....", "........c#c.....", "........cc......", "........c.......", "................", "................"}; class ChoiceItem : public QCheckListItem { public: QString id; ChoiceItem(const QString& i, QListViewItem* parent) : QCheckListItem(parent, i.mid(6), // strip "QT_NO_" as we reverse the logic CheckBox), id(i) { setOpen(TRUE); label = text(0); avl = TRUE; } // We reverse the logic void setDefined(bool y) { setOn(!y); } bool isDefined() const { return !isOn(); } void setAvailable(bool y) { if ( avl != y ) { avl = y; repaint(); } } bool isAvailable() const { return avl; } virtual void setOn(bool y) { QCheckListItem::setOn(y); setOpen(y); /* for (QListViewItem* i=firstChild(); i; i = i->nextSibling() ) { ChoiceItem* ci = (ChoiceItem*)i; // all are ChoiceItem if ( ci->isSelectable() != y ) { ci->setSelectable(y); listView()->repaintItem(ci); } } */ } void paintBranches( QPainter * p, const QColorGroup & cg, int w, int y, int h) { QListViewItem::paintBranches(p,cg,w,y,h); } void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int align ) { if ( !isSelectable() || !isAvailable() ) { QColorGroup c = cg; c.setColor(QColorGroup::Text, lightGray); QCheckListItem::paintCell(p,c,column,width,align); } else { QCheckListItem::paintCell(p,cg,column,width,align); } } void setInfo(const QString& l, const QString& d) { label = l; doc = d; setText(0,label); } QString label; QString info() const { return "

"+label+"

"+doc; } private: QString doc; bool avl; }; Main::Main() { setIcon( (const char**)logo_xpm ); #ifdef FIXED_LAYOUT QHBox* horizontal = new QHBox(this); #else QSplitter* horizontal = new QSplitter(this); #endif lv = new QListView(horizontal); lv->setSorting(-1); lv->setRootIsDecorated(TRUE); lv->addColumn("ID"); info = new Info(horizontal); info->setBackgroundMode(PaletteBase); info->setMargin(10); info->setFrameStyle(QFrame::WinPanel|QFrame::Sunken); info->setAlignment(AlignTop); connect(info, SIGNAL(idClicked(const QString&)), this, SLOT(selectId(const QString&))); #ifdef FIXED_LAYOUT horizontal->setStretchFactor(info,2); #endif connect(lv, SIGNAL(pressed(QListViewItem*)), this, SLOT(updateAvailability(QListViewItem*))); connect(lv, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(showInfo(QListViewItem*))); setCentralWidget(horizontal); QToolBar* tb = new QToolBar( this, "browser controls" ); tb->setLabel( "Browser Controls" ); (void)new QToolButton( QPixmap(back_xpm), "Back", QString::null, info, SLOT(back()), tb, "back" ); (void)new QToolButton( QPixmap(forward_xpm), "Forward", QString::null, info, SLOT(forward()), tb, "forward" ); QPopupMenu* file = new QPopupMenu( menuBar() ); file->insertItem( "&Open", this, SLOT(open()), CTRL+Key_O ); file->insertItem( "&Save", this, SLOT(save()), CTRL+Key_S ); file->insertSeparator(); file->insertItem( "&Test all", this, SLOT(testAll()), CTRL+Key_T ); file->insertSeparator(); file->insertItem( "E&xit", qApp, SLOT(quit()), CTRL+Key_Q ); menuBar()->insertItem( "&File",file ); menuBar()->insertSeparator(); QPopupMenu *help = new QPopupMenu( menuBar() ); help->insertItem( "&About", this, SLOT(about()) ); help->insertItem( "About &Qt", this, SLOT(aboutQt()) ); menuBar()->insertItem( "&Help", help ); statusBar()->message( "Ready" ); } void Main::open() { } void Main::save() { } void Main::testAll() { QString qtdir = getenv("QTDIR"); chdir((qtdir+"/src").ascii()); QString c; for (QStringList::ConstIterator it = choices.begin(); it != choices.end(); ++it) { c += "Feature: "; c += *it; c += "\n"; c += "Section: "; c += section[*it]; c += "\n"; c += "Requires: "; c += dependencies[*it].join(" "); c += "\n"; c += "Name: "; c += label[*it]; c += "\n"; c += "SeeAlso: ???\n"; c += "\n"; } QFile f("features.txt"); f.open(IO_WriteOnly); f.writeBlock(c.ascii(),c.length()); f.close(); // system("./feature_size_calculator"); #if 0 system("mv ../include/qconfig.h ../include/qconfig.h-orig"); for (QStringList::ConstIterator it = choices.begin(); it != choices.end(); ++it) { QString choice = *it; QFile f("../include/qconfig.h"); f.open(IO_WriteOnly); QCString s = "#define "; s += choice.latin1(); s += "\n"; f.writeBlock(s,s.length()); f.close(); int err = system("make"); if ( err != 0 ) break; } system("mv ../include/qconfig.h-orig ../include/qconfig.h"); #endif } // ##### should be in QMap? template QValueList keys(QMap map) { QValueList result; for (Q_TYPENAME QMap::ConstIterator it = map.begin(); it!=map.end(); ++it) result.append(it.key()); return result; } void Main::loadFeatures(const QString& filename) { QFile file(filename); if ( !file.open(IO_ReadOnly) ) { QMessageBox::warning(this,"Warning", "Cannot open file " + filename); return; } QTextStream s(&file); QRegExp qt_no_xxx("QT_NO_[A-Z_0-9]*"); QStringList sections; #if 1 QString line = s.readLine(); QString feature, lab, sec; QStringList deps, seealso; QMap sectioncontents; while (!s.atEnd()) { if ( line.length() <= 1 ) { if ( !feature.isEmpty() ) { dependencies[feature] = deps; for (QStringList::ConstIterator it = deps.begin(); it!=deps.end(); ++it) rdependencies[*it].append(feature); label[feature] = lab; links[feature] = seealso; section[feature] = sec; sectioncontents[sec].append(feature); choices.append(feature); } else { qDebug("Unparsed text"); } feature = lab = sec = QString::null; deps.clear(); seealso.clear(); line = s.readLine(); continue; } QString nextline = s.readLine(); while ( nextline[0] == ' ' ) { line += nextline; nextline = s.readLine(); } int colon = line.find(':'); if ( colon < 0 ) { qDebug("Cannot parse: %s",line.ascii()); } else { QString tag = line.left(colon); QString value = line.mid(colon+1).stripWhiteSpace(); if ( tag == "Feature" ) feature = value; else if ( tag == "Requires" ) deps = QStringList::split(QChar(' '),value); else if ( tag == "Name" ) lab = value; else if ( tag == "Section" ) sec = value; else if ( tag == "SeeAlso" ) seealso = QStringList::split(QChar(' '),value); } line = nextline; } sections = keys(sectioncontents); #else QString sec; QString lab; QString doc; bool on = FALSE; bool docmode = FALSE; QStringList deps; do { QString line = s.readLine(); line.replace(QRegExp("# *define"),"#define"); QStringList token = QStringList::split(QChar(' '),line); if ( on ) { if ( docmode ) { if ( token[0] == "*/" ) docmode = FALSE; else if ( lab.isEmpty() ) lab = line.stripWhiteSpace(); else doc += line.simplifyWhiteSpace() + "\n"; } else if ( token[0] == "//#define" || token[0] == "#define" ) { dependencies[token[1]] = deps; for (QStringList::ConstIterator it = deps.begin(); it!=deps.end(); ++it) rdependencies[*it].append(token[1]); section[token[1]] = sec; documentation[token[1]] = doc; label[token[1]] = lab; choices.append(token[1]); doc = ""; lab = ""; } else if ( token[0] == "/*!" ) { docmode = TRUE; } else if ( token[0] == "//" ) { token.remove(token.begin()); sec = token.join(" "); sections.append(sec); } else if ( token[0] == "#if" ) { Q_ASSERT(deps.isEmpty()); for (int i=1; i<(int)token.count(); i++) { if ( token[i][0] == 'd' ) { int index; int len; index = qt_no_xxx.match(token[i],0,&len); if ( index >= 0 ) { QString d = token[i].mid(index,len); deps.append(d); } } } } else if ( token[0] == "#endif" ) { deps.clear(); } else if ( token[0].isEmpty() ) { } else { qDebug("Cannot parse: %s",token.join(" ").ascii()); } } else if ( token[0] == "#include" ) { on = TRUE; } } while (!s.atEnd()); #endif lv->clear(); sections.sort(); // ##### QListView default sort order is reverse of insertion order for (QStringList::Iterator se = sections.fromLast(); se != sections.end(); --se) { sectionitem[*se] = new QListViewItem(lv,*se); } for (QStringList::Iterator ch = choices.begin(); ch != choices.end(); ++ch) { createItem(*ch); } #ifdef FIXED_LAYOUT lv->setFixedWidth(lv->sizeHint().width()); #endif } void Main::createItem(const QString& ch) { if ( !item[ch] ) { QStringList deps = dependencies[ch]; QString sec = section[ch]; QListViewItem* parent = 0; for (QStringList::Iterator dp = deps.begin(); dp != deps.end(); ++dp) { QString dsec = section[*dp]; if ( dsec.isEmpty() ) qDebug("No section for %s",(*dp).latin1()); if ( !parent && dsec == sec ) { createItem(*dp); parent = item[*dp]; } } if ( !parent ) parent = sectionitem[section[ch]]; ChoiceItem* ci = new ChoiceItem(ch,parent); item[ch] = ci; if ( !label[ch].isEmpty() ) ci->setInfo(label[ch],documentation[ch]); } } void Main::loadConfig(const QString& filename) { QFile file(filename); if ( !file.open(IO_ReadOnly) ) { QMessageBox::warning(this,"Warning", "Cannot open file " + filename); return; } QTextStream s(&file); QRegExp qt_no_xxx("QT_NO_[A-Z_0-9]*"); for (QStringList::Iterator ch = choices.begin(); ch != choices.end(); ++ch) { item[*ch]->setDefined(FALSE); } do { QString line = s.readLine(); QStringList token = QStringList::split(QChar(' '),line); if ( token[0] == "#define" ) { ChoiceItem* i = item[token[1]]; if ( i ) i->setDefined(TRUE); else qDebug("The item %s is not used by qfeatures.h", token[1].latin1()); } } while (!s.atEnd()); } void Main::updateAvailability(QListViewItem* i) { if ( !i || !i->parent() ) { // section. do nothing for now } else { ChoiceItem* choice = (ChoiceItem*)i; QStringList deps = rdependencies[choice->id]; for (QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) { ChoiceItem* d = item[*it]; QStringList ddeps = dependencies[d->id]; bool av = TRUE; for (QStringList::ConstIterator dit = ddeps.begin(); av && dit != ddeps.end(); ++dit) { ChoiceItem* dd = item[*dit]; if ( dd ) { if ( dd->isDefined() || !dd->isAvailable() ) av = FALSE; } else qDebug("%s ???",(*dit).latin1()); } if ( d->isAvailable() != av ) { d->setAvailable(av); updateAvailability(d); } } qDebug("%s: %d",choice->id.latin1(),choice->isAvailable()); } } void Main::showInfo(QListViewItem* i) { if ( !i ) return; if ( !i->parent() ) { // section. do nothing for now } else { ChoiceItem* choice = (ChoiceItem*)i; QString i = choice->info(); QStringList deps = dependencies[choice->id]; if ( !deps.isEmpty() ) { i += "

Requires:

    "; for (QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) { ChoiceItem* d = item[*it]; if ( d ) { bool got = d->isAvailable() && !d->isDefined(); i += "
  • "; if ( !got ) i += ""; i += "id+">"+d->label+""; if ( !got ) i += ""; } } i += "
"; } QStringList rdeps = rdependencies[choice->id]; if ( !rdeps.isEmpty() ) { i += "

Required for:

    "; for (QStringList::ConstIterator it = rdeps.begin(); it != rdeps.end(); ++it) { ChoiceItem* d = item[*it]; if ( d ) i += "
  • id+">"+d->label+""; } i += "
"; } info->setText(i); } } void Main::selectId(const QString& id) { QListViewItem* it = item[id]; if ( it ) { lv->setSelected(it,TRUE); lv->ensureItemVisible(it); } } Info::Info( QWidget* parent, const char* name ) : QTextBrowser(parent, name) { } void Info::setSource(const QString& name) { if ( name.left(5) == "id://" ) { emit idClicked(name.mid(5,name.length()-6)); // skip trailing "/" too } else { QTextBrowser::setSource(name); } } void Main::about() { QMessageBox::about(this, "About qconfig", "

Qt/Embedded build configuration

" "

" "

Version 1.0

" "

Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.

" "

" "

This program is licensed to you under the terms of the GNU General " "Public License Version 2 as published by the Free Software Foundation. This " "gives you legal permission to copy, distribute and/or modify this software " "under certain conditions. For details, see the file 'LICENSE.GPL' that came with " "this software distribution. If you did not get the file, send email to " "info@trolltech.com.

\n\n

The program is provided AS IS with NO WARRANTY " "OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS " "FOR A PARTICULAR PURPOSE.

" ); } void Main::aboutQt() { QMessageBox::aboutQt( this, tr("qconfig") ); } int main(int argc, char** argv) { QApplication app(argc,argv); Main m; QString qtdir = getenv("QTDIR"); QString qfeatures = qtdir + "/src/tools/qfeatures.txt"; //QString qfeatures = qtdir + "/include/qfeatures.h"; QString qconfig = qtdir + "/include/qconfig.h"; for (int i=1; i