RSS Git Download  Clone
Raw Blame History
/*******************************************************************************
 *	BWidgets.cc	BWidgets BEAM QT Widgets
 *	T.Barnaby,	BEAM Ltd,	2009-07-29
 *	Copyright (c) 2022 All Right Reserved, Beam Ltd, https://www.beam.ltd.uk
 *	For license see LICENSE.txt at the root of the beamlib source tree.
 *******************************************************************************
 */
#include <BWidgets.h>

#include <qtablewidget.h>
#include <qcoreevent.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qmessagebox.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <qspinbox.h>
#include <qevent.h>
#include <qheaderview.h>
#include <math.h>
#include <ctype.h>

int blayoutSpacing = 2;					// Default spacing of layout widgets

BHBox::BHBox(QWidget* parent) : QFrame(parent), olayout(this){
	blayoutSetSpacing(olayout, blayoutSpacing);
}

QHBoxLayout& BHBox::layout(){
	return olayout;
}

void BHBox::childEvent(QChildEvent* event){
	QWidget::childEvent(event);
	if((event->type() == QEvent::ChildAdded) && event->child()->isWidgetType())
		olayout.addWidget((QWidget*)event->child());
}

BVBox::BVBox(QWidget* parent) : QFrame(parent), olayout(this){
	blayoutSetSpacing(olayout, blayoutSpacing);
}

QVBoxLayout& BVBox::layout(){
	return olayout;
}

void BVBox::childEvent(QChildEvent* event){
	QWidget::childEvent(event);
	if((event->type() == QEvent::ChildAdded) && event->child()->isWidgetType())
		olayout.addWidget((QWidget*)event->child());
}

BGrid::BGrid(BUInt size, Qt::Orientation orientation, QWidget* parent) : QFrame(parent), olayout(this), oorientation(orientation), osize(size){
	orow = 0;
	ocolumn = 0;
	blayoutSetSpacing(olayout, blayoutSpacing);
}

QGridLayout& BGrid::layout(){
	return olayout;
}

void BGrid::childEvent(QChildEvent* event){
	QWidget::childEvent(event);
	if((event->type() == QEvent::ChildAdded) && event->child()->isWidgetType())
		olayout.addWidget((QWidget*)event->child(), orow, ocolumn);

	if(oorientation == Qt::Horizontal){
		if(++ocolumn >= osize){
			ocolumn = 0;
			orow++;
		}
	}
	else {
		if(++orow >= osize){
			orow = 0;
			ocolumn++;
		}
	}
}

BGroupBox::BGroupBox(QString title, BUInt size, Qt::Orientation orientation, QWidget* parent) : QGroupBox(title, parent), olayout(this), oorientation(orientation), osize(size){
	orow = 0;
	ocolumn = 0;
	blayoutSetSpacing(olayout, blayoutSpacing);
	setAlignment(Qt::AlignLeft);
}

QGridLayout& BGroupBox::layout(){
	return olayout;
}

void BGroupBox::childEvent(QChildEvent* event){
	QWidget::childEvent(event);
	if((event->type() == QEvent::ChildAdded) && event->child()->isWidgetType())
		olayout.addWidget((QWidget*)event->child(), orow, ocolumn);

	if(oorientation == Qt::Horizontal){
		if(++ocolumn >= osize){
			ocolumn = 0;
			orow++;
		}
	}
	else {
		if(++orow >= osize){
			orow = 0;
			ocolumn++;
		}
	}
}

BGroupBoxGrid::BGroupBoxGrid(QString title, QWidget* parent) : QGroupBox(title, parent), olayout(this){
	blayoutSetSpacing(olayout, blayoutSpacing);
}

void BGroupBoxGrid::addWidget(QWidget* w, int row, int col, int rowSpan, int colSpan, Qt::Alignment alignment){
	olayout.addWidget(w, row, col, rowSpan, colSpan, alignment);
}

QGridLayout& BGroupBoxGrid::layout(){
	return olayout;
}


BWTableWidgetItem::BWTableWidgetItem(const BWTableWidgetItem& other) : QTableWidgetItem(other){
	orow = other.orow;
}

BWTableWidgetItem::BWTableWidgetItem(int row, const QString& text) : QTableWidgetItem(text, QTableWidgetItem::UserType){
	orow = row;
}

BWTableWidgetItem::BWTableWidgetItem(int row) : QTableWidgetItem(QTableWidgetItem::UserType){
	orow = row;
}

QTableWidgetItem* BWTableWidgetItem::clone() const {
	return new BWTableWidgetItem(*this);
}

int BWTableWidgetItem::dataRow() const {
	return orow;
}


BWTableView::BWTableView(QWidget* parent) : QTableWidget(parent){
	oeditable = 0;
	setEditable(oeditable);
	setSelectionBehavior(QAbstractItemView::SelectRows);
	setSelectionMode(QAbstractItemView::SingleSelection);
	
	setItemPrototype(new BWTableWidgetItem());
}

BWTableView::~BWTableView(){
}

void BWTableView::setEditable(int on){
	oeditable = on;
	if(on)
		setEditTriggers(QAbstractItemView::AllEditTriggers);
	else
		setEditTriggers(QAbstractItemView::NoEditTriggers);

}

void BWTableView::setColumns(BStringList columns){
	unsigned int	c;
	
	setColumnCount(columns.number());
	
	for(c = 0; c < columns.number(); c++){
		setHorizontalHeaderItem(c, new QTableWidgetItem(columns[c]));
	}
}

void BWTableView::setColumnWidths(BStringList columns){
	unsigned int	c;
	
	for(c = 0; c < columns.number(); c++){
		setColumnWidth(c, columns[c].retInt());
	}
}

void BWTableView::setColumnAlignment(int col,  int alignment){
	 int	r;
	
	for(r = 0; r < rowCount(); r++){
		item(r, col)->setTextAlignment(alignment);
	}
}

void BWTableView::setText(int row, int col, BString value){
	setItem(row, col, new BWTableWidgetItem(row, value));
}

BString BWTableView::getText(int row, int col){
	QTableWidgetItem*	i = item(row, col);
	
	if(i)
		return i->text();
	else
		return "";
}

void BWTableView::set(int row, int col, int value){
	BWTableWidgetItem*	item = new BWTableWidgetItem(row);

	item->setData(Qt::EditRole, value);   
	setItem(row, col, item);
}

void BWTableView::set(int row, int col, BUInt value){
	BWTableWidgetItem*	item = new BWTableWidgetItem(row);

	item->setData(Qt::EditRole, value);   
	setItem(row, col, item);
}

void BWTableView::set(int row, int col, BString value){
	BWTableWidgetItem*	item = new BWTableWidgetItem(row);

	item->setData(Qt::EditRole, QString(value.retStr()));
	setItem(row, col, item);
}

void BWTableView::set(int row, int col, double value){
	BWTableWidgetItem*	item = new BWTableWidgetItem(row);

	item->setData(Qt::EditRole, value);   
	setItem(row, col, item);
}

BList<int> BWTableView::selectedDataRows(){
	QModelIndexList		selected = selectionModel()->selectedRows();
	BList<int>		selList;
	int			s;
	int			r;

	for(s = 0; s < selected.size(); s++){
		BWTableWidgetItem*	wi;

		r = selected[s].row();
		wi = (BWTableWidgetItem*)item(r, 0);
		selList.append(wi->dataRow());
	}

	return selList;
}

int BWTableView::currentDataRow(){
	int			r;
	BWTableWidgetItem*	wi;
	
	if((r = currentRow()) < 0)
		return r;

	wi = (BWTableWidgetItem*)item(r, 0);
	return wi->dataRow();
}

Bool BWTableView::isDataRowSelected(int r){
	QModelIndexList		selected = selectionModel()->selectedRows();

	for(int i = 0; i < selected.size(); i++){
		BWTableWidgetItem*	wi;

		wi = (BWTableWidgetItem*)item(selected[i].row(), 0);
		if(wi->dataRow() == r)
			return 1;
	}
	
	return 0;
}

BWTable::BWTable(QWidget* parent) : BVBox(parent){
	QPushButton*	b;

	owTable = new BWTableView(this);
	owButtons = new BHBox(this);

	b = new QPushButton("Append Row", owButtons);
	owButtonList.append(b);
	connect(b, SIGNAL(clicked()), this, SLOT(appendRow()));

	b = new QPushButton("Delete Row", owButtons);
	owButtonList.append(b);
	connect(b, SIGNAL(clicked()), this, SLOT(deleteRow()));
}

BWTable::~BWTable(){
}

BWTableView* BWTable::table(){
	return owTable;
}

void BWTable::setColumns(BStringList columns){
	owTable->setColumns(columns);
}

void BWTable::setRowCount(int num){
	owTable->setRowCount(num);
}

void BWTable::setText(int row, int col, BString value){
	owTable->setText(row, col, value);
}

BString BWTable::getText(int row, int col){
	QTableWidgetItem*	i = owTable->item(row, col);
	
	if(i)
		return i->text();
	else
		return "";
}

void BWTable::setEditable(int on){
	BIter	i;
	
	owTable->setEditable(on);
	
	for(owButtonList.start(i); !owButtonList.isEnd(i); owButtonList.next(i)){
		owButtonList[i]->setEnabled(on);
	}
}

void BWTable::appendRow(){
	int		r;

	if((r = owTable->currentRow()) < 0){
		r = owTable->rowCount();
	}
	else {
		r++;
	}
	owTable->insertRow(r);
	owTable->setCurrentCell(r, 0);
}

void BWTable::deleteRow(){
	int		r;
	
	if((r = owTable->currentRow()) < 0){
		BWMessageBox::warning(this, "Error", "No item selected");
		return;
	}

	owTable->removeRow(r);
}

void BWTable::addButton(BString name, BString memberFunc){
	QPushButton*	b;
	
	b = new QPushButton(name, owButtons);
	owButtonList.append(b);
	connect(b, SIGNAL(clicked()), this, memberFunc);	
}

BList<int> BWTable::selectedDataRows(){
	return owTable->selectedDataRows();
}

Bool BWTable::isDataRowSelected(int r){
	return owTable->isDataRowSelected(r);
}


BWEditListSelect::BWEditListSelect(QWidget* parent, BStringList selectionList) : BHBox(parent){
	setSelection(selectionList);
}

BWEditListSelect::~BWEditListSelect(){
}

void BWEditListSelect::setReadOnly(int on){
	BIter	i;
	
	for(oboxes.start(i); !oboxes.isEnd(i); oboxes.next(i)){
		oboxes[i]->setDisabled(on);
	}
}


void BWEditListSelect::setSelection(BStringList selectionList){
	BIter	i;
	
	oselectionList = selectionList;

	for(oboxes.start(i); !oboxes.isEnd(i); ){
		delete oboxes[i];
		oboxes.del(i);
	}
	
	for(oselectionList.start(i); !oselectionList.isEnd(i); oselectionList.next(i)){
		oboxes.append(new QCheckBox(oselectionList[i], this));
	}
}

void BWEditListSelect::setString(BString str){
	BStringList	sel = bstringToList(str);
	BIter		i1;
	BIter		i2;
	
	for(oboxes.start(i1); !oboxes.isEnd(i1); oboxes.next(i1)){
		oboxes[i1]->setChecked(0);
		for(sel.start(i2); !sel.isEnd(i2); sel.next(i2)){
			if(sel[i2] == BString(oboxes[i1]->text()))
				oboxes[i1]->setChecked(1);
		}
	}
}

BString BWEditListSelect::getString(){
	BStringList	sel;
	BIter		i;
	
	for(oboxes.start(i); !oboxes.isEnd(i); oboxes.next(i)){
		if(oboxes[i]->isChecked())
			sel.append(oboxes[i]->text());
	}
	return blistToString(sel);
}


BWEditComboBox::BWEditComboBox(QWidget* parent, BStringList options, int editable) : BHBox(parent), owComboBox(this){
	connect(&owComboBox, SIGNAL(activated(int)), this, SLOT(update()));
	BIter	i;
	
	owComboBox.setEditable(editable);
	for(options.start(i); !options.isEnd(i); options.next(i)){
		addItem(options[i]);
	}
}

BWEditComboBox::~BWEditComboBox(){
}

void BWEditComboBox::setReadOnly(int on){
	owComboBox.setDisabled(on);
}

void BWEditComboBox::clear(){
	owComboBox.clear();
	ostringList.clear();
}

void BWEditComboBox::addItem(BString str){
	owComboBox.addItem(str);
	ostringList.append(str);
}

void BWEditComboBox::setSelection(BStringList selectionList){
	BIter	i;
	BString	v = getString();
	
	clear();
	for(selectionList.start(i); !selectionList.isEnd(i); selectionList.next(i)){
		addItem(selectionList[i]);
	}
	setString(v);
}

void BWEditComboBox::setCurrentIndex(int item){
	owComboBox.setCurrentIndex(item);
}

void BWEditComboBox::setString(BString str){
	BUInt	i;

	for(i = 0; i < ostringList.size(); i++){
		if(ostringList[i] == str){
			owComboBox.setCurrentIndex(i);
			return;
		}
	}
	owComboBox.setCurrentIndex(0);
}

BString BWEditComboBox::getString(){
	return owComboBox.currentText();
}

int BWEditComboBox::getIndex(){
	return owComboBox.currentIndex();
}

void BWEditComboBox::update(){
	emit valueChanged(getString());
}


BWEditMoney::BWEditMoney(QWidget* parent, BTimeStamp timeStamp) : BHBox(parent){
	new QLabel("Val:", this); owValue = new QLineEdit(this);
	new QLabel("Vat:", this); owVat = new QLineEdit(this);
	new QLabel("Tot:", this); owTotal = new QLineEdit(this);
	connect(owValue, SIGNAL(textEdited(const QString&)), this, SLOT(updateValue()));
	connect(owVat, SIGNAL(textEdited(const QString&)), this, SLOT(updateVat()));
	connect(owTotal, SIGNAL(textEdited(const QString&)), this, SLOT(updateTotal()));
}

BWEditMoney::~BWEditMoney(){
}

void BWEditMoney::setReadOnly(int on){
	owValue->setReadOnly(on);
	owVat->setReadOnly(on);
	owTotal->setReadOnly(on);
}

void BWEditMoney::setPaletteBackgroundColor (const QColor& colour){
	QPalette p = palette();
	
	p.setColor(backgroundRole(), colour);
	setPalette(p);
}

void BWEditMoney::setMoney(double value, double vat){
	setValue(owValue, value);
	setValue(owVat, vat);
	setValue(owTotal, value + vat);
}

void BWEditMoney::getMoney(double& value, double& vat){
	value = getValue(owValue);
	vat = getValue(owVat);
}

void BWEditMoney::updateValue(){
	setValue(owTotal, getValue(owValue) + getValue(owVat));
	emit valueChanged();
}
void BWEditMoney::updateVat(){
	setValue(owTotal, getValue(owValue) + getValue(owVat));
	emit valueChanged();
}
void BWEditMoney::updateTotal(){
	double	v;
	
	v = round(getValue(owTotal) / 1.20);
	setValue(owValue, v);
	setValue(owVat, getValue(owTotal) - v);

	emit valueChanged();
}

void BWEditMoney::setValue(QLineEdit* w, double v){
	BString	s;

	s.printf("%.2f", v);
	w->setText(s);
}

double BWEditMoney::getValue(QLineEdit* w){
	return w->text().toDouble();
}

double BWEditMoney::round(double value){
        return ( floor(value * 100.0 + 0.5) / 100.0 );
}









BString justify(BString str){
	BString	s;
	int		x = 0;
	const char*	p = str;
	
	while(*p){
		if(*p == '\n')
			x = 0;
		if(x >= 80){
			s = s + "\n";
			x = 0;
		}
		s += *p++;
		x++;
	}

	return s;
}

int BWMessageBox::warning(QWidget* parent, const QString& caption, const QString& text, const QString& button0Text, const QString& button1Text, const QString& button2Text, int defaultButtonNumber, int escapeButtonNumber){
	BString	str = text;

	return QMessageBox::warning(parent, caption, str.justify(0, 80), button0Text, button1Text, button2Text, defaultButtonNumber, escapeButtonNumber);
}




BFieldEdit::BFieldEdit(QWidget* parent) : QLineEdit(parent){
	QFont		f = font();

	ofield = 0;
	oblank = 0;
	
	f.setFixedPitch(1);
	setFont(f);
}

void BFieldEdit::setSize(){
	int		w = 0;
	unsigned int	i;

	for(i = 0; i < ofields.size(); i++){
		w += ofields[i].osize;
		w += ofields[i].opost.len();
	}
	
#if QT_VERSION >= 0x050D00
	setFixedWidth(fontMetrics().horizontalAdvance("0") * w + 14);
#else
	setFixedWidth(fontMetrics().width("0") * w + 14);
#endif
	setMaxLength(w);
}

void BFieldEdit::updateFromFields(){
	BString		l;
	BString		s;
	unsigned int	i;

	updatePos();
	
	if(!oblank){
		for(i = 0; i < ofields.size(); i++){
			l.printf("%0*d", ofields[i].osize, ofields[i].ovalue);
			s = s + l + ofields[i].opost;
		}
	}
		
	setText(s);
	setCursorPosition(0);
	if(hasFocus() && !isReadOnly())
		setSelection(ofields[ofield].opos, ofields[ofield].osize);
	validate();
}

void BFieldEdit::updateFromText(){
	BString		s = text();
	unsigned int	i;

	updatePos();
	
	for(i = 0; i < ofields.size(); i++){
		ofields[i].ovalue = atoi(s.subString(ofields[i].opos, ofields[i].osize));
	}
}

void BFieldEdit::updatePos(){
	int	n;
	
	for(n = ofields.size() - 1; n >= 0; n--){
		if(cursorPosition() >= ofields[n].opos){
			ofield = n;
			break;
		}
	}
}

int BFieldEdit::validate(int v){
	unsigned int	f;
	
	for(f = 0; f < ofields.size(); f++){
		if(ofields[f].ovalue > ofields[f].omax)
			v = 0;
		if(ofields[f].ovalue < ofields[f].omin)
			v = 0;
	}

#if QT_VERSION >= 0x040000
	QPalette	pal = palette();
	if(!v){
		pal.setColor(backgroundRole(), Qt::red);
	}
	else {
		pal.setColor(backgroundRole(), Qt::white);
	}
	setPalette(pal);
#else
	if(!v){
		setPaletteBackgroundColor(QColor("red"));
	}
	else {
		setPaletteBackgroundColor(QColor("white"));
	}
#endif
	return v;
}

void BFieldEdit::setBlank(Bool on){
	oblank = on;
}

void BFieldEdit::keyPressEvent(QKeyEvent* event){
	BError	err;
	
	if(isReadOnly())
		return;

#if QT_VERSION >= 0x040000
	if(event->modifiers() & ~Qt::KeypadModifier){
		QLineEdit::keyPressEvent(event);
		return;
	}
#else
	if(event->stateAfter() & ~Qt::Keypad){
		QLineEdit::keyPressEvent(event);
		return;
	}
#endif
	updatePos();
	
	if(event->key() == Qt::Key_Up){
		ofields[ofield].ovalue++;
		if(ofields[ofield].ovalue > ofields[ofield].omax)
			ofields[ofield].ovalue = ofields[ofield].omax;
		if(ofields[ofield].ovalue < ofields[ofield].omin)
			ofields[ofield].ovalue = ofields[ofield].omin;
		updateFromFields();
		if(validate())
			emit changed();
	}
	else if(event->key() == Qt::Key_Down){
		ofields[ofield].ovalue--;
		if(ofields[ofield].ovalue < ofields[ofield].omin)
			ofields[ofield].ovalue = ofields[ofield].omin;
		if(ofields[ofield].ovalue > ofields[ofield].omax)
			ofields[ofield].ovalue = ofields[ofield].omax;
		updateFromFields();
		if(validate())
			emit changed();
	}
	else if(event->key() == Qt::Key_Home){
		ofield = 0;
		setCursorPosition(ofields[ofield].opos);
		updateFromFields();
	}
	else if(event->key() == Qt::Key_End){
		ofield = ofields.size()-1;
		setCursorPosition(ofields[ofield].opos);
		updateFromFields();
	}
	else if(event->key() == Qt::Key_Right){
		if(hasSelectedText()){
			if(++ofield > ofields.size())
				ofield = ofields.size();
			setCursorPosition(ofields[ofield].opos);
			updateFromFields();
		}
		else {
			QLineEdit::keyPressEvent(event);
			updatePos();

			if(cursorPosition() == ofields[ofield].opos)
				updateFromFields();
		}
	}
	else if(event->key() == Qt::Key_Left){
		if(hasSelectedText()){
			if(ofield > 0)
				ofield--;
			setCursorPosition(ofields[ofield].opos);
			updateFromFields();
		}
		else {
			QLineEdit::keyPressEvent(event);
			updatePos();
			if(cursorPosition() == ofields[ofield].opos)
				updateFromFields();
		}
	}
	else if((ofields[ofield].opost != "") && (event->key() == ofields[ofield].opost[0])){
		ofield++;
		setCursorPosition(ofields[ofield].opos);
		updateFromFields();
	}
	else if(isdigit(event->key())){
		BString s = text();
		int	p = cursorPosition();

		if(hasSelectedText()){
			setSelection(ofields[ofield].opos, ofields[ofield].osize);
			if(ofields[ofield].osize == 4)
				insert("000");
			else
				insert("0");
			QLineEdit::keyPressEvent(event);
		}
		else {
			setCursorPosition(ofields[ofield].opos);
			del();
			setCursorPosition(p - 1);
			QLineEdit::keyPressEvent(event);
		}
		updateFromText();

		if(validate())
			emit changed();
	}
		
}

void BFieldEdit::focusInEvent(QFocusEvent* event){
	QLineEdit::focusInEvent(event);
	setCursorPosition(ofields[ofield].opos);
	updateFromFields();
}


void BFieldEdit::focusOutEvent(QFocusEvent* event){
	updateFromFields();
	QLineEdit::focusOutEvent(event);
}

void BFieldEdit::mouseReleaseEvent(QMouseEvent* event){
	int		p = cursorPosition();
	unsigned int	f;
	
	QLineEdit::mouseReleaseEvent(event);
	if(!hasSelectedText()){
		for(f = 0; f < ofields.size(); f++){
			if((p >= ofields[f].opos) && (p < (ofields[f].opos + ofields[f].osize))){
				setCursorPosition(ofields[f].opos + ofields[f].osize);
				break;
			}
		}
	}
}

void BFieldEdit::contextMenuEvent(QContextMenuEvent* event){
}

void BFieldEdit::wheelEvent(QWheelEvent* event){
#if QT_VERSION >= 0x050D00
	if(event->angleDelta().y() > 0){
#else
	if(event->delta() > 0){
#endif
		ofields[ofield].ovalue++;
		if(ofields[ofield].ovalue > ofields[ofield].omax)
			ofields[ofield].ovalue = ofields[ofield].omax;
		if(ofields[ofield].ovalue < ofields[ofield].omin)
			ofields[ofield].ovalue = ofields[ofield].omin;
		updateFromFields();
	}
	else {
		ofields[ofield].ovalue--;
		if(ofields[ofield].ovalue < ofields[ofield].omin)
			ofields[ofield].ovalue = ofields[ofield].omin;
		if(ofields[ofield].ovalue > ofields[ofield].omax)
			ofields[ofield].ovalue = ofields[ofield].omax;
		updateFromFields();
	}
	if(validate())
		emit changed();
}

BDate	BWEditDate::gdate;

BWEditDate::BWEditDate(QWidget* parent, Format format) : BFieldEdit(parent), oformat(format){
	if((oformat == ISO) || (oformat == ISO_BLANK)){
		ofields.append(BField(0, 4, "-", 0, 9999, 0));
		ofields.append(BField(5, 2, "-", 1, 12, 1));
		ofields.append(BField(8, 2, "", 1, 31, 1));
	}
	else {
		ofields.append(BField(0, 2, "-", 1, 31, 1));
		ofields.append(BField(3, 2, "-", 1, 12, 1));
		ofields.append(BField(6, 4, " ", 0, 9999, 0));
	}

	setToolTip("BWEditDate allows the edit of date information. Press n for now, c for clear, s for start of time, e for end of time and p for a previous setting.");
	setSize();
	clearWhenNotSet();
	updateFromFields();
}

void BWEditDate::setReadOnly(int on){
	QLineEdit::setReadOnly(on);
}

void BWEditDate::setDate(BDate date){
	odate = date;
	clearWhenNotSet();

	if((oformat == ISO) || (oformat == ISO_BLANK)){
		ofields[2].ovalue = date.day();
		ofields[1].ovalue = date.month();
		ofields[0].ovalue = date.year();
	}
	else {
		ofields[0].ovalue = date.day();
		ofields[1].ovalue = date.month();
		ofields[2].ovalue = date.year();
	}
	updateFromFields();
}

BDate BWEditDate::getDate(){
	BDate	date;
	
	if((oformat == ISO) || (oformat == ISO_BLANK)){
		date.set(ofields[0].ovalue, ofields[1].ovalue, ofields[2].ovalue);
	}
	else {
		date.set(ofields[2].ovalue, ofields[1].ovalue, ofields[0].ovalue);
	}
	gdate = date;

	return date;
}

void BWEditDate::keyPressEvent(QKeyEvent* event){
	BString	k = event->text();
	
	if(isReadOnly()){
		BFieldEdit::keyPressEvent(event);
		return;
	}

	if(oblank){
		setBlank(0);
		updateFromFields();
	}
	if(k == "n"){
		setDate(BDate("now"));	
	}
	else if((k == "c") || (event->key() == Qt::Key_Delete)){
		setDate(BDate());	
	}
	else if(k == "s"){
		setDate(BDate("first"));	
	}
	else if(k == "e"){
		setDate(BDate("last"));	
	}
	else if(k == "p"){
		setDate(gdate);	
	}
	else {
		BFieldEdit::keyPressEvent(event);
	}
}

void BWEditDate::clearWhenNotSet(){
	if(!odate.isSet() && ((oformat == ISO_BLANK) || (oformat == UK_BLANK))){
		setBlank(1);
	}
	else if(oblank){
		setBlank(0);
	}
}

int BWEditDate::validate(int v){
	int	ndays;
	
	if((oformat == ISO) || (oformat == ISO_BLANK)){
		ndays = BDate::daysInMonth(ofields[0].ovalue, ofields[1].ovalue);
	
		ofields[2].omax =  ndays;

		if(ofields[2].ovalue > ndays)
			return BFieldEdit::validate(0);
		else
			return BFieldEdit::validate(1);
	}
	else {
		ndays = BDate::daysInMonth(ofields[2].ovalue, ofields[1].ovalue);
	
		ofields[0].omax =  ndays;

		if(ofields[0].ovalue > ndays)
			return BFieldEdit::validate(0);
		else
			return BFieldEdit::validate(1);
	}
}

BTimeStamp	BWEditTimeStamp::gtimeStamp;

BWEditTimeStamp::BWEditTimeStamp(QWidget* parent, Format format) : BFieldEdit(parent), oformat(format){
	ofields.append(BField(0, 4, "-", 0, 9999, 0));
	ofields.append(BField(5, 2, "-", 1, 12, 1));
	ofields.append(BField(8, 2, " ", 1, 31, 1));
	ofields.append(BField(11, 2, ":", 0, 23, 0));
	ofields.append(BField(14, 2, ":", 0, 59, 0));
	if((oformat == DATE_TIME_MICROSEC) || (oformat == DATE_TIME_MICROSEC_BLANK)){
		ofields.append(BField(17, 2, ".", 0, 59, 0));
		ofields.append(BField(20, 6, "", 0, 999999, 0));
	}
	else {
		ofields.append(BField(17, 2, "", 0, 59, 0));
	}

	setToolTip("BWEditTimeStamp allows the edit of datetime information. Press n for now, c for clear, s for start of time, e for end of time and p for a previous setting.");
	setSize();
	clearWhenNotSet();
	updateFromFields();
}

void BWEditTimeStamp::setReadOnly(int on){
	QLineEdit::setReadOnly(on);
}

void BWEditTimeStamp::setTimeStamp(BTimeStamp timeStamp){
	otimeStamp = timeStamp;
	clearWhenNotSet();

	ofields[0].ovalue = timeStamp.year();
	ofields[1].ovalue = timeStamp.month();
	ofields[2].ovalue = timeStamp.day();
	ofields[3].ovalue = timeStamp.hour();
	ofields[4].ovalue = timeStamp.minute();
	ofields[5].ovalue = timeStamp.second();
	if((oformat == DATE_TIME_MICROSEC) || (oformat == DATE_TIME_MICROSEC_BLANK))
		ofields[6].ovalue = timeStamp.microSecond();

	updateFromFields();
}

void BWEditTimeStamp::clearWhenNotSet(){
	if(!otimeStamp.isSet() && ((oformat == DATE_TIME_MICROSEC_BLANK) || (oformat == DATE_TIME_BLANK))){
		setBlank(1);
	}
	else if(oblank){
		setBlank(0);
	}
}

BTimeStamp BWEditTimeStamp::getTimeStamp(){
	BTimeStamp	timeStamp;
	
	if((oformat == DATE_TIME_MICROSEC) || (oformat == DATE_TIME_MICROSEC_BLANK)){
		timeStamp.set(ofields[0].ovalue, ofields[1].ovalue, ofields[2].ovalue,
			ofields[3].ovalue, ofields[4].ovalue, ofields[5].ovalue, ofields[6].ovalue);
	}
	else {
		timeStamp.set(ofields[0].ovalue, ofields[1].ovalue, ofields[2].ovalue,
			ofields[3].ovalue, ofields[4].ovalue, ofields[5].ovalue, 0);
	}
	gtimeStamp = timeStamp;
	return timeStamp;
}

void BWEditTimeStamp::keyPressEvent(QKeyEvent* event){
	BString	k = event->text();
	
	if(isReadOnly()){
		BFieldEdit::keyPressEvent(event);
		return;
	}

	if(oblank){
		setBlank(0);
		updateFromFields();
	}
	
	if(k == "n"){
		setTimeStamp(BTimeStamp("now"));	
	}
	else if((k == "c") || (event->key() == Qt::Key_Delete)){
		setTimeStamp(BTimeStamp());	
	}
	else if(k == "s"){
		setTimeStamp(BTimeStamp("first"));	
	}
	else if(k == "e"){
		setTimeStamp(BTimeStamp("last"));	
	}
	else if(k == "p"){
		setTimeStamp(gtimeStamp);
	}
	else {
		BFieldEdit::keyPressEvent(event);
	}
}

int BWEditTimeStamp::validate(int v){
	int	ndays;
	
	ndays = BDate::daysInMonth(ofields[0].ovalue, ofields[1].ovalue);
	
	ofields[2].omax =  ndays;

	if(ofields[2].ovalue > ndays)
		return BFieldEdit::validate(0);
	else
		return BFieldEdit::validate(1);
}