コード例 #1
18
ファイル: newaccount.cpp プロジェクト: opieproject/opie
void NewAccount::addAccountDescription ()
  {
    // Function for adding or editing an account description.
    QDialog *description = new QDialog ( this, "description", TRUE );
    description->setCaption ( "Notes" );
    QMultiLineEdit *enter = new QMultiLineEdit ( description );
    enter->setFixedSize ( ( int ) (this->width() * 0.75 ), ( int ) ( this->height() * 0.5 ) );
    enter->setWrapColumnOrWidth ( ( int ) (this->width() * 0.75 ) );
    enter->setWordWrap ( QMultiLineEdit::WidgetWidth );
    if ( accountdescription != "(NULL)" )
      enter->setText ( accountdescription );
    if ( description->exec () == QDialog::Accepted )
      accountdescription = enter->text ();
  }
コード例 #2
0
ファイル: devices.cpp プロジェクト: opieproject/opie
int DevicesWidget::doTab(){
    QDialog *dlg = new QDialog( 0, "newDevice", true, Qt::WStyle_ContextHelp );
    QVBoxLayout *layout = new QVBoxLayout( dlg );
    layout->setSpacing( 0 );
    layout->setMargin( 1 );

    QTabWidget *tabWindow = new QTabWidget( dlg, "tabWindow" );
    layout->addWidget( tabWindow );

    bool isnew;

    if(_pppdata->devname().isEmpty()) {
        dlg->setCaption(tr("New Device"));
        isnew = true;
    } else {
        QString tit = tr("Edit Device: ");
        tit += _pppdata->devname();
        dlg->setCaption(tit);
        isnew = false;
    }

   modem1 = new ModemWidget( _pppdata, tabWindow, "modem1" );
   tabWindow->addTab( modem1, tr("&Device") );
   modem2 = new ModemWidget2( _pppdata, _ifaceppp, tabWindow, "modem2" );
   tabWindow->addTab( modem2, tr("&Modem") );

   connect(modem2, SIGNAL(sig_beforeQueryModem()),
           modem1, SLOT(slotBeforeModemQuery()));
   connect(modem2, SIGNAL(sig_afterQueryModem()),
           modem1, SLOT(slotAfterModemQuery()));

    int result = 0;
    bool ok = false;

    while (!ok){
        result = QPEApplication::execDialog( dlg );
        ok = true;

        if(result == QDialog::Accepted) {
            if (!modem1->save()){
                QMessageBox::critical(this, tr("Error"), tr( "You must enter a unique device name"));
                ok = false;
            }else{
                 modem2->save();
            }
        }
    }

    delete dlg;

    return result;
}
コード例 #3
0
ファイル: buttonsettings.cpp プロジェクト: opieproject/opie
void ButtonSettings::slotAddDlgClosed( int key )
{
    if( key > 0 ) {
        odebug << "**** Add button " << ODevice::keyToString( key ) << oendl;
        delete m_addWidget;
        m_addWidget = 0;

        buttoninfo *bi = buttonInfoForKeycode( key );
        if( bi ) {
            QMessageBox::warning ( this, tr( "Already bound" ), tr( "The pressed button is already in the list." ));
            return;
        }

        // Get a name for the key
        QDialog *dlg = new QDialog( this, 0, true );
        QVBoxLayout *lay = new QVBoxLayout( dlg );
        QLabel *l = new QLabel( tr("Please enter a name for this button"), dlg );
        lay->addWidget(l);
        QLineEdit *le = new QLineEdit( dlg );
        lay->addWidget(le);
        lay->addStretch(1);
        dlg->setGeometry( qApp->desktop()->width() / 8, (qApp->desktop()->height() / 2) - 25,
                 3 * (qApp->desktop()->width() / 4), 50 );
        dlg->setCaption( tr( "Button name" ) );
        dlg->show();
        if( dlg->exec() == QDialog::Accepted ) {
            ODevice::inst()->registerCustomButton( key, le->text(), "" );
            addButtonItem( ODevice::inst()->buttons().last() );
            updateLabels();
            m_customChanged = true;
        }

    }
}
コード例 #4
0
ファイル: ohighscoredlg.cpp プロジェクト: opieproject/opie
QString OHighscore::getName()
{
	QString name;
	QDialog *d = new QDialog ( this, 0, true );
	d->setCaption( tr( "Enter your name!" ));
	QLineEdit *ed = new QLineEdit ( d );
	( new QVBoxLayout ( d, 3, 3 ))->addWidget ( ed );
	ed->setFocus ( );

    if ( d->exec() == QDialog::Accepted ) {
        name = ed->text();
    }
    //delete d;
	return name;
}
コード例 #5
0
void KasTaskItem::showPropertiesDialog()
{
    //
    // Create Dialog
    //
    QDialog *dlg = new QDialog( /*kasbar()*/0L, "task_props", false );

    //
    // Title
    //
    KPopupTitle *title = new KPopupTitle( dlg, "title" );
    dlg->setCaption( i18n("Task Properties") );
    title->setText( i18n("Task Properties") );
    title->setIcon( icon() );

    //
    // Tabbed View
    //
    QTabWidget *tabs = new QTabWidget( dlg );
    tabs->addTab( createX11Props( tabs ), i18n("General") );
    tabs->addTab( createTaskProps( task_, tabs ), i18n("Task") );

    tabs->addTab( createTaskProps( this, tabs ), i18n("Item") );
    tabs->addTab( createTaskProps( kasbar(), tabs, false ), i18n("Bar") );

#if 0
    tabs->addTab( createNETProps( tabs ), i18n("NET") );
#endif

    //
    // Layout Dialog
    //
    QVBoxLayout *vbl = new QVBoxLayout( dlg, KDialog::marginHint(), KDialog::spacingHint() );
    vbl->addWidget( title );
    vbl->addWidget( tabs );

    dlg->resize( 470, 500 );
    dlg->show();

}
コード例 #6
0
ファイル: cash_reconcile.cpp プロジェクト: cwarden/quasar
void
CashReconcile::slotReconcile()
{
    if (_lines->selectedItem() == NULL) {
	QString message;
	if (_company.shiftMethod() == Company::BY_STATION) {
	    message = tr("A station must be picked");
	} else {
	    message = tr("An employee must be picked");
	}
	QMessageBox::critical(this, tr("Error"), message);
	return;
    }

    Id station_id = stationId();
    Id employee_id = employeeId();
    Id store_id = _store->getId();
    Id safe_store_id = _safeStore->getId();
    Id safe_id = _safeId->getId();
    Id adjust_id = _adjust->getId();
    Id transfer_id = _transfer->getId();

    Id safe_station_id;
    Id safe_employee_id;
    if (_company.shiftMethod() == Company::BY_STATION)
	safe_station_id = safe_id;
    else
	safe_employee_id = safe_id;

    if (store_id == INVALID_ID) {
	QString message = tr("A store must be entered");
	QMessageBox::critical(this, tr("Error"), message);
	_store->setFocus();
	return;
    }
    if (safe_store_id == INVALID_ID) {
	QString message = tr("A safe store must be entered");
	QMessageBox::critical(this, tr("Error"), message);
	_tabs->showPage(_setup);
	_safeStore->setFocus();
	return;
    }
    if (safe_id == INVALID_ID) {
	QString message = tr("A safe must be entered");
	QMessageBox::critical(this, tr("Error"), message);
	_tabs->showPage(_setup);
	_safeId->setFocus();
	return;
    }
    if (adjust_id == INVALID_ID) {
	QString message = tr("An over/short account must be entered");
	QMessageBox::critical(this, tr("Error"), message);
	_tabs->showPage(_setup);
	_adjust->setFocus();
	return;
    }
    if (transfer_id == INVALID_ID) {
	QString message = tr("A transfer account must be entered");
	QMessageBox::critical(this, tr("Error"), message);
	_tabs->showPage(_setup);
	_transfer->setFocus();
	return;
    }
    if (_shifts.size() == 0) {
	QString message = tr("You must have at least one shift");
	QMessageBox::critical(this, tr("Error"), message);
	return;
    }

    QDate date = _date->getDate();
    if (date.isNull()) {
	QString message = tr("The date to reconcile is required");
	QMessageBox::critical(this, tr("Error"), message);
	_date->setFocus();
	return;
    }

    // Posting time is current time if closing for today or 11:59:59 PM
    QTime time = QTime::currentTime();
    if (date != QDate::currentDate())
	time = QTime(23, 59, 59);

    vector<Shift> shifts = _shifts;
    vector<TenderCount> counts = _counts;

    if (shifts.size() > 1 || counts.size() > 1) {
	// TODO: ask which shifts/counts to use
    }

    QApplication::setOverrideCursor(waitCursor);
    qApp->processEvents();

    Id shift_id = shifts[0].id();
    _tenders.clear();
    _summary.clear();

    // Process shifts and add tenders to summary
    unsigned int i;
    for (i = 0; i < shifts.size(); ++i) {
	const Shift& shift = shifts[i];

	GltxSelect conditions;
	conditions.shift_id = shift.id();
	conditions.activeOnly = true;
	vector<Gltx> gltxs;
	_quasar->db()->select(gltxs, conditions);

	for (unsigned int j = 0; j < gltxs.size(); ++j) {
	    const Gltx& gltx = gltxs[j];

	    for (unsigned int k = 0; k < gltx.tenders().size(); ++k) {
		Id tender_id = gltx.tenders()[k].tender_id;
		fixed amount = gltx.tenders()[k].conv_amt;
		if (gltx.tenders()[k].voided) continue;

		addShiftAmt(tender_id, amount);
	    }
	}
    }

    // Process counts and add tenders to summary
    for (i = 0; i < counts.size(); ++i) {
	const TenderCount& count = counts[i];

	for (unsigned int j = 0; j < count.tenders().size(); ++j) {
	    const TenderInfo& info = count.tenders()[j];
	    addCountAmt(info.tender_id, info.amount);
	}
    }

    // Sort tenders by menu number
    std::sort(_summary.begin(), _summary.end());

    // Prepare over/short transaction
    TenderAdjust adjustment;
    adjustment.setPostDate(date);
    adjustment.setPostTime(time);
    adjustment.setMemo(tr("Over/Short"));
    adjustment.setStoreId(store_id);
    adjustment.setStationId(station_id);
    adjustment.setEmployeeId(employee_id);
    adjustment.setShiftId(shift_id);
    adjustment.setAccountId(adjust_id);

    // Prepare transfer out transaction
    TenderAdjust transOut;
    transOut.setPostDate(date);
    transOut.setPostTime(time);
    transOut.setMemo(tr("Deposit to safe"));
    transOut.setStoreId(store_id);
    transOut.setStationId(station_id);
    transOut.setEmployeeId(employee_id);
    transOut.setShiftId(shift_id);
    transOut.setAccountId(transfer_id);

    // Memo for transfer in depends on method
    QString memo;
    if (station_id != INVALID_ID) {
	Station station;
	_quasar->db()->lookup(station_id, station);
	memo = tr("Deposit from: %1").arg(station.name());
    } else {
	Employee employee;
	_quasar->db()->lookup(employee_id, employee);
	memo = tr("Deposit from: %1").arg(employee.nameFL());
    }

    // Prepare transfer in transaction
    TenderAdjust transIn;
    transIn.setPostDate(date);
    transIn.setPostTime(time);
    transIn.setMemo(memo);
    transIn.setStoreId(safe_store_id);
    transIn.setStationId(safe_station_id);
    transIn.setEmployeeId(safe_employee_id);
    transIn.setAccountId(transfer_id);

    // Setup screen
    QDialog* dialog = new QDialog(this, "Summary", true);
    dialog->setCaption(tr("Reconcile Summary"));

    ListView* tenderList = new ListView(dialog);
    tenderList->addTextColumn(tr("Tender"), 20);
    tenderList->addMoneyColumn(tr("Shifts"));
    tenderList->addMoneyColumn(tr("Counts"));
    tenderList->addMoneyColumn(tr("Over/Short"));
    tenderList->setAllColumnsShowFocus(true);
    tenderList->setSorting(-1);

    QFrame* buttons = new QFrame(dialog);
    QPushButton* post = new QPushButton(tr("Reconcile"), buttons);
    QPushButton* cancel = new QPushButton(tr("Cancel"), buttons);
    cancel->setDefault(true);

    connect(post, SIGNAL(clicked()), dialog, SLOT(accept()));
    connect(cancel, SIGNAL(clicked()), dialog, SLOT(reject()));

    QGridLayout* buttonGrid = new QGridLayout(buttons);
    buttonGrid->setSpacing(3);
    buttonGrid->setMargin(3);
    buttonGrid->setColStretch(0, 1);
    buttonGrid->addWidget(post, 0, 1);
    buttonGrid->addWidget(cancel, 0, 2);

    QGridLayout* grid = new QGridLayout(dialog);
    grid->setSpacing(3);
    grid->setMargin(3);
    grid->setRowStretch(0, 1);
    grid->setColStretch(0, 1);
    grid->addWidget(tenderList, 0, 0);
    grid->addWidget(buttons, 1, 0);

    // Process summary info
    fixed shiftsTotal = 0.0;
    fixed countsTotal = 0.0;
    fixed overShort = 0.0;
    fixed transferAmt = 0.0;
    ListViewItem* last = NULL;
    for (i = 0; i < _summary.size(); ++i) {
	const Tender& tender = _summary[i].tender;
	fixed shiftsAmt = _summary[i].shiftsAmt;
	fixed countsAmt = _summary[i].countsAmt;
	fixed overShortAmt = countsAmt - shiftsAmt;

	// Add to table to show to user
	ListViewItem* item = new ListViewItem(tenderList, last);
	last = item;
	item->setValue(0, tender.name());
	item->setValue(1, shiftsAmt);
	item->setValue(2, countsAmt);
	item->setValue(3, overShortAmt);

	// Add to over/short if there is an amount
	if (overShortAmt != 0.0) {
	    TenderLine info;
	    info.tender_id = tender.id();
	    info.conv_amt = overShortAmt;
	    info.conv_rate = tender.convertRate();
	    info.amount = overShortAmt * tender.convertRate();
	    info.amount.moneyRound();
	    info.is_change = false;
	    info.voided = false;
	    adjustment.tenders().push_back(info);
	    overShort += info.amount;
	}

	// Add counted to transfer in/out
	TenderLine info;
	info.tender_id = tender.id();
	info.conv_amt = countsAmt;
	info.conv_rate = tender.convertRate();
	info.amount = countsAmt * tender.convertRate();
	info.amount.moneyRound();
	info.is_change = false;
	info.voided = false;
	transIn.tenders().push_back(info);

	transferAmt += info.amount;
	info.amount = -info.amount;
	info.conv_amt = -info.conv_amt;
	transOut.tenders().push_back(info);

	shiftsTotal += shiftsAmt;
	countsTotal += countsAmt;
    }

    // Add total line
    ListViewItem* item = new ListViewItem(tenderList, last);
    item->setValue(0, tr("Total"));
    item->setValue(1, shiftsTotal);
    item->setValue(2, countsTotal);
    item->setValue(3, countsTotal - shiftsTotal);

    // Show table to user and allow cancel or post
    QApplication::restoreOverrideCursor();
    int ch = dialog->exec();
    if (ch != QDialog::Accepted) return;

    // Check total over/short
    if (overShort > 5.0 || overShort < -5.0) {
	QString message = tr("Warning - your over/short is large.\n"
			     "Are you sure you mean to post this?");
	int ch = QMessageBox::warning(this, tr("Post?"), message,
				      QMessageBox::No, QMessageBox::Yes);
	if (ch != QMessageBox::Yes) return;
    }

    QApplication::setOverrideCursor(waitCursor);
    qApp->processEvents();

    // Add accounts to adjustment
    adjustment.accounts().push_back(AccountLine(adjust_id, -overShort));
    for (i = 0; i < adjustment.tenders().size(); ++i) {
	Id tender_id = adjustment.tenders()[i].tender_id;
	fixed amount = adjustment.tenders()[i].amount;

	Tender tender;
	findTender(tender_id, tender);

	Id tender_acct = tender.accountId();
	if (_company.shiftMethod() == Company::BY_STATION) {
	    if (adjustment.stationId() == safe_station_id)
		if (tender.safeId() != INVALID_ID)
		    tender_acct = tender.safeId();
	} else {
	    if (adjustment.employeeId() == safe_employee_id)
		if (tender.safeId() != INVALID_ID)
		    tender_acct = tender.safeId();
	}

	adjustment.accounts().push_back(AccountLine(tender_acct, amount));
    }

    // Add accounts to transfer out
    transOut.accounts().push_back(AccountLine(transfer_id, transferAmt));
    for (i = 0; i < transOut.tenders().size(); ++i) {
	Id tender_id = transOut.tenders()[i].tender_id;
	fixed amount = transOut.tenders()[i].amount;

	Tender tender;
	findTender(tender_id, tender);

	Id tender_acct = tender.accountId();
	if (_company.shiftMethod() == Company::BY_STATION) {
	    if (transOut.stationId() == safe_station_id)
		if (tender.safeId() != INVALID_ID)
		    tender_acct = tender.safeId();
	} else {
	    if (transOut.employeeId() == safe_employee_id)
		if (tender.safeId() != INVALID_ID)
		    tender_acct = tender.safeId();
	}

	transOut.accounts().push_back(AccountLine(tender_acct, amount));
    }

    // Add accounts to transfer in
    transIn.accounts().push_back(AccountLine(transfer_id, -transferAmt));
    for (i = 0; i < transIn.tenders().size(); ++i) {
	Id tender_id = transIn.tenders()[i].tender_id;
	fixed amount = transIn.tenders()[i].amount;

	Tender tender;
	findTender(tender_id, tender);

	Id tender_acct = tender.safeId();
	if (tender_acct == INVALID_ID)
	    tender_acct = tender.accountId();

	transIn.accounts().push_back(AccountLine(tender_acct, amount));
    }

    // Post adjustment if any tenders
    if (adjustment.tenders().size() > 0) {
	QApplication::restoreOverrideCursor();
	if (!_quasar->db()->create(adjustment)) {
	    QString message = tr("Failed creating over/short transaction");
	    QMessageBox::critical(this, tr("Error"), message);
	    return;
	}
    }

    // Post transfers
    if (!_quasar->db()->create(transOut)) {
	QApplication::restoreOverrideCursor();
	QString message = tr("Failed creating transfer out transaction");
	QMessageBox::critical(this, tr("Error"), message);
	if (adjustment.id() != INVALID_ID)
	    _quasar->db()->remove(adjustment);
	return;
    }
    if (!_quasar->db()->create(transIn)) {
	QApplication::restoreOverrideCursor();
	QString message = tr("Failed creating transfer in transaction");
	QMessageBox::critical(this, tr("Error"), message);
	if (adjustment.id() != INVALID_ID)
	    _quasar->db()->remove(adjustment);
	_quasar->db()->remove(transOut);
	return;
    }

    // Link the transfers
    _quasar->db()->linkTx(transOut.id(), transIn.id());

    // Set shift in shifts
    for (int cnt = shifts.size() - 1; cnt >= 0; --cnt) {
	Shift shift = shifts[cnt];
	shift.setShiftId(shift_id);
	shift.setAdjustmentId(adjustment.id());
	shift.setTransferId(transOut.id());
	_quasar->db()->update(shifts[cnt], shift);
    }

    // Set shift in counts
    for (i = 0; i < counts.size(); ++i) {
	TenderCount count = counts[i];
	count.setShiftId(shift_id);
	_quasar->db()->update(counts[i], count);
    }

    Company orig, company;
    _quasar->db()->lookup(orig);
    company = orig;

    company.setSafeStore(safe_store_id);
    company.setSafeStation(safe_station_id);
    company.setSafeEmployee(safe_employee_id);
    company.setOverShortAccount(adjust_id);
    company.setTransferAccount(transfer_id);
    _quasar->db()->update(orig, company);

    QApplication::restoreOverrideCursor();
    slotRefresh();
}
コード例 #7
0
ファイル: changedialog.cpp プロジェクト: AMDmi3/qucs
// -----------------------------------------------------------------------
// Is called if the "Replace"-button is pressed.
void ChangeDialog::slotButtReplace()
{
  Expr.setWildcard(true);  // switch into wildcard mode
  Expr.setPattern(CompNameEdit->text());
  if(!Expr.isValid()) {
    QMessageBox::critical(this, tr("Error"),
	  tr("Regular expression for component name is invalid."));
    return;
  }

  // create dialog showing all found components
  QDialog *Dia = new QDialog(this);
  Dia->setCaption(tr("Found Components"));
  QVBoxLayout *Dia_All = new QVBoxLayout(Dia);
  Dia_All->setSpacing(3);
  Dia_All->setMargin(5);
  
  QScrollArea *Dia_Scroll = new QScrollArea(Dia);
  //Dia_Scroll->setMargin(5);
  Dia_All->addWidget(Dia_Scroll);
  
  QVBoxLayout *Dia_Box = new QVBoxLayout(Dia_Scroll->viewport());
  Dia_Scroll->insertChild(Dia_Box);
  QLabel *Dia_Label = new QLabel(tr("Change properties of\n")
                               + tr("these components ?"), Dia);
  Dia_All->addWidget(Dia_Label);
  
  QHBoxLayout *Dia_h = new QHBoxLayout(Dia);
  Dia_h->setSpacing(5);
  QPushButton *YesButton = new QPushButton(tr("Yes"));
  QPushButton *CancelButton = new QPushButton(tr("Cancel"));
  Dia_h->addWidget(YesButton);
  Dia_h->addWidget(CancelButton);
  connect(YesButton, SIGNAL(clicked()), Dia, SLOT(accept()));
  connect(CancelButton, SIGNAL(clicked()), Dia, SLOT(reject()));
  
  Dia_All->addLayout(Dia_h);

  QList<QCheckBox *> pList;
  QCheckBox *pb;
  Component *pc;
  QStringList List;
  QString str;
  int i1, i2;
  // search through all components
  for(pc = Doc->Components->first(); pc!=0; pc = Doc->Components->next()) {
    if(matches(pc->Model)) {
      if(Expr.search(pc->Name) >= 0)
        for(Property *pp = pc->Props.first(); pp!=0; pp = pc->Props.next())
          if(pp->Name == PropNameEdit->currentText()) {
            pb = new QCheckBox(pc->Name);
            Dia_Box->addWidget(pb);   
            pList.append(pb);
            pb->setChecked(true);
            i1 = pp->Description.find('[');
            if(i1 < 0)  break;  // no multiple-choice property

            i2 = pp->Description.findRev(']');
            if(i2-i1 < 2)  break;
            str = pp->Description.mid(i1+1, i2-i1-1);
            str.replace( QRegExp("[^a-zA-Z0-9_,]"), "" );
            List = List.split(',',str);
            if(List.findIndex(NewValueEdit->text()) >= 0)
              break;    // property value is okay

            pb->setChecked(false);
            pb->setEnabled(false);
            break;
          }
    }
  }
/*
  QColor theColor;
  if(pList.isEmpty()) {
    YesButton->setEnabled(false);
    theColor =
       (new QLabel(tr("No match found!"), Dia_Box))->paletteBackgroundColor();
  }
  else  theColor = pList.current()->paletteBackgroundColor();
*/
  //Dia_Scroll->viewport()->setPaletteBackgroundColor(theColor);
  Dia->resize(50, 300);


  // show user all components found
  int Result = Dia->exec();
  if(Result != QDialog::Accepted) return;


  bool changed = false;
  // change property values
  
  QListIterator<QCheckBox *> i(pList);
  while(i.hasNext()){
    pb = i.next();
    if(!pb->isChecked())  continue;

    for(pc = Doc->Components->first(); pc!=0; pc = Doc->Components->next()) {
      if(pb->text() != pc->Name)  continue;

      for(Property *pp = pc->Props.first(); pp!=0; pp = pc->Props.next()) {
        if(pp->Name != PropNameEdit->currentText())  continue;

        int tx_Dist, ty_Dist, tmp;
        pc->textSize(tx_Dist, ty_Dist);
        tmp = pc->tx+tx_Dist - pc->x1;
        if((tmp > 0) || (tmp < -6))  tx_Dist = 0; // remember text position
        tmp = pc->ty+ty_Dist - pc->y1;
        if((tmp > 0) || (tmp < -6))  ty_Dist = 0;

        pp->Value = NewValueEdit->text();

        int dx, dy;
        pc->textSize(dx, dy);   // correct text position
        if(tx_Dist != 0) {
          pc->tx += tx_Dist-dx;
          tx_Dist = dx;
        }
        if(ty_Dist != 0) {
          pc->ty += ty_Dist-dy;
          ty_Dist = dy;
        }

        // apply changes to schematic symbol
        Doc->recreateComponent(pc);
        changed = true;
        break;
      }
      break;
    }
  }

  delete Dia_All;
  delete Dia;
  if(changed) accept();
  else reject();
}
コード例 #8
0
ファイル: item_transfer.cpp プロジェクト: cwarden/quasar
void
ItemTransfer::slotSearch()
{
    QDialog* dialog = new QDialog(this, "Search", true);
    dialog->setCaption(tr("Item Search"));

    QLabel* numberLabel = new QLabel(tr("Item Number:"), dialog);
    LineEdit* numberWidget = new LineEdit(dialog);
    QLabel* descLabel = new QLabel(tr("Description:"), dialog);
    LineEdit* descWidget = new LineEdit(dialog);
    QCheckBox* startOver = new QCheckBox(tr("Start search at top?"), dialog);

    QFrame* buttons = new QFrame(dialog);
    QPushButton* next = new QPushButton(tr("&Next"), buttons);
    QPushButton* cancel = new QPushButton(tr("&Cancel"), buttons);
    next->setDefault(true);

    QGridLayout* buttonGrid = new QGridLayout(buttons);
    buttonGrid->setMargin(6);
    buttonGrid->setSpacing(10);
    buttonGrid->addWidget(next, 0, 1);
    buttonGrid->addWidget(cancel, 0, 2);

    QGridLayout* grid = new QGridLayout(dialog);
    grid->setMargin(6);
    grid->setSpacing(10);
    grid->addWidget(numberLabel, 0, 0);
    grid->addWidget(numberWidget, 0, 1, AlignLeft | AlignVCenter);
    grid->addWidget(descLabel, 1, 0);
    grid->addWidget(descWidget, 1, 1, AlignLeft | AlignVCenter);
    grid->addMultiCellWidget(startOver, 2, 2, 0, 1, AlignLeft | AlignVCenter);
    grid->addMultiCellWidget(buttons, 3, 3, 0, 1);

    connect(next, SIGNAL(clicked()), dialog, SLOT(accept()));
    connect(cancel, SIGNAL(clicked()), dialog, SLOT(reject()));

    _items->setFocus();
    startOver->setChecked(true);

    while (true) {
	if (dialog->exec() != QDialog::Accepted)
	    break;

	QString number = numberWidget->text();
	QString desc = descWidget->text();
	if (number.isEmpty() && desc.isEmpty()) {
	    QString message = tr("No search criteria given");
	    QMessageBox::critical(this, tr("Error"), message);
	    continue;
	}

	int startRow = -1;
	if (!startOver->isChecked())
	    startRow = _items->currentRow();

	int foundRow = -1;
	for (int row = startRow + 1; row < _items->rows(); ++row) {
	    QString rowNumber = _items->cellValue(row, 0).toPlu().number();
	    QString rowDesc = _items->cellValue(row, 1).toString();

	    if (!number.isEmpty() && rowNumber.contains(number, false)) {
		foundRow = row;
		break;
	    }
	    if (!desc.isEmpty() && rowDesc.contains(desc, false)) {
		foundRow = row;
		break;
	    }
	}

	if (foundRow == -1 && startOver->isChecked()) {
	    QString message = tr("No matches found");
	    QMessageBox::critical(this, tr("Error"), message);
	} else if (foundRow == -1 && !startOver->isChecked()) {
	    QString message = tr("No further matches found");
	    int choice = QMessageBox::critical(this, tr("Error"), message,
					       tr("Start Over"), tr("Cancel"));
	    if (choice != 0) break;
	    _items->setCurrentCell(0, 0);
	    startOver->setChecked(true);
	} else {
	    _items->setCurrentCell(foundRow, 0);
	    startOver->setChecked(false);
	}
    }

    delete dialog;
}