//
// Listing 8.1 ----------------------------------------------
// The simple Select indicator dialog.
//

//
// selectdialog.h
//

#ifndef _SELECT_DIALOG_H_
#define _SELECT_DIALOG_H_

class QLineEdit;
#include <kdialogbase.h>

class SelectDialog : public KDialogBase
{
  Q_OBJECT
  
  public:
    SelectDialog( QWidget *parent=0, const char *name=0, bool modal=false );
    ~SelectDialog();

  public slots:
    void setSelectionSize( uint selectionSize );

  private:
    QLineEdit *mSelectSizeEdit;
    uint mSelectionSize;
};

#endif


//
// selectdialog.cpp
//
#include <qlabel.h>
#include <qlayout.h> 
#include <qlineedit.h>
#include <klocale.h>

#include "selectdialog.h"

SelectDialog::SelectDialog( QWidget *parent, const char *name, bool modal )
  :KDialogBase( Plain, i18n("Select Indicator"), Cancel, Cancel, parent, name, 
		modal ), mSelectionSize(0)
{
  QVBoxLayout *topLayout = new QVBoxLayout( plainPage(), 0, spacingHint() );
  if( topLayout == 0 ) { return; }

  QLabel *label = new QLabel( i18n("Selection size [bytes]:"), plainPage() );
  if( label == 0 ) { return; }

  topLayout->addWidget( label );

  mSelectSizeEdit = new QLineEdit( plainPage() );
  if( mSelectSizeEdit ==  0 ) { return; }
  mSelectSizeEdit->setMinimumWidth( fontMetrics().maxWidth()*17 );
  mSelectSizeEdit->setFocusPolicy( QWidget::NoFocus );
  topLayout->addWidget( mSelectSizeEdit );
  topLayout->addStretch(10);

  setSelectionSize(0);
}


SelectDialog::~SelectDialog()
{
}


void 
SelectDialog::setSelectionSize( uint selectionSize )
{
  mSelectionSize = selectionSize;
  QString msg;

  msg.sprintf( "%08u, %04x:%04x", mSelectionSize, mSelectionSize>>16,
	       mSelectionSize&0x0000FFFF );
  mSelectSizeEdit->setText( msg );
}


//
// A main.cpp file used to test the dialog
//

#include <kcmdlineargs.h>
#include "selectdialog.h"
int main( int argc, char **argv )
{
  KCmdLineArgs::init(argc, argv, "selectdialog", 0, 0);
  KApplication app;
  SelectDialog *dialog = new SelectDialog;
  dialog->show();
  int result = app.exec();
  return result;
}






//
// Listing 8.2 ----------------------------------------------
// Manual geomentry management versus QLayout based. 
//
// This example is meant as an illustration. It does not contain
// all code to compile.
//

#include <qdialog.h>
#include <qlabel.h>
#include <qlcdnumber.h>
#include <qpushbutton.h> 
#include <qscrollbar.h>

OldDialog::OldDialog( QWidget *parent, const char *name, bool modal )
  : QDialog( parent, name, modal )
{
  setCaption( i18n("Update Frequency") );

  QLabel *label = new QLabel( this, "label" );
  label->setGeometry( 16, 24, 180, 24 );
  label->setText( i18n("Update frequency in seconds:") );

  QScrollBar *scollbar = new QScrollBar( this, "scrollbar" );
  scollbar->setGeometry( 24, 48, 160, 16 );
  scollbar->setOrientation( QScrollBar::Horizontal );

  QLCDNumber *lcdNumber = QLCDNumber( this, "lcdnumber" );
  lcdNumber->setGeometry( 192, 32, 72, 32 );
  lcdNumber->setSmallDecimalPoint( false );
  lcdNumber->setNumDigits( 5 );
  lcdNumber->setMode( QLCDNumber::DEC );
  
  QPushButton *ok = new QPushButton( this, "ok" );
  ok->setGeometry( 32, 120, 80, 24 );
  ok->setText( i18n("&OK") );

  QPushButton *cancel = new QPushButton( this, "PushButton_2" );
  b_cancel->setGeometry( 176, 120, 80, 24 );
  b_cancel->setText( i18n("&Cancel") );

  resize( 288, 168 );

  connect( scollbar, SIGNAL(valueChanged(int)), 
     lcdNumber, SLOT(display(int)) );
  connect( ok, SIGNAL(clicked()), this, SLOT(accept()) );
  connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) );
}


#include <qlabel.h>
#include <qlcdnumber.h>
#include <qpushbutton.h> 
#include <qscrollbar.h>
#include <kdialogbase.h>

NewDialog::NewDialog( QWidget *parent, const char* name, bool modal )
  : KDialogBase( parent, name, modal, i18n("Update Frequency"), 
     Ok|Cancel, Ok )
{
  QWidget *page = new QWidget( this ); 
  setMainWidget(page);

  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
  QHBoxLayout *hlay = new QHBoxLayout( topLayout );
  QVBoxLayout *vlay = new QVBoxLayout( hlay, 10 );

  QLabel *label2 = new QLabel( page, "label1" );
  label->setText( i18n("Update frequency in seconds:") );
  vlay->addWidget( label );

  //
  // It is very simple to add a new label here
  //
  QLabel *label2 = new QLabel( page, "label2" );
  label2->setText( i18n("A new label text") );
  vlay->addWidget( label2 );

  QScrollBar *scollbar = QScrollBar( page, "scrollbar" );
  scollbar->setOrientation( QScrollBar::Horizontal );
  vlay->addWidget( scollbar );

  QLCDNumber *lcdNumber = QLCDNumber( page, "lcdnumber" );
  lcdNumber->setSmallDecimalPoint( false );
  lcdNumber->setNumDigits( 3 );
  lcdNumber->setMode( QLCDNumber::DEC );
  hlay->addWidget( lcdNumber, 0 );

  connect( scollbar, SIGNAL(valueChanged(int)), 
     lcdNumber, SLOT(display(int)) );
}




//
// Listing 8.3 ----------------------------------------------
// Goto dialog box using layouts only
//

//
// gotodialog.h
//

#ifndef _GOTO_DIALOG_H_
#define _GOTO_DIALOG_H_

class QCheckBox;
class QComboBox;

#include <kdialogbase.h>

class CGotoDialog : public KDialogBase 
{
  Q_OBJECT
  
  public:
    CGotoDialog( QWidget *parent=0, const char *name=0, bool modal=false );
    ~CGotoDialog();
    void defaultFocus();

  protected slots:
    virtual void slotOk();

  signals:
    void gotoOffset( uint offset, uint bit, bool fromCursor, bool forward );

  private:
    QComboBox *mComboBox;
    QCheckBox *mCheckBackward;
    QCheckBox *mCheckFromCursor;
    QCheckBox *mCheckVisible;
};

#endif


//
// gotodialog.cpp
//

#include <qbuttongroup.h>
#include <qcheckbox.h> 
#include <qcombobox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <klocale.h>

CGotoDialog::CGotoDialog( QWidget *parent, const char *name, bool modal )
  :KDialogBase( Plain, i18n("Goto Offset"), Ok|Cancel, Ok, parent, name, 
    modal )
{
  QVBoxLayout *topLayout = new QVBoxLayout( plainPage(), 0, spacingHint() );
  CHECK_PTR(topLayout);

  QVBoxLayout *vbox = new QVBoxLayout( topLayout );
  CHECK_PTR(topLayout);

  mComboBox = new QComboBox( true, plainPage() );
  CHECK_PTR(mComboBox);
  mComboBox->setMaxCount( 10 );
  mComboBox->setInsertionPolicy( QComboBox::AtTop );  
  mComboBox->setMinimumWidth( fontMetrics().maxWidth()*17 );

  QLabel *label = new QLabel( mComboBox, i18n("O&ffset:"), plainPage() );
  CHECK_PTR(label);

  vbox->addWidget( label );
  vbox->addWidget( mComboBox );

  QButtonGroup *group = new QButtonGroup( i18n("Options"), plainPage() );
  CHECK_PTR(group);
  topLayout->addWidget( group, 10 ); // Only the group will be resized

  QGridLayout *gbox = new QGridLayout( group, 4, 2, spacingHint() );
  CHECK_PTR(gbox);
  gbox->addRowSpacing( 0, fontMetrics().lineSpacing() );
  mCheckFromCursor = new QCheckBox( i18n("&From cursor"), group );
  CHECK_PTR(mCheckFromCursor);
  gbox->addWidget( mCheckFromCursor, 1, 0 );
  mCheckBackward = new QCheckBox( i18n("&Backwards"), group );
  CHECK_PTR(mCheckBackward);
  gbox->addWidget( mCheckBackward, 1, 1 );
  mCheckVisible = new QCheckBox( i18n("&Stay visible"), group );
  CHECK_PTR(mCheckVisible);
  gbox->addWidget( mCheckVisible, 2, 0 );
  gbox->setRowStretch( 3, 10 ); // Eat up all extra space when resized
  mCheckVisible->setChecked( true );

  defaultFocus();
}

CGotoDialog::~CGotoDialog()
{
}

void 
CGotoDialog::defaultFocus()
{
  mComboBox->setFocus();
}

void 
CGotoDialog::slotOk()
{
  uint offset;
  bool success = stringToOffset( mComboBox->currentText(), offset );
  if( success == false )
  {
    return;
  }

  if( mCheckVisible->isChecked() == false )
  {
    hide();
  }
  emit gotoOffset( offset, 7, mCheckFromCursor->isChecked(),
       mCheckBackward->isChecked() == true ? false : true );
}




//
// Listing 8.4 ----------------------------------------------
// Goto dialog box using a QVBox widget
//
// This example is meant as an illustration. You can replace the 
// constructor code of Listing 8.3 with this.
//

#include <qbuttongroup.h>
#include <qcheckbox.h> 
#include <qcombobox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qvbox.h> 
#include <klocale.h>

CGotoDialog::CGotoDialog( QWidget *parent, const char *name, bool modal )
  :KDialogBase( Plain, i18n("Goto Offset"), Ok|Cancel, Ok, parent, name, 
		modal )
{
  QVBoxLayout *topLayout = new QVBoxLayout( plainPage(), 0, spacingHint() );
  CHECK_PTR(topLayout);

  QVBox *topBox = new QVBox( plainPage() );
  CHECK_PTR(topBox);
  topBox->setSpacing( spacingHint() );
  topLayout->addWidget( topBox );

  QLabel *label = new QLabel( i18n("O&ffset:"), topBox );
  CHECK_PTR(label);

  mComboBox = new QComboBox( true, topBox );
  CHECK_PTR(mComboBox);
  mComboBox->setMaxCount( 10 );
  mComboBox->setInsertionPolicy( QComboBox::AtTop );  
  mComboBox->setMinimumWidth( fontMetrics().maxWidth()*17 );
  label->setBuddy(mComboBox); // To get the underlining to work

  QButtonGroup *group = new QButtonGroup( i18n("Options"), topBox );
  CHECK_PTR(group);
   
  QGridLayout *gbox = new QGridLayout( group, 4, 2, spacingHint() );
  CHECK_PTR(gbox);
  gbox->addRowSpacing( 0, fontMetrics().lineSpacing() );
  mCheckFromCursor = new QCheckBox( i18n("&From cursor"), group );
  CHECK_PTR(mCheckFromCursor);
  gbox->addWidget( mCheckFromCursor, 1, 0 );
  mCheckBackward = new QCheckBox( i18n("&Backwards"), group );
  CHECK_PTR(mCheckBackward);
  gbox->addWidget( mCheckBackward, 1, 1 );
  mCheckVisible = new QCheckBox( i18n("&Stay visible"), group );
  CHECK_PTR(mCheckVisible);
  gbox->addWidget( mCheckVisible, 2, 0 );
  gbox->setRowStretch( 3, 10 ); // Eat up all extra space when resized
  mCheckVisible->setChecked( true );

  defaultFocus();
}





//
// Listing 8.5 ----------------------------------------------
// Picking a color using a modal KColorDialog on the stack.
//

#include <kcolordlg.h>

int getColor( QColor &theColor, QWidget *parent )
{
  KColorDialog dialog( parent, "colorselector", true );
  if( theColor.isValid() )
  {
    dialog.setColor( theColor );
  }
  int result = dialog.exec();
  if( result == Accepted )
  {
    theColor = dialog.color();
  }
  return result;
}





//
// Listing 8.6 ----------------------------------------------
// Picking a color allocating a modal KColorDialog
//
#include <kcolordlg.h>

int getColor( QColor &theColor, QWidget *parent )
{
  KColorDialog *dialog = new KColorDialog( parent, "colorselector", true );
  if( dialog == 0 )
  {
    return Rejected; // Rejected is a constant defined in QDialog
  }  

  if( theColor.isValid() )
  {
    dialog->setColor( theColor );
  }
  int result = dialog->exec();
  if( result == Accepted )
  {
    theColor = dialog->color();
  }

  delete dialog; // Important to avoid memory leaks

  return result;
}






//
// Listing 8.7 ----------------------------------------------
// The Goto dialog is used as a modeless dialog.
//

#include "gotodialog.h"

CHexEditorWidget::CHexEditorWidget()
{
  mGotoDialog = 0;
}

CHexEditorWidget::~CHexEditorWidget()
{
  delete mGotoDialog;
}

void 
CHexEditorWidget::gotoOffset()
{
  if( mGotoDialog == 0 )
  {
    mGotoDialog = new CGotoDialog( topLevelWidget(), "goto", false );
    if( mGotoDialog == 0 ) 
    { 
      return; 
    }
    connect( mGotoDialog, SIGNAL(gotoOffset( uint, uint, bool, bool )), 
	     mHexView, SLOT(gotoOffset( uint, uint, bool, bool )) );
  }
  mGotoDialog->show();
}





//
// Listing 8.8 ----------------------------------------------
// Bad method to destroy a modeless dialog.
//

void 
CGotoDialog::slotCancel()
{
  hide();       // Ok, will hide the dialog
  delete this;  // Bad!
}





//
// Listing 8.9 ----------------------------------------------
// Ok method to destroy a modeless dialog that is derived from 
// KDialogBase.
//

void 
KJotsMain::configure()
{
  if( mOptionDialog == 0 )
  {
    mOptionDialog = new ConfigureDialog( topLevelWidget(), 0, false );
    if( mOptionDialog == 0 ) 
    { 
      return; 
    }
    connect( mOptionDialog, SIGNAL(hidden()),this,SLOT(configureHide()));
    connect( mOptionDialog, SIGNAL(valueChanged()),
	     this, SLOT(updateConfiguration()) );
  }
  mOptionDialog->show();
}

void 
KJotsMain::configureHide()
{
  QTimer::singleShot( 0, this, SLOT(configureDestroy()) ); // Zero delay
}

void 
KJotsMain::configureDestroy()
{
  if( mOptionDialog != 0 && mOptionDialog->isVisible() == false )
  {
    delete mOptionDialog; 
    mOptionDialog = 0;
  }
}





//
// Listing 8.10 ---------------------------------------------
// Using the KDE font selector dialog
//

#include <kfontdialog.h>

void 
Editor::selectFont()
{
  QFont fnt = font();        // Get current font
  KFontDialog::getFont(fnt); // Select a new, default is current font
  setFont(fnt);              // Install new font
}





//
// Listing 8.11 ---------------------------------------------
// Using the KButtonBox widget in a dialog derived from KDialog.
//
#include <qlayout.h>
#include <qpushbutton.h> 

#include <kbuttonbox.h>
#include <kdialog.h>
#include <klocale.h>

MyDialog::MyDialog( QWidget *parent, const char *name, bool modal)
  : KDialog( parent, name, modal )
{
  QVBoxLayout *topLayout = new QVBoxLayout( this, marginHint(),
    spacingHint() );
  CHECK_PTR( topLayout );

  //
  // Main body of the dialog is not shown here, just the button box
  //

  KButtonBox *bbox = new KButtonBox( this, KButtonBox::HORIZONTAL, 0, 
    spacingHint() );
  CHECK_PTR( bbox );
  topLayout->addWidget( bbox );

  buttonBox->addStretch();
  QPushButton *ok = bbox->addButton( i18n("&Ok"), false );
  QPushButton *cancel = bbox->addButton( i18n("&Cancel"), false );
  buttonBox->layout();
  ok->setDefault( true );
  connect( ok , SIGNAL(clicked()), this, SLOT(accept()) );
  connect( cancel , SIGNAL(clicked()), this, SLOT(reject()) );
}




//
// Listing 8.12 ---------------------------------------------
// A dialog using the KJanusWidget in tabbed mode and with custom
// action buttons.
//
CPrinterDialog::CPrinterDialog( QWidget *parent, char *name, bool modal )
  :KDialogBase( Tabbed, i18n("Print Document"), 
   Help|User2|User1|Cancel, User1, parent, name, modal, false, 
   i18n("&Print"), i18n("Pre&view") ),
{
  // The code has been removd in this example.
}





//
// Listing 8.13 ---------------------------------------------
// A full blown example. The KEdit Option dialog. This also show
// how you can add a licence text.
//

//
// optiondialog.h
//

/*
 *   kedit - KDE editor
 *   This file only: Copyright (C) 1999  Espen Sand, espen@kde.org
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifndef _OPTION_DIALOG_H_
#define _OPTION_DIALOG_H_

class QCheckBox;
class QLabel;
class QLineEdit;
class KColorButton;
class KFontChooser;
class KSpellConfig;

#include <kdialogbase.h>
#include "optionstate.h" // See end of example!


class COptionDialog : public KDialogBase
{
  Q_OBJECT

  public:
    enum Page
    {
      page_font = 0,
      page_color,
      page_spell,
      page_misc,
      page_max
    };

    COptionDialog( QWidget *parent = 0, char *name = 0, bool modal = false );
    ~COptionDialog();

    void setFont( const SFontState &font );
    void setColor( const SColorState &color );
    void setSpell( const SSpellState &spell );
    void setMisc( const SMiscState &misc );
    void setState( const SOptionState &state );

  public slots:

    virtual void slotDefault();
    virtual void slotOk();
    virtual void slotApply();

  private:
    struct SFontWidgets
    {
      KFontChooser *chooser;
    };

    struct SColorWidgets
    {
      KColorButton *fgColor;
      KColorButton *bgColor;
    };

    struct SSpellWidgets
    {
      KSpellConfig *config;
    };

    struct SMiscWidgets
    {
      QComboBox *wrapCombo;
      QLabel    *wrapLabel;
      QLineEdit *wrapInput;
      QCheckBox *backupCheck;
      QLineEdit *mailInput;
    };

  private slots:
    void wrapMode( int mode );

  private:
    void setupFontPage();
    void setupColorPage();
    void setupSpellPage();
    void setupMiscPage();

  signals:
    void fontChoice( const SFontState &font );
    void colorChoice( const SColorState &color );
    void spellChoice( const SSpellState &spell );
    void miscChoice( const SMiscState &misc );

  private:
    SOptionState   mState;
    SColorWidgets  mColor;
    SFontWidgets   mFont;
    SSpellWidgets  mSpell;
    SMiscWidgets   mMisc;
};


#endif

//
// optiondialog.cpp
//

/*
 *   kedit - KDE editor
 *   This file only: Copyright (C) 1999  Espen Sand, espen@kde.org
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <qcheckbox.h>
#include <qcombobox.h>
#include <qfont.h>
#include <qframe.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qlineedit.h> 

#include <kapp.h>
#include <kcolorbtn.h>
#include <kfontdialog.h> // For KFontChooser
#include <klocale.h>
#include <kspell.h>

#include "optiondialog.h" // See below in this text for defintion


COptionDialog::COptionDialog( QWidget *parent, char *name, bool modal )
  :KDialogBase( IconList, i18n("Options"), Help|Default|Apply|Ok|Cancel,
		Ok, parent, name, modal, true )
{
  setHelp( "kedit/index.html", QString::null ); // When Help is pressed

  setupFontPage();
  setupColorPage();
  setupSpellPage();
  setupMiscPage();
}

COptionDialog::~COptionDialog()
{
}


void 
COptionDialog::setupFontPage()
{
  QFrame *page = addPage( i18n("Font"), i18n("Editor font" ),
                          UserIcon("fonts") ); 
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
  if( topLayout == 0 ) { return; }

  mFont.chooser = new KFontChooser( page,"font",false,QStringList(),false,6 );
  topLayout->addWidget( mFont.chooser );
}


void 
COptionDialog::setupColorPage()
{
  QFrame *page = addPage( i18n("Color"), i18n("Text color in editor area"),
                          UserIcon("colors") );  
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
  if( topLayout == 0 ) { return; }

  QGridLayout *gbox = new QGridLayout( 2, 2 );
  topLayout->addLayout(gbox);

  QLabel *label;
  mColor.fgColor = new KColorButton( page );
  mColor.bgColor = new KColorButton( page );
  label = new QLabel( mColor.fgColor, "Foreground color", page );
  label = new QLabel( mColor.bgColor, "Background color", page );

  gbox->addWidget( label, 0, 0 );
  gbox->addWidget( label, 1, 0 );
  gbox->addWidget( mColor.fgColor, 0, 1 );
  gbox->addWidget( mColor.bgColor, 1, 1 );

  topLayout->addStretch(10);
}


void 
COptionDialog::setupSpellPage()
{
  QFrame *page = addPage( i18n("Spelling"), i18n("Spell checker behavior"),
                          UserIcon("spellconfig") );
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
  if( topLayout == 0 ) { return; }

  mSpell.config = new KSpellConfig( page, "spell");
  topLayout->addWidget( mSpell.config );

  topLayout->addStretch(10);
}


void 
COptionDialog::setupMiscPage()
{
  QFrame *page = addPage( i18n("Miscellaneous"), i18n("Various properties"),
                          UserIcon("misc") );
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
  if( topLayout == 0 ) { return; }

  QGridLayout *gbox = new QGridLayout( 5, 2 );
  topLayout->addLayout( gbox );

  QString text;

  text = i18n("Word Wrap");
  QLabel *label = new QLabel( text, page, "wraplabel" );
  gbox->addWidget( label, 0, 0 );
  QStringList wrapList;
  wrapList.append( i18n("Disable wrapping") );
  wrapList.append( i18n("Let editor width decide") );
  wrapList.append( i18n("At specified column") );
  mMisc.wrapCombo = new QComboBox( false, page );
  connect(mMisc.wrapCombo,SIGNAL(activated(int)),this,SLOT(wrapMode(int)));
  mMisc.wrapCombo->insertStringList( wrapList );
  gbox->addWidget( mMisc.wrapCombo, 0, 1 );

  text = i18n("Wrap Column");
  mMisc.wrapLabel = new QLabel( text, page, "wrapcolumn" );
  gbox->addWidget( mMisc.wrapLabel, 1, 0 );
  mMisc.wrapInput = new QLineEdit( page, "values" );
  mMisc.wrapInput->setMinimumWidth( fontMetrics().maxWidth()*10 );
  gbox->addWidget( mMisc.wrapInput, 1, 1 );

  gbox->addRowSpacing( 2, spacingHint()*2 );  

  text = i18n("Make backup when saving a file");
  mMisc.backupCheck = new QCheckBox( text, page, "backup" );
  gbox->addMultiCellWidget( mMisc.backupCheck, 3, 3, 0, 1 );
  
  mMisc.mailInput = new QLineEdit( page, "mailcmd" );
  mMisc.mailInput->setMinimumWidth(fontMetrics().maxWidth()*10);
  text = i18n("Mail Command");
  label = new QLabel( text, page,"mailcmdlabel" );
  gbox->addWidget( label, 4, 0 );
  gbox->addWidget( mMisc.mailInput, 4, 1 );

  topLayout->addStretch(10);
}


void 
COptionDialog::wrapMode( int mode )
{
  bool state = mode == 2 ? true : false;
  mMisc.wrapInput->setEnabled( state );
  mMisc.wrapLabel->setEnabled( state );
}


void 
COptionDialog::slotOk()
{
  slotApply();
  accept();
}


void 
COptionDialog::slotApply()
{
  switch( activePageIndex() )
  {
    case page_font:
      mState.font.font = mFont.chooser->font();
      emit fontChoice( mState.font );
    break;

    case page_color:
      mState.color.textFg = mColor.fgColor->color();
      mState.color.textBg = mColor.bgColor->color();
      emit colorChoice( mState.color );
    break;

    case page_spell:
      mState.spell.config = *mSpell.config;
      emit spellChoice( mState.spell );
    break;

    case page_misc:
      mState.misc.wrapMode    = mMisc.wrapCombo->currentItem();
      mState.misc.backupCheck = mMisc.backupCheck->isChecked();
      mState.misc.wrapColumn  = mMisc.wrapInput->text().toInt();
      mState.misc.mailCommand = mMisc.mailInput->text();
      emit miscChoice( mState.misc );
    break;
  }
}


void 
COptionDialog::slotDefault()
{
  //
  // The constructors store the default settings.
  //
  switch( activePageIndex() )
  {
    case page_font:
      setFont( SFontState() );
    break;

    case page_color:
      setColor( SColorState() );
    break;

    case page_spell:
      setSpell( SSpellState() );
    break;

    case page_misc:
      setMisc( SMiscState() );
    break;
  }
}


void 
COptionDialog::setFont( const SFontState &font )
{
  mState.font = font;
  mFont.chooser->setFont( font.font, false );
}


void 
COptionDialog::setColor( const SColorState &color )
{
  mState.color = color;
  mColor.fgColor->setColor( color.textFg );
  mColor.bgColor->setColor( color.textBg );
}


void 
COptionDialog::setSpell( const SSpellState &spell )
{
  *mSpell.config = spell.config;
}


void 
COptionDialog::setMisc( const SMiscState &misc )
{
  mState.misc = misc;
  mMisc.wrapCombo->setCurrentItem( misc.wrapMode ); 
  mMisc.wrapInput->setText( QString().setNum(misc.wrapColumn) );
  mMisc.backupCheck->setChecked( misc.backupCheck );
  mMisc.mailInput->setText( misc.mailCommand );
  wrapMode( mMisc.wrapCombo->currentItem() );
}


void 
COptionDialog::setState( const SOptionState &state )
{
  setFont( state.font );
  setColor( state.color );
  setSpell( state.spell );
  setMisc( state.misc );
}



//
// A main.cpp file used to test the dialog
//

#include <kcmdlineargs.h>
#include "optiondialog.h"
int main( int argc, char **argv )
{
  KCmdLineArgs::init(argc, argv, "kedit", 0, 0);
  KApplication app;
  COptionDialog *dialog = new COptionDialog;
  dialog->show();
  int result = app.exec();
  return result;
}


//
// optionstate.h
//

/*
 *   kedit - KDE editor
 *   This file only: Copyright (C) 1999  Espen Sand, espen@kde.org
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifndef _OPTION_STATE_H_
#define _OPTION_STATE_H_

#include <kapp.h>
#include <kspell.h>
#include <qfont.h> 


struct SFontState
{
  SFontState()
  {
    font = QFont ("courier", 12, QFont::Normal);
  }

  QFont font;
};

struct SColorState
{
  SColorState()
  {
    textFg = Qt::black;
    textBg = Qt::white;
  }

  QColor textFg;
  QColor textBg;
};

struct SSpellState
{
  SSpellState()
  {
    config = KSpellConfig();
  }

  KSpellConfig config;
};

struct SMiscState
{
  enum WrapModes
  {
    noWrap = 0,
    dynamicWrap = 1,
    fixedColumnWrap = 2
  }; 

  SMiscState()
  {
    wrapMode    = fixedColumnWrap;
    wrapColumn  = 79;
    backupCheck = true;
    mailCommand = "mail -s \"%s\" \"%s\"";
  }

  int  wrapMode;
  int  wrapColumn;
  bool backupCheck;
  QString mailCommand;
};


struct SOptionState
{
  SFontState  font;
  SColorState color;
  SSpellState spell;
  SMiscState  misc;
};

#endif



//
// Listing 8.14 ---------------------------------------------
// The code used in the first exercise
//

//
// maildialog.h
//

#ifndef _MAIL_DIALOG_H_
#define _MAIL_DIALOG_H_

class QLineEdit;
class QMultiLineEdit;
#include <kdialogbase.h>

class MailDialog : public KDialogBase
{
  Q_OBJECT
  
  public:
    MailDialog( QWidget *parent=0, const char *name=0, bool modal=true );

  protected slots:
    virtual void slotUser2();
    virtual void slotUser1();

  private:
    QLineEdit *mFromLineEdit;
    QLineEdit *mToLineEdit;
    QLineEdit *mCcLineEdit;
    QLineEdit *mSubjectLineEdit;
    QMultiLineEdit *mBodyTextEdit;
};
#endif

//
// maildialog.cc
//

#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qmultilineedit.h>
#include <klocale.h>

#include "maildialog.h"
  
MailDialog::MailDialog( QWidget *parent, const char *name, bool modal )
  : KDialogBase( parent, name, modal, i18n("Compose Mail"), 
 User2|User1|Cancel, Ok, false, i18n("&Send"), 
 i18n("&Address") )
{
  setPlainCaption("Compose Mail");

  QWidget *page = new QWidget( this ); 
  setMainWidget(page);
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );

  QGridLayout *glay = new QGridLayout(topLayout,4,2);
  QLabel *fromLabel = new QLabel( i18n("From:"), page );
  QLabel *toLabel = new QLabel( i18n("To:"), page );
  QLabel *ccLabel = new QLabel( i18n("Cc:"), page );
  QLabel *subjectLabel = new QLabel( i18n("Subject:"), page );

  mFromLineEdit = new QLineEdit( page );
  mToLineEdit = new QLineEdit( page );
  mCcLineEdit = new QLineEdit( page );
  mSubjectLineEdit = new QLineEdit( page );

  glay->addWidget( fromLabel, 0, 0, AlignRight );
  glay->addWidget( toLabel, 1, 0, AlignRight  );
  glay->addWidget( ccLabel, 2, 0, AlignRight  );
  glay->addWidget( subjectLabel, 3, 0, AlignRight  );
  glay->addWidget( mFromLineEdit, 0, 1 );
  glay->addWidget( mToLineEdit, 1, 1 );
  glay->addWidget( mCcLineEdit, 2, 1 );
  glay->addWidget( mSubjectLineEdit, 3, 1 );
  mFromLineEdit->setMinimumWidth(fontMetrics().maxWidth()*20);

  mBodyTextEdit = new QMultiLineEdit( page );
  topLayout->addWidget( mBodyTextEdit, 10 );
  mBodyTextEdit->setMinimumHeight(fontMetrics().lineSpacing()*10);
}

void 
MailDialog::slotUser1() // Send
{
  // Send your mail here
}

void 
MailDialog::slotUser2() // Addresses
{
  // Open your address book here
}


//
// A main.cpp file used to test the dialog
//

#include <kcmdlineargs.h>
#include "maildialog.h"
int main( int argc, char **argv )
{
  KCmdLineArgs::init(argc, argv, "appname", 0, 0);
  KApplication app;
  MailDialog *dialog = new MailDialog;
  dialog->show();
  int result = app.exec();
  return result;
}





//
// Listing 8.15 ---------------------------------------------
// The code used in the second exercise where you add some extra
// pushbuttons
//

MailDialog::MailDialog( QWidget *parent, const char *name, bool modal )
  : KDialogBase( parent, name, modal, i18n("Compose Mail"), 
  Help|User1|Cancel, Ok, false, i18n("&Send") )
{
  setPlainCaption("Compose Mail");

  QWidget *page = new QWidget( this ); 
  setMainWidget(page);
  QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );

  QGridLayout *glay = new QGridLayout(topLayout,4,2);
  QLabel *fromLabel = new QLabel( i18n("From:"), page );
  QLabel *toLabel = new QLabel( i18n("To:"), page );
  QLabel *ccLabel = new QLabel( i18n("Cc:"), page );
  QLabel *subjectLabel = new QLabel( i18n("Subject:"), page );

  mFromLineEdit = new QLineEdit( page );
  mToLineEdit = new QLineEdit( page );
  mCcLineEdit = new QLineEdit( page );
  mSubjectLineEdit = new QLineEdit( page );

  QPushButton *toPushButton = new QPushButton( i18n("Choose..."), page );
  toPushButton->setAutoDefault( false );
  QPushButton *ccPushButton = new QPushButton( i18n("Choose..."), page );
  ccPushButton->setAutoDefault( false );

  glay->addWidget( fromLabel, 0, 0, AlignRight );
  glay->addWidget( toLabel, 1, 0, AlignRight  );
  glay->addWidget( ccLabel, 2, 0, AlignRight  );
  glay->addWidget( subjectLabel, 3, 0, AlignRight  );
  glay->addMultiCellWidget( mFromLineEdit, 0, 0, 1, 2 );
  glay->addWidget( mToLineEdit, 1, 1 );
  glay->addWidget( mCcLineEdit, 2, 1 );
  glay->addMultiCellWidget( mSubjectLineEdit, 3, 3, 1, 2 );
  mFromLineEdit->setMinimumWidth(fontMetrics().maxWidth()*20);
  glay->addWidget( toPushButton, 1, 2 );
  glay->addWidget( ccPushButton, 2, 2 );

  mBodyTextEdit = new QMultiLineEdit( page );
  topLayout->addWidget( mBodyTextEdit, 10 );
  mBodyTextEdit->setMinimumHeight(fontMetrics().lineSpacing()*10);
}











