Exemple #1
0
    void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
    {
        std::string name = mNameEdit->getCaption();
        boost::algorithm::trim(name);

        MWMechanics::Alchemy::Result result = mAlchemy.create (mNameEdit->getCaption ());

        if (result == MWMechanics::Alchemy::Result_NoName)
        {
            mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
            return;
        }

        // check if mortar & pestle is available (always needed)
        if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle)
        {
            mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
            return;
        }

        // make sure 2 or more ingredients were selected
        if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients)
        {
            mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
            return;
        }

        if (result == MWMechanics::Alchemy::Result_NoEffects)
        {
            mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
            return;
        }

        if (result == MWMechanics::Alchemy::Result_Success)
        {
            mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
        }
        else if (result == MWMechanics::Alchemy::Result_RandomFailure)
        {
            // potion failed
            mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
        }

        // reduce count of the ingredients
        for (int i=0; i<4; ++i)
            if (mIngredients[i]->isUserString("ToolTipType"))
            {
                MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>();
                ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
                if (ingred.getRefData().getCount() == 0)
                    removeIngredient(mIngredients[i]);
        }

        update();
    }
    void AlchemyWindow::createPotions(int count)
    {
        MWMechanics::Alchemy::Result result = mAlchemy->create(mNameEdit->getCaption(), count);
        MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager();

        switch (result)
        {
        case MWMechanics::Alchemy::Result_NoName:
            winMgr->messageBox("#{sNotifyMessage37}");
            break;
        case MWMechanics::Alchemy::Result_NoMortarAndPestle:
            winMgr->messageBox("#{sNotifyMessage45}");
            break;
        case MWMechanics::Alchemy::Result_LessThanTwoIngredients:
            winMgr->messageBox("#{sNotifyMessage6a}");
            break;
        case MWMechanics::Alchemy::Result_Success:
            winMgr->playSound("potion success");
            if (count == 1)
                winMgr->messageBox("#{sPotionSuccess}");
            else
                winMgr->messageBox("#{sPotionSuccess} "+mNameEdit->getCaption()+" ("+std::to_string(count)+")");
            break;
        case MWMechanics::Alchemy::Result_NoEffects:
        case MWMechanics::Alchemy::Result_RandomFailure:
            winMgr->messageBox("#{sNotifyMessage8}");
            winMgr->playSound("potion fail");
            break;
        }

        // remove ingredient slots that have been fully used up
        for (int i=0; i<4; ++i)
            if (mIngredients[i]->isUserString("ToolTipType"))
            {
                MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>();
                if (ingred.getRefData().getCount() == 0)
                    removeIngredient(mIngredients[i]);
            }

        update();
    }
Exemple #3
0
    void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
    {
        MWMechanics::Alchemy::Result result = mAlchemy->create (mNameEdit->getCaption ());

        switch (result)
        {
        case MWMechanics::Alchemy::Result_NoName:
            MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage37}");
            break;
        case MWMechanics::Alchemy::Result_NoMortarAndPestle:
            MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage45}");
            break;
        case MWMechanics::Alchemy::Result_LessThanTwoIngredients:
            MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage6a}");
            break;
        case MWMechanics::Alchemy::Result_Success:
            MWBase::Environment::get().getWindowManager()->messageBox("#{sPotionSuccess}");
            MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
            break;
        case MWMechanics::Alchemy::Result_NoEffects:
        case MWMechanics::Alchemy::Result_RandomFailure:
            MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage8}");
            MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
            break;
        }

        // remove ingredient slots that have been fully used up
        for (int i=0; i<4; ++i)
            if (mIngredients[i]->isUserString("ToolTipType"))
            {
                MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>();
                if (ingred.getRefData().getCount() == 0)
                    removeIngredient(mIngredients[i]);
            }

        update();
    }
Exemple #4
0
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)
{
    removeIngredient(_sender);
    update();
}
Exemple #5
0
    void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
    {
        // check if mortar & pestle is available (always needed)
        /// \todo check albemic, calcinator, retort (sometimes needed)
        if (!mApparatus1->isUserString("ToolTipType"))
        {
            mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
            return;
        }

        // make sure 2 or more ingredients were selected
        int numIngreds = 0;
        if (mIngredient1->isUserString("ToolTipType"))
            ++numIngreds;
        if (mIngredient2->isUserString("ToolTipType"))
            ++numIngreds;
        if (mIngredient3->isUserString("ToolTipType"))
            ++numIngreds;
        if (mIngredient4->isUserString("ToolTipType"))
            ++numIngreds;
        if (numIngreds < 2)
        {
            mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
            return;
        }

        // make sure a name was entered
        std::string name = mNameEdit->getCaption();
        boost::algorithm::trim(name);
        if (name == "")
        {
            mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
            return;
        }

        // if there are no created effects, the potion will always fail (but the ingredients won't be destroyed)
        if (mEffects.empty())
        {
            mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
            return;
        }

        if (rand() % 2 == 0) /// \todo
        {
            ESM::Potion newPotion;
            newPotion.mName = mNameEdit->getCaption();
            ESM::EffectList effects;
            for (unsigned int i=0; i<4; ++i)
            {
                if (mEffects.size() >= i+1)
                {
                    ESM::ENAMstruct effect;
                    effect.mEffectID = mEffects[i].mEffectID;
                    effect.mArea = 0;
                    effect.mRange = ESM::RT_Self;
                    effect.mSkill = mEffects[i].mSkill;
                    effect.mAttribute = mEffects[i].mAttribute;
                    effect.mMagnMin = 1; /// \todo
                    effect.mMagnMax = 10; /// \todo
                    effect.mDuration = 60; /// \todo
                    effects.mList.push_back(effect);
                }
            }

            // UESP Wiki / Morrowind:Alchemy
            // "The weight of a potion is an average of the weight of the ingredients, rounded down."
            // note by scrawl: not rounding down here, I can't imagine a created potion to
            // have 0 weight when using ingredients with 0.1 weight respectively
            float weight = 0;
            if (mIngredient1->isUserString("ToolTipType"))
                weight += mIngredient1->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
            if (mIngredient2->isUserString("ToolTipType"))
                weight += mIngredient2->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
            if (mIngredient3->isUserString("ToolTipType"))
                weight += mIngredient3->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
            if (mIngredient4->isUserString("ToolTipType"))
                weight += mIngredient4->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
            newPotion.mData.mWeight = weight / float(numIngreds);

            newPotion.mData.mValue = 100; /// \todo
            newPotion.mEffects = effects;
            // pick a random mesh and icon
            std::vector<std::string> names;
            /// \todo is the mesh/icon dependent on alchemy skill?
            names.push_back("standard");
            names.push_back("bargain");
            names.push_back("cheap");
            names.push_back("fresh");
            names.push_back("exclusive");
            names.push_back("quality");
            int random = rand() % names.size();
            newPotion.mModel = "m\\misc_potion_" + names[random ] + "_01.nif";
            newPotion.mIcon = "m\\tx_potion_" + names[random ] + "_01.dds";

            // check if a similiar potion record exists already
            bool found = false;
            std::string objectId;
            typedef std::map<std::string, ESM::Potion> PotionMap;
            PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list;
            for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it)
            {
                if (found) break;

                if (it->second.mData.mValue == newPotion.mData.mValue
                    && it->second.mData.mWeight == newPotion.mData.mWeight
                    && it->second.mName == newPotion.mName
                    && it->second.mEffects.mList.size() == newPotion.mEffects.mList.size())
                {
                    // check effects
                    for (unsigned int i=0; i < it->second.mEffects.mList.size(); ++i)
                    {
                        const ESM::ENAMstruct& a = it->second.mEffects.mList[i];
                        const ESM::ENAMstruct& b = newPotion.mEffects.mList[i];
                        if (a.mEffectID == b.mEffectID
                            && a.mArea == b.mArea
                            && a.mRange == b.mRange
                            && a.mSkill == b.mSkill
                            && a.mAttribute == b.mAttribute
                            && a.mMagnMin == b.mMagnMin
                            && a.mMagnMax == b.mMagnMax
                            && a.mDuration == b.mDuration)
                        {
                            found = true;
                            objectId = it->first;
                            break;
                        }
                    }
                }
            }

            if (!found)
            {
                std::pair<std::string, const ESM::Potion*> result = MWBase::Environment::get().getWorld()->createRecord(newPotion);
                objectId = result.first;
            }

            // create a reference and add it to player inventory
            MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId);
            MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
            ref.getPtr().getRefData().setCount(1);
            store.add(ref.getPtr());

            mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
        }
        else
        {
            // potion failed
            mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
            MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
        }

        // reduce count of the ingredients
        if (mIngredient1->isUserString("ToolTipType"))
        {
            MWWorld::Ptr ingred = *mIngredient1->getUserData<MWWorld::Ptr>();
            ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
            if (ingred.getRefData().getCount() == 0)
                removeIngredient(mIngredient1);
        }
        if (mIngredient2->isUserString("ToolTipType"))
        {
            MWWorld::Ptr ingred = *mIngredient2->getUserData<MWWorld::Ptr>();
            ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
            if (ingred.getRefData().getCount() == 0)
                removeIngredient(mIngredient2);
        }
        if (mIngredient3->isUserString("ToolTipType"))
        {
            MWWorld::Ptr ingred = *mIngredient3->getUserData<MWWorld::Ptr>();
            ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
            if (ingred.getRefData().getCount() == 0)
                removeIngredient(mIngredient3);
        }
        if (mIngredient4->isUserString("ToolTipType"))
        {
            MWWorld::Ptr ingred = *mIngredient4->getUserData<MWWorld::Ptr>();
            ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
            if (ingred.getRefData().getCount() == 0)
                removeIngredient(mIngredient4);
        }
        update();
    }
Exemple #6
0
View::View(QWidget *parent, Recipe *recipe)
    : QWidget(parent), recipe_(recipe), grainmodel_(0), hopmodel_(0),
      miscmodel_(0), notepage_(0)
{
    ui.setupUi(this);

    // get current font information
    QFont bold(font());
    bold.setBold(true);
    QFontMetrics fm(font());
    unsigned mh = (unsigned)(fm.lineSpacing() * 1.5);
    unsigned mw = fm.width('M');

    // additional setup
    ui.ogreclabel->setFont(bold);
    ui.ogrec->setFont(bold);
    ui.ibureclabel->setFont(bold);
    ui.iburec->setFont(bold);
    ui.srmreclabel->setFont(bold);
    ui.srmrec->setFont(bold);
    ui.abvlabel->setFont(bold);
    ui.abv->setFont(bold);
    ui.abwlabel->setFont(bold);
    ui.abw->setFont(bold);
    ui.fglabel->setFont(bold);
    ui.fg->setFont(bold);

    // grain page
    QWidget *widget = new QWidget();
    grainpage.setupUi(widget);
    ui.ingredients->addTab(widget, tr("&Grains"));

    grainmodel_ = new GrainModel(this, recipe_->grains());
    grainpage.view->setModel(grainmodel_);
    QItemDelegate *delegate = new GrainDelegate(this);
    grainpage.view->setItemDelegate(delegate);

    grainpage.view->verticalHeader()->setDefaultSectionSize(mh);
    grainpage.view->verticalHeader()->hide();
    grainpage.view->horizontalHeader()->setClickable(true);
    grainpage.view->horizontalHeader()->setHighlightSections(false);

    grainpage.view->setColumnWidth(GrainModel::NAME, 20*mw);
    grainpage.view->setColumnWidth(GrainModel::WEIGHT, 8*mw);
    grainpage.view->setColumnWidth(GrainModel::EXTRACT, 8*mw);
    grainpage.view->setColumnWidth(GrainModel::COLOR, 8*mw);
    grainpage.view->setColumnWidth(GrainModel::TYPE, 8*mw);
    grainpage.view->setColumnWidth(GrainModel::USE, 8*mw);

    // hop page
    widget = new QWidget();
    hoppage.setupUi(widget);
    ui.ingredients->addTab(widget, tr("&Hops"));

    hopmodel_ = new HopModel(this, recipe_->hops());
    hoppage.view->setModel(hopmodel_);
    delegate = new HopDelegate(this);
    hoppage.view->setItemDelegate(delegate);

    hoppage.view->verticalHeader()->setDefaultSectionSize(mh);
    hoppage.view->verticalHeader()->hide();
    hoppage.view->horizontalHeader()->setClickable(true);
    hoppage.view->horizontalHeader()->setHighlightSections(false);

    hoppage.view->setColumnWidth(HopModel::NAME, 20*mw);
    hoppage.view->setColumnWidth(HopModel::WEIGHT, 8*mw);
    hoppage.view->setColumnWidth(HopModel::ALPHA, 8*mw);
    hoppage.view->setColumnWidth(HopModel::TIME, 8*mw);
    hoppage.view->setColumnWidth(HopModel::TYPE, 8*mw);

    // misc page
    widget = new QWidget();
    miscpage.setupUi(widget);
    ui.ingredients->addTab(widget, tr("&Miscellaneous"));

    miscmodel_ = new MiscModel(this, recipe_->miscs());
    miscpage.view->setModel(miscmodel_);
    delegate = new MiscDelegate(this);
    miscpage.view->setItemDelegate(delegate);

    miscpage.view->verticalHeader()->setDefaultSectionSize(mh);
    miscpage.view->verticalHeader()->hide();
    miscpage.view->horizontalHeader()->setClickable(true);
    miscpage.view->horizontalHeader()->setHighlightSections(false);

    miscpage.view->setColumnWidth(MiscModel::NAME, 20*mw);
    miscpage.view->setColumnWidth(MiscModel::QUANTITY, 8*mw);
    miscpage.view->setColumnWidth(MiscModel::TYPE, 8*mw);
    miscpage.view->horizontalHeader()->setStretchLastSection(true);

    // note page
    notepage_ = new NotePage(0, recipe_);
    ui.ingredients->addTab(notepage_, tr("&Notes"));

    // set icons
    QIcon icon = QIcon(":/icons/22x22/list-add.png");
    icon.addFile(":/icons/16x16/list-add.png");
    grainpage.addbutton->setIcon(icon);
    hoppage.addbutton->setIcon(icon);
    miscpage.addbutton->setIcon(icon);
    icon = QIcon(":/icons/22x22/list-remove.png");
    icon.addFile(":/icons/16x16/list-remove.png");
    grainpage.removebutton->setIcon(icon);
    hoppage.removebutton->setIcon(icon);
    miscpage.removebutton->setIcon(icon);

    // widget connections
    connect(grainmodel_, SIGNAL(modified()),
            this, SLOT(modelModified()));
    connect(grainpage.addbutton, SIGNAL(clicked()),
            grainpage.view, SLOT(addIngredient()));
    connect(grainpage.removebutton, SIGNAL(clicked()),
            grainpage.view, SLOT(removeIngredient()));

    connect(hopmodel_, SIGNAL(modified()),
            this, SLOT(modelModified()));
    connect(hoppage.addbutton, SIGNAL(clicked()),
            hoppage.view, SLOT(addIngredient()));
    connect(hoppage.removebutton, SIGNAL(clicked()),
            hoppage.view, SLOT(removeIngredient()));

    connect(miscmodel_, SIGNAL(modified()),
            this, SLOT(modelModified()));
    connect(miscpage.addbutton, SIGNAL(clicked()),
            miscpage.view, SLOT(addIngredient()));
    connect(miscpage.removebutton, SIGNAL(clicked()),
            miscpage.view, SLOT(removeIngredient()));

    connect(ui.titleedit, SIGNAL(textChanged(const QString &)),
            this, SLOT(setTitle(const QString &)));
    connect(ui.stylecombo, SIGNAL(activated(const QString &)),
            this, SLOT(setStyle(const QString &)));
    connect(ui.breweredit, SIGNAL(textChanged(const QString &)),
            this, SLOT(setBrewer(const QString &)));
    connect(ui.sizespin, SIGNAL(valueChanged(double)),
            this, SLOT(setSize(double)));

    connect(recipe_, SIGNAL(recipeChanged()), this, SLOT(flush()));
    connect(recipe_, SIGNAL(recipeModified()), this, SLOT(refresh()));

    // start with new view
    flush();
}
IngredientParserDialog::IngredientParserDialog( const UnitList &units, QWidget* parent, const char* name )
		: KDialog( parent ),
		m_unitList(units)
{
	//setButtonBoxOrientation( Qt::Vertical );
	setObjectName( name );
	setCaption(i18nc( "@title:window", "Ingredient Parser" ));
	setButtons(KDialog::Ok | KDialog::Cancel);
	setDefaultButton(KDialog::Ok);
	setModal( true );

	KVBox *page = new KVBox( this );
	setMainWidget( page );

	textLabel1 = new QLabel( page );
	textLabel1->setObjectName( "textLabel1" );
	textLabel1->setTextFormat( Qt::RichText );

	ingredientTextEdit = new KTextEdit( page );
	ingredientTextEdit->setObjectName( "ingredientTextEdit" );
	ingredientTextEdit->setAcceptRichText( false );

	parseButton = new KPushButton( page );

	previewLabel = new QLabel( page );
	previewLabel->setObjectName( "previewLabel" );
	previewLabel->setTextFormat( Qt::RichText );

	previewIngView = new K3ListView( page );
	previewIngView->setSorting(-1);
	previewIngView->addColumn( i18nc( "@title:column", "Ingredient" ) );
	previewIngView->addColumn( i18nc( "@title:column", "Amount" ) );
	previewIngView->addColumn( i18nc( "@title:column", "Unit" ) );
	previewIngView->addColumn( i18nc( "@title:column", "Preparation Method" ) );

	languageChange();
	setInitialSize( QSize(577, 371).expandedTo(minimumSizeHint()) );

	previewIngView->setItemsRenameable( true );
	previewIngView->setRenameable( 0, true );
	previewIngView->setRenameable( 1, true );
	previewIngView->setRenameable( 2, true );
	previewIngView->setRenameable( 3, true );

	previewIngView->setSelectionMode( Q3ListView::Extended );

	ingredientTextEdit->setText( QApplication::clipboard()->text() );
	ingredientTextEdit->selectAll();

	QWidget *buttonWidget = new QWidget( page );
	QHBoxLayout *buttonBox = new QHBoxLayout(buttonWidget);
	QSpacerItem *horizontalSpacing = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
	buttonGroup = new QPushButton( i18nc("@action:button", "Set &Header"), buttonWidget );
	buttonGroup->setWhatsThis( i18nc( "@info:whatsthis", "If an ingredient header is detected as an ingredient, select it and click this button so that Krecipes will recognize it as a header.  All the ingredients below the header will be included within that group.\n\nAlternatively, if you select multiple ingredients and click this button, those ingredients will be grouped together.") );
	buttonBox->addWidget( buttonGroup );
	buttonBox->addItem( horizontalSpacing );

	KMenu *kpop = new KMenu( previewIngView );
	kpop->addAction( i18nc( "@item:inmenu", "&Delete" ), this, SLOT( removeIngredient() ), Qt::Key_Delete );
	kpop->addAction( i18nc( "@item:inmenu", "Set &Header") , this, SLOT( convertToHeader() ) );

	connect( parseButton, SIGNAL(clicked()), this, SLOT(parseText()) );
	connect( buttonGroup, SIGNAL(clicked()), this, SLOT(convertToHeader()) );
}
IngredientMatcherDialog::IngredientMatcherDialog( QWidget *parent, RecipeDB *db ) : QSplitter( parent )
{
	// Initialize internal variables
	database = db;

	//Design the dialog

	setOrientation( Qt::Vertical );
	setChildrenCollapsible( false );
	
	QWidget * upperBox = new QWidget( this );

	// Ingredient list
	QHBoxLayout *layout2 = new QHBoxLayout;
	layout2->setObjectName( "layout2" );

	allIngListView = new KreListView( this, QString(), true, 0 );
	StdIngredientListView *list_view = new StdIngredientListView(allIngListView,database);
	list_view->setSelectionMode( Q3ListView::Multi );
	allIngListView->setListView(list_view);
	layout2->addWidget( allIngListView );
	allIngListView->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );

	QVBoxLayout *layout1 = new QVBoxLayout;
	layout1->addStretch();
	layout1->setObjectName( "layout1" );

	addButton = new KPushButton;
	addButton->setObjectName( "addButton" );
	addButton->setIcon( KIcon( "arrow-right" ) );
	addButton->setFixedSize( QSize( 32, 32 ) );
	layout1->addWidget( addButton );

	removeButton = new KPushButton;
	removeButton->setObjectName( "removeButton" );
	removeButton->setIcon( KIcon( "arrow-left" ) );
	removeButton->setFixedSize( QSize( 32, 32 ) );
	layout1->addWidget( removeButton );
	layout1->addStretch();
	layout2->addLayout( layout1 );

	ingListView = new KreListView( this, QString(), true );
	ingListView->listView() ->addColumn( i18nc( "@title:column", "Ingredient (required?)" ) );
	ingListView->listView() ->addColumn( i18nc( "@title:column", "Amount Available" ) );
	layout2->addWidget( ingListView );
	upperBox->setLayout( layout2 );
	addWidget( upperBox );
	ingListView->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );

	KVBox * lowerBox = new KVBox( this );

	// Box to select allowed number of missing ingredients
	missingBox = new KHBox( lowerBox );
	missingNumberLabel = new QLabel( missingBox );
	missingNumberLabel->setText( i18nc(
		"@label:spinbox Number of missing ingredients allowed when doing a search by ingredients",
		"Missing ingredients allowed:" ) );
	missingNumberSpinBox = new KIntSpinBox( missingBox );
	missingNumberSpinBox->setMinimum( -1 );
	missingNumberSpinBox->setSpecialValueText( i18nc(
		"@item Any amount of ingredients missing when doing a search by ingredients", "Any" ) );

	// Found recipe list
	recipeListView = new KreListView( lowerBox, i18nc( "@title", "Matching Recipes" ), false, 1, missingBox );
	recipeListView->listView() ->setAllColumnsShowFocus( true );

	recipeListView->listView() ->addColumn( i18nc( "@title:column Recipe Title", "Title" ) );

	KConfigGroup config( KGlobal::config(), "Advanced" );
	bool show_id = config.readEntry( "ShowID", false );
	recipeListView->listView() ->addColumn( "Id" , show_id ? -1 : 0 );

	recipeListView->listView()->addColumn( i18nc( "@title:column Missing ingredients in a search result",
		"Missing Ingredients" ) );

	recipeListView->listView() ->setSorting( -1 );
	recipeListView->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );

	actionHandler = new RecipeActionsHandler( recipeListView->listView(), database );

	KHBox *buttonBox = new KHBox( lowerBox );

	okButton = new KPushButton( buttonBox );
	okButton->setIcon( KIcon( "dialog-ok" ) );
	okButton->setText( i18nc( "@action:button", "Find matching recipes" ) );

	//buttonBox->layout()->addItem( new QSpacerItem( 10,10, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ) );

	clearButton = new KPushButton( buttonBox );
	clearButton->setIcon( KIcon( "edit-clear" ) );
	clearButton->setText( i18nc( "@action:button Clear search criteria", "Clear" ) );

	addWidget( lowerBox );

	// Connect signals & slots
	connect ( okButton, SIGNAL( clicked() ), this, SLOT( findRecipes() ) );
	connect ( clearButton, SIGNAL( clicked() ), recipeListView->listView(), SLOT( clear() ) );
	connect ( clearButton, SIGNAL( clicked() ), this, SLOT( unselectIngredients() ) );
	connect( recipeListView->listView(), SIGNAL( selectionChanged() ), this, SLOT( haveSelectedItems() ) );
	connect ( actionHandler, SIGNAL( recipeSelected( int, int ) ), SIGNAL( recipeSelected( int, int ) ) );
	connect( addButton, SIGNAL( clicked() ), this, SLOT( addIngredient() ) );
	connect( removeButton, SIGNAL( clicked() ), this, SLOT( removeIngredient() ) );
	connect( ingListView->listView(), SIGNAL( doubleClicked( Q3ListViewItem*, const QPoint &, int ) ), SLOT( itemRenamed( Q3ListViewItem*, const QPoint &, int ) ) );
}