//
// Qt Example Application: widgets
//
// Demonstrates Qt widgets.
//

#include <qdialog.h>
#include <qmsgbox.h>
#include <qpixmap.h>
#include <qapp.h>

// Standard Qt widgets

#include <qbttngrp.h>
#include <qchkbox.h>
#include <qcombo.h>
#include <qframe.h>
#include <qgrpbox.h>
#include <qlabel.h>
#include <qlcdnum.h>
#include <qlined.h>
#include <qlistbox.h>
#include <qpushbt.h>
#include <qradiobt.h>
#include <qscrbar.h>

// Some sample widgets

#include "../aclock/aclock.h"
#include "../dclock/dclock.h"


//
// WidgetView contains lots of Qt widgets.
//

class WidgetView : public QDialog
{
    Q_OBJECT
public:
    WidgetView( QWidget *parent=0, const char *name=0 );

private slots:
    void	button1Clicked();
    void	button2Clicked();
    void	checkBoxClicked( int );
    void	radioButtonClicked( int );
    void	scrollBarValueChanged( int );
    void	listBoxItemSelected( int );
    void	comboBoxItemActivated( int );
    void	lineEditTextChanged( const char * );

private:
    bool	eventFilter( QObject *, QEvent * );
    QLabel     *msg;
    QCheckBox  *cb[3];
};


//
// Construct the WidgetView with buttons
//

WidgetView::WidgetView( QWidget *parent, const char *name )
    : QDialog( parent, name )
{
    QColor col;

  // Set the window caption/title

    setCaption( "Qt Widgets Demo Application" );

  // Install an application-global event filter

    qApp->installEventFilter( this );

  // Create an analog and a digital clock

    AnalogClock  *aclock = new AnalogClock( this );
    DigitalClock *dclock = new DigitalClock( this );
    aclock->setGeometry( 300,100, 100,100 );
    dclock->setGeometry( 300,220, 100, 60 );

  // Give the dclock widget a blue palette

    col.setRgb( 0xaa, 0xbe, 0xff );
    QColorGroup colgrp( black, col, col.light(), col.dark(), col.dark(120),
			black, white );
    dclock->setPalette( QPalette(colgrp,colgrp,colgrp) );

  // Create two push buttons, a text button and a pixmap button

    QPushButton *pb;
    pb = new QPushButton( this, "button1" );	// create button 1
    pb->setText( "Push button 1" );
    pb->setGeometry( 10,30, 120,30 );
    connect( pb, SIGNAL(clicked()), SLOT(button1Clicked()) );
    pb = new QPushButton( this, "button2" );	// create button 2
    QPixmap pm;
    if ( !pm.load("qt.bmp") ) {			// load pixmap for button 2
	QMessageBox::message( "Error", "Could not load qt.bmp pixmap" );
	pb->setText( "No pixmap" );
    }
    else
	pb->setPixmap( pm );
    pb->setGeometry( 150,10, 60,60 );
    connect( pb, SIGNAL(clicked()), SLOT(button2Clicked()) );

  // Create a quit button
  // Pressing the quit button will terminate the application

    QPushButton *quitButton = new QPushButton( this, "quitButton" );
    quitButton->setText( "Quit" );
    quitButton->setGeometry( 300,30, 80,30 );
    connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );

  // Make the quit button red and give it another font

    col = QColor( 240, 10, 10 );
    colgrp = QColorGroup( black, col, col.light(), col.dark(), col.dark(120),
			  blue, white );
    quitButton->setPalette( QPalette(colgrp,colgrp,colgrp) );
    quitButton->setFont( QFont("times",14,QFont::Bold,TRUE) );

  // Create a group of check boxes

    QButtonGroup *bg = new QButtonGroup( this, "checkGroup" );
    bg->setTitle( "Check Boxes" );
    cb[0] = new QCheckBox( bg );
    cb[0]->setText( "Read" );
    cb[0]->setGeometry( 10,15, 100,25 );
    cb[1] = new QCheckBox( bg );
    cb[1]->setText( "Write" );
    cb[1]->setGeometry( 10,45, 100,25 );
    cb[2] = new QCheckBox( bg );
    cb[2]->setText( "Execute" );
    cb[2]->setGeometry( 10,75, 100,30 );
    bg->setGeometry( 10,80, 120,110 );
    connect( bg, SIGNAL(clicked(int)), SLOT(checkBoxClicked(int)) );

  // Create a group of radio buttons

    QRadioButton *rb;
    bg = new QButtonGroup( this, "radioGroup" );
    bg->setTitle( "Radio buttons" );
    rb = new QRadioButton( bg );
    rb->setText( "AM" );
    rb->setGeometry( 10, 15, 100,25 );
    rb = new QRadioButton( bg );
    rb->setText( "FM" );
    rb->setGeometry( 10, 45, 100,25 );
    rb = new QRadioButton( bg );
    rb->setText( "Short Wave" );
    rb->setGeometry( 10, 75, 100,25 );
    bg->setGeometry( 140, 80, 120, 110 );
    connect( bg, SIGNAL(clicked(int)), SLOT(radioButtonClicked(int)) );

  // Create a list box

    QListBox *lb = new QListBox( this, "listBox" );
    for ( int i=0; i<100; i++ ) {		// fill list box
	QString str;
	str.sprintf( "line %d", i );
	lb->insertItem( str );
    }
    lb->setGeometry( 10, 200, 120, 140 );
    int lbIH = lb->itemHeight();
    lb->resize( lb->width(), ((lb->height()+lbIH)/lbIH)*lbIH +
		lb->frameWidth()*2 );		// round up to next line
    connect( lb, SIGNAL(selected(int)), SLOT(listBoxItemSelected(int)) );

  // Create a scroll bar

    QScrollBar *sb = new QScrollBar( QScrollBar::Horizontal,this,"scrollBar" );
    sb->setGeometry( 140, 200, 120, 16 );
    connect( sb, SIGNAL(valueChanged(int)), SLOT(scrollBarValueChanged(int)) );

  // Create a combo box

    QComboBox *combo = new QComboBox( this, "comboBox" );
    combo->insertItem( "True" );
    combo->insertItem( "False" );
    combo->insertItem( "Maybe" );
    combo->insertItem( "Certainly" );
    combo->insertItem( "Nope" );    
    combo->setGeometry( 140, 250, 120, 30 );
    combo->setAutoResize( TRUE );
    connect( combo, SIGNAL(activated(int)), SLOT(comboBoxItemActivated(int)) );

  // Create a line edit

    QLineEdit *le = new QLineEdit( this, "lineEdit" );
    le->setGeometry( 140, 300, 230, 25 );
    connect( le, SIGNAL(textChanged(const char *)),
	         SLOT(lineEditTextChanged(const char *)) );

  // Create an message label
  // The message is updated when buttons are clicked etc.

    QLabel *msgLabel = new QLabel( this, "msgLabel" );
    msgLabel->setText( "Message:" );
    msgLabel->setAlignment( AlignRight|AlignVCenter );
    msgLabel->setGeometry( 10,400, 85, 30 );

    msg = new QLabel( this, "message" );
    msg->setFrameStyle( QFrame::Panel | QFrame::Sunken );
    msg->setAlignment( AlignCenter );
    msg->setGeometry( 100,400, 300,30 );
    msg->setFont( QFont("times",12,QFont::Bold) );

  // Create a horizontal line (sort of QFrame) above the quit button

    QFrame *separator = new QFrame( this, "separatorLine" );
    separator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
    separator->setGeometry( 5, 390, 440, 4 );

    adjustSize();
}


void WidgetView::button1Clicked()
{
    msg->setText( "The first push button was clicked" );
}


void WidgetView::button2Clicked()
{
    msg->setText( "The second push button was clicked" );
}


void WidgetView::checkBoxClicked( int id )
{
    QString str;
    str.sprintf( "Check box %d clicked : ", id );
    QString chk = "---";
    if ( cb[0]->isChecked() )
	chk[0] = 'r';
    if ( cb[1]->isChecked() )
	chk[1] = 'w';
    if ( cb[2]->isChecked() )
	chk[2] = 'x';
    str += chk;
    msg->setText( str );
}


void WidgetView::radioButtonClicked( int id )
{
    QString str;
    str.sprintf( "Radio button #%d clicked", id );
    msg->setText( str );
}


void WidgetView::listBoxItemSelected( int index )
{
    QString str;
    str.sprintf( "List box item %d selected", index );
    msg->setText( str );
}


void WidgetView::scrollBarValueChanged( int value )
{
    QString str;
    str.sprintf( "New scroll bar value %d", value );
    msg->setText( str );
}


void WidgetView::comboBoxItemActivated( int index )
{
    QString str;
    str.sprintf( "Combo box item %d activated", index );
    msg->setText( str );
}


void WidgetView::lineEditTextChanged( const char *newText )
{
    QString str;
    str.resize( strlen(newText)+100 );
    str.sprintf( "Line edit text: %s", newText );
    msg->setText( str );
}


//
// All application events are passed throught this event filter.
// We're using it to display some information about a clicked
// widget (right mouse button + CTRL).
//

bool WidgetView::eventFilter( QObject *obj, QEvent *event )
{    
    static bool identify_now = TRUE;
    if ( event->type() == Event_MouseButtonPress && identify_now ) {
	QMouseEvent *e = (QMouseEvent*)event;
	if ( e->button() == RightButton && (e->state() & ControlButton) != 0 ){
	    QString str = "The clicked widget is a\n";
	    str += obj->className();
	    str += "\nThe widget's name is\n";
	    if ( obj->name() )
		str += obj->name();
	    else
		str += "<no name>";
	    identify_now = FALSE;		// don't do it in message box
	    QMessageBox::message( "Identify Widget", str, 0, (QWidget*)obj );
	    identify_now = TRUE;		// allow it again
	}
    }
    return FALSE;				// don't eat event
}

//
// Include the meta-object code for our own classes
//

#include "widgets.moc"
#include "aclock.moc"
#include "dclock.moc"

//
// Create and display our WidgetView.
//

int main( int argc, char **argv )
{
    QApplication  a( argc, argv );
    WidgetView   *w = new WidgetView;
    a.setMainWidget( w );
    w->show();
    return a.exec();
}
