QWidget *Expert::createTopicWidget(QDomElement &elem) { QScrollArea *area = new QScrollArea; QWidget *topic = new QWidget; QGridLayout *layout = new QGridLayout(topic); QDomElement child = elem.firstChildElement(); int row=0; while (!child.isNull()) { QString type = child.attribute(SA("type")); if (type==SA("bool")) { InputBool *boolOption = new InputBool( layout,row, child.attribute(SA("id")), child.attribute(SA("defval"))==SA("1"), child.attribute(SA("docs")) ); m_options.insert( child.attribute(SA("id")), boolOption ); connect(boolOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*))); connect(boolOption,SIGNAL(changed()),SIGNAL(changed())); } else if (type==SA("string")) { InputString::StringMode mode; QString format = child.attribute(SA("format")); if (format==SA("dir")) { mode = InputString::StringDir; } else if (format==SA("file")) { mode = InputString::StringFile; } else // format=="string" { mode = InputString::StringFree; } InputString *stringOption = new InputString( layout,row, child.attribute(SA("id")), child.attribute(SA("defval")), mode, child.attribute(SA("docs")), child.attribute(SA("abspath")) ); m_options.insert( child.attribute(SA("id")), stringOption ); connect(stringOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*))); connect(stringOption,SIGNAL(changed()),SIGNAL(changed())); } else if (type==SA("enum")) { InputString *enumList = new InputString( layout,row, child.attribute(SA("id")), child.attribute(SA("defval")), InputString::StringFixed, child.attribute(SA("docs")) ); QDomElement enumVal = child.firstChildElement(); while (!enumVal.isNull()) { enumList->addValue(enumVal.attribute(SA("name"))); enumVal = enumVal.nextSiblingElement(); } enumList->setDefault(); m_options.insert(child.attribute(SA("id")),enumList); connect(enumList,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*))); connect(enumList,SIGNAL(changed()),SIGNAL(changed())); } else if (type==SA("int")) { InputInt *intOption = new InputInt( layout,row, child.attribute(SA("id")), child.attribute(SA("defval")).toInt(), child.attribute(SA("minval")).toInt(), child.attribute(SA("maxval")).toInt(), child.attribute(SA("docs")) ); m_options.insert( child.attribute(SA("id")), intOption ); connect(intOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*))); connect(intOption,SIGNAL(changed()),SIGNAL(changed())); } else if (type==SA("list")) { InputStrList::ListMode mode; QString format = child.attribute(SA("format")); if (format==SA("dir")) { mode = InputStrList::ListDir; } else if (format==SA("file")) { mode = InputStrList::ListFile; } else if (format==SA("filedir")) { mode = InputStrList::ListFileDir; } else // format=="string" { mode = InputStrList::ListString; } QStringList sl; QDomElement listVal = child.firstChildElement(); while (!listVal.isNull()) { sl.append(listVal.attribute(SA("name"))); listVal = listVal.nextSiblingElement(); } InputStrList *listOption = new InputStrList( layout,row, child.attribute(SA("id")), sl, mode, child.attribute(SA("docs")) ); m_options.insert( child.attribute(SA("id")), listOption ); connect(listOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*))); connect(listOption,SIGNAL(changed()),SIGNAL(changed())); } else if (type==SA("obsolete")) { // ignore } else // should not happen { printf("Unsupported type %s\n",qPrintable(child.attribute(SA("type")))); } child = child.nextSiblingElement(); } // compute dependencies between options child = elem.firstChildElement(); while (!child.isNull()) { QString dependsOn = child.attribute(SA("depends")); QString id = child.attribute(SA("id")); if (!dependsOn.isEmpty()) { Input *parentOption = m_options[dependsOn]; Input *thisOption = m_options[id]; Q_ASSERT(parentOption); Q_ASSERT(thisOption); if (parentOption && thisOption) { //printf("Adding dependency '%s' (%p)->'%s' (%p)\n", // qPrintable(dependsOn),parentOption, // qPrintable(id),thisOption); parentOption->addDependency(thisOption); } } child = child.nextSiblingElement(); } // set initial dependencies QHashIterator<QString,Input*> i(m_options); while (i.hasNext()) { i.next(); if (i.value()) { i.value()->updateDependencies(); } } layout->setRowStretch(row,1); layout->setColumnStretch(1,2); layout->setSpacing(5); topic->setLayout(layout); area->setWidget(topic); area->setWidgetResizable(true); return area; }
Expert::Expert( QWidget *parent ) : QTabDialog( parent ) { m_dependencies = new QDict< QList<IInput> >(257); m_dependencies->setAutoDelete(TRUE); m_inputWidgets = new QDict< IInput >; m_switches = new QDict< QObject >; m_changed = FALSE; setHelpButton(); QListIterator<ConfigOption> options = Config::instance()->iterator(); QVBoxLayout *pageLayout = 0; QFrame *page = 0; ConfigOption *option = 0; for (options.toFirst();(option=options.current());++options) { switch(option->kind()) { case ConfigOption::O_Info: { if (pageLayout) pageLayout->addStretch(1); QScrollView *view = new QScrollView(this); view->setVScrollBarMode(QScrollView::Auto); view->setHScrollBarMode(QScrollView::AlwaysOff); view->setResizePolicy(QScrollView::AutoOneFit); page = new QFrame( view->viewport(), option->name() ); pageLayout = new QVBoxLayout(page); pageLayout->setMargin(10); view->addChild(page); addTab(view,option->name()); QWhatsThis::add(page, option->docs().simplifyWhiteSpace() ); QToolTip::add(page, option->docs() ); } break; case ConfigOption::O_String: { ASSERT(page!=0); InputString::StringMode sm=InputString::StringFree; switch(((ConfigString *)option)->widgetType()) { case ConfigString::String: sm=InputString::StringFree; break; case ConfigString::File: sm=InputString::StringFile; break; case ConfigString::Dir: sm=InputString::StringDir; break; } InputString *inputString = new InputString( option->name(), // name page, // widget *((ConfigString *)option)->valueRef(), // variable sm // type ); pageLayout->addWidget(inputString); QWhatsThis::add(inputString, option->docs().simplifyWhiteSpace() ); QToolTip::add(inputString,option->docs()); connect(inputString,SIGNAL(changed()),SLOT(changed())); m_inputWidgets->insert(option->name(),inputString); addDependency(m_switches,option->dependsOn(),option->name()); } break; case ConfigOption::O_Enum: { ASSERT(page!=0); InputString *inputString = new InputString( option->name(), // name page, // widget *((ConfigEnum *)option)->valueRef(), // variable InputString::StringFixed // type ); pageLayout->addWidget(inputString); QStrListIterator sli=((ConfigEnum *)option)->iterator(); for (sli.toFirst();sli.current();++sli) { inputString->addValue(sli.current()); } inputString->init(); QWhatsThis::add(inputString, option->docs().simplifyWhiteSpace() ); QToolTip::add(inputString, option->docs()); connect(inputString,SIGNAL(changed()),SLOT(changed())); m_inputWidgets->insert(option->name(),inputString); addDependency(m_switches,option->dependsOn(),option->name()); } break; case ConfigOption::O_List: { ASSERT(page!=0); InputStrList::ListMode lm=InputStrList::ListString; switch(((ConfigList *)option)->widgetType()) { case ConfigList::String: lm=InputStrList::ListString; break; case ConfigList::File: lm=InputStrList::ListFile; break; case ConfigList::Dir: lm=InputStrList::ListDir; break; case ConfigList::FileAndDir: lm=InputStrList::ListFileDir; break; } InputStrList *inputStrList = new InputStrList( option->name(), // name page, // widget *((ConfigList *)option)->valueRef(), // variable lm // type ); pageLayout->addWidget(inputStrList); QWhatsThis::add(inputStrList, option->docs().simplifyWhiteSpace() ); QToolTip::add(inputStrList, option->docs()); connect(inputStrList,SIGNAL(changed()),SLOT(changed())); m_inputWidgets->insert(option->name(),inputStrList); addDependency(m_switches,option->dependsOn(),option->name()); } break; break; case ConfigOption::O_Bool: { ASSERT(page!=0); InputBool *inputBool = new InputBool( option->name(), // name page, // widget *((ConfigBool *)option)->valueRef() // variable ); pageLayout->addWidget(inputBool); QWhatsThis::add(inputBool, option->docs().simplifyWhiteSpace() ); QToolTip::add(inputBool, option->docs() ); connect(inputBool,SIGNAL(changed()),SLOT(changed())); m_inputWidgets->insert(option->name(),inputBool); addDependency(m_switches,option->dependsOn(),option->name()); } break; case ConfigOption::O_Int: { ASSERT(page!=0); InputInt *inputInt = new InputInt( option->name(), // name page, // widget *((ConfigInt *)option)->valueRef(), // variable ((ConfigInt *)option)->minVal(), // min value ((ConfigInt *)option)->maxVal() // max value ); pageLayout->addWidget(inputInt); QWhatsThis::add(inputInt, option->docs().simplifyWhiteSpace() ); QToolTip::add(inputInt, option->docs() ); connect(inputInt,SIGNAL(changed()),SLOT(changed())); m_inputWidgets->insert(option->name(),inputInt); addDependency(m_switches,option->dependsOn(),option->name()); } break; case ConfigOption::O_Obsolete: break; } } if (pageLayout) pageLayout->addStretch(1); QDictIterator<QObject> di(*m_switches); QObject *obj = 0; for (di.toFirst();(obj=di.current());++di) { connect(obj,SIGNAL(toggle(const char *,bool)),SLOT(toggle(const char *,bool))); // UGLY HACK: assumes each item depends on a boolean without checking! emit toggle(di.currentKey(),((InputBool *)obj)->getState()); } connect(this,SIGNAL(helpButtonPressed()),this,SLOT(handleHelp())); }