[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: New Class: KInputDialog
From:       Nadeem Hasan <nhasan () nadmm ! com>
Date:       2003-06-01 3:34:27
[Download RAW message or body]

WARNING: Unsanitized content follows.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here is the updated version of the class after considering the feedback from 
Cornelius and beineri. I will commit it in a day or two if there are no 
objections.

Regards,
- -- 
Nadeem Hasan
nhasan@nadmm.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)

iD8DBQE+2XRDbAx1Pt06D1MRAi9LAJ9v3Jo5g6qfCI73mF8qt4e/knN4UwCfRz1A
RI6YudQtrYCMMhgult+MfNE=
=2xgP
-----END PGP SIGNATURE-----

["kinputdialog.cpp" (text/x-c__src)]

/*
  Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
*/

#include <qlayout.h>
#include <qlabel.h>
#include <qvalidator.h>

#include <klineedit.h>
#include <knuminput.h>
#include <kcombobox.h>
#include <klistbox.h>

#include "kinputdialog.h"

class KInputDialogPrivate
{
  public:
    KInputDialogPrivate();

    QLabel *m_label;
    KLineEdit *m_lineEdit;
    KIntSpinBox *m_intSpinBox;
    KDoubleSpinBox *m_doubleSpinBox;
    KComboBox *m_comboBox;
    KListBox *m_listBox;
};

KInputDialogPrivate::KInputDialogPrivate()
    : m_label( 0L ), m_lineEdit( 0L ), m_intSpinBox( 0L ),
      m_doubleSpinBox( 0L ), m_comboBox( 0L )
{
}

KInputDialog::KInputDialog( const QString &caption, const QString &label,
    const QString &value, QWidget *parent, const char *name,
    QValidator *validator )
    : KDialogBase( parent, name, true, caption, Ok|Cancel|User1, Ok, true,
    KStdGuiItem::clear() ),
    d( 0L )
{
  d = new KInputDialogPrivate();

  QFrame *frame = makeMainWidget();
  QVBoxLayout *layout = new QVBoxLayout( frame, 0, spacingHint() );

  d->m_label = new QLabel( label, frame );
  layout->addWidget( d->m_label );

  d->m_lineEdit = new KLineEdit( value, frame );
  layout->addWidget( d->m_lineEdit );

  d->m_label->setBuddy( d->m_lineEdit );

  layout->addStretch();

  if ( validator )
    d->m_lineEdit->setValidator( validator );

  connect( d->m_lineEdit, SIGNAL( textChanged( const QString & ) ),
      SLOT( slotEditTextChanged( const QString & ) ) );
  connect( this, SIGNAL( user1Clicked() ), d->m_lineEdit, SLOT( clear() ) );

  if ( value.isNull() )
  {
      enableButtonOK( false );
      enableButton( User1, false );
  }

  d->m_lineEdit->setSelection( 0, value.length() );
  d->m_lineEdit->setFocus();

  slotEditTextChanged( value );
  setMinimumWidth( 350 );
}

KInputDialog::KInputDialog( const QString &caption, const QString &label,
    int value, int minValue, int maxValue, int step, int base,
    QWidget *parent, const char *name )
    : KDialogBase( parent, name, true, caption, Ok|Cancel, Ok, true ),
    d( 0L )
{
  d = new KInputDialogPrivate();

  QFrame *frame = makeMainWidget();
  QVBoxLayout *layout = new QVBoxLayout( frame, 0, spacingHint() );

  d->m_label = new QLabel( label, frame );
  layout->addWidget( d->m_label );

  d->m_intSpinBox = new KIntSpinBox( minValue, maxValue, step, value,
      base, frame );
  layout->addWidget( d->m_intSpinBox );

  layout->addStretch();

  setMinimumWidth( 300 );
}

KInputDialog::KInputDialog( const QString &caption, const QString &label,
    double value, double minValue, double maxValue, double step, int decimals,
    QWidget *parent, const char *name )
    : KDialogBase( parent, name, true, caption, Ok|Cancel, Ok, true ),
    d( 0L )
{
  d = new KInputDialogPrivate();

  QFrame *frame = makeMainWidget();
  QVBoxLayout *layout = new QVBoxLayout( frame, 0, spacingHint() );

  d->m_label = new QLabel( label, frame );
  layout->addWidget( d->m_label );

  d->m_doubleSpinBox = new KDoubleSpinBox( minValue, maxValue, step, value,
      decimals, frame );
  layout->addWidget( d->m_doubleSpinBox );

  layout->addStretch();

  setMinimumWidth( 300 );
}

KInputDialog::KInputDialog( const QString &caption, const QString &label,
    const QStringList &list, int current, bool editable, QWidget *parent,
    const char *name )
    : KDialogBase( parent, name, true, caption, Ok|Cancel|User1, Ok, true,
    KStdGuiItem::clear() ),
    d( 0L )
{
  d = new KInputDialogPrivate();

  showButton( User1, editable );

  QFrame *frame = makeMainWidget();
  QVBoxLayout *layout = new QVBoxLayout( frame, 0, spacingHint() );

  d->m_label = new QLabel( label, frame );
  layout->addWidget( d->m_label );

  d->m_comboBox = new KComboBox( editable, frame );
  d->m_comboBox->insertStringList( list );
  d->m_comboBox->setCurrentItem( current );
  layout->addWidget( d->m_comboBox );

  layout->addStretch();

  if ( editable )
  {
    connect( this, SIGNAL( textChanged( const QSring & ) ),
      SLOT( updateClearButton( const QString & ) ) );
    connect( this, SIGNAL( user1Clicked() ),
      d->m_comboBox, SLOT( clearEdit() ) );
  }

  setMinimumWidth( 300 );
}

KInputDialog::KInputDialog( const QString &caption, const QString &label,
    const QStringList &list, const QStringList &select, bool multiple,
    QWidget *parent, const char *name )
    : KDialogBase( parent, name, true, caption, Ok|Cancel, Ok, true ),
    d( 0L )
{
  d = new KInputDialogPrivate();

  QFrame *frame = makeMainWidget();
  QVBoxLayout *layout = new QVBoxLayout( frame, 0, spacingHint() );

  d->m_label = new QLabel( label, frame );
  layout->addWidget( d->m_label );

  d->m_listBox = new KListBox( frame );
  d->m_listBox->insertStringList( list );
  layout->addWidget( d->m_listBox );

  QListBoxItem *item;

  if ( multiple )
  {
    d->m_listBox->setSelectionMode( QListBox::Extended );

    for ( QStringList::ConstIterator it=select.begin(); it!=select.end(); ++it )
    {
      item = d->m_listBox->findItem( *it, CaseSensitive|ExactMatch );
      if ( item )
        d->m_listBox->setSelected( item, true );
    }
  }
  else
  {
    connect( d->m_listBox, SIGNAL( doubleClicked( QListBoxItem * ) ),
      SLOT( slotOk() ) );

    QString text = select.first();
    item = d->m_listBox->findItem( text, CaseSensitive|ExactMatch );
    if ( item )
      d->m_listBox->setSelected( item, true );
  }

  d->m_listBox->ensureCurrentVisible();

  layout->addStretch();

  setMinimumWidth( 300 );
}

KInputDialog::~KInputDialog()
{
  delete d;
}

QString KInputDialog::getText( const QString &caption, const QString &label,
    const QString &value, bool *ok, QWidget *parent, const char *name,
    QValidator *validator )
{
  KInputDialog *dlg = new KInputDialog( caption, label, value, parent, name,
    validator );

  bool _ok = ( dlg->exec() == Accepted );

  if ( ok )
    *ok = _ok;

  QString result;
  if ( _ok )
    result = dlg->lineEdit()->text();

  delete dlg;
  return result;
}

int KInputDialog::getInteger( const QString &caption, const QString &label,
    int value, int minValue, int maxValue, int step, int base, bool *ok,
    QWidget *parent, const char *name )
{
  KInputDialog *dlg = new KInputDialog( caption, label, value, minValue,
    maxValue, step, base, parent, name );

  bool _ok = ( dlg->exec() == Accepted );

  if ( ok )
    *ok = _ok;

  int result=0;
  if ( _ok )
    result = dlg->intSpinBox()->value();

  delete dlg;
  return result;
}

int KInputDialog::getInteger( const QString &caption, const QString &label,
    int value, int minValue, int maxValue, int step, bool *ok,
    QWidget *parent, const char *name )
{
  return getInteger( caption, label, value, minValue, maxValue, step, 
    10, ok, parent, name );
}

double KInputDialog::getDouble( const QString &caption, const QString &label,
    double value, double minValue, double maxValue, double step, int decimals,
    bool *ok, QWidget *parent, const char *name )
{
  KInputDialog *dlg = new KInputDialog( caption, label, value, minValue,
    maxValue, step, decimals, parent, name );

  bool _ok = ( dlg->exec() == Accepted );

  if ( ok )
    *ok = _ok;

  double result=0;
  if ( _ok )
    result = dlg->doubleSpinBox()->value();

  delete dlg;
  return result;
}

double KInputDialog::getDouble( const QString &caption, const QString &label,
    double value, double minValue, double maxValue, int decimals,
    bool *ok, QWidget *parent, const char *name )
{
  return getDouble( caption, label, value, minValue, maxValue, 0.1, decimals,
    ok, parent, name );
}

QString KInputDialog::getItem( const QString &caption, const QString &label,
    const QStringList &list, int current, bool editable, bool *ok,
    QWidget *parent, const char *name )
{
  KInputDialog *dlg = new KInputDialog( caption, label, list, current,
    editable, parent, name );

  bool _ok = ( dlg->exec() == Accepted );

  if ( ok )
    *ok = _ok;

  QString result;
  if ( _ok )
    result = dlg->comboBox()->currentText();

  delete dlg;
  return result;
}

QStringList KInputDialog::getItemList( const QString &caption,
    const QString &label, const QStringList &list, const QStringList &select,
    bool multiple, bool *ok, QWidget *parent, const char *name )
{
  KInputDialog *dlg = new KInputDialog( caption, label, list, select,
    multiple, parent, name );

  bool _ok = ( dlg->exec() == Accepted );

  if ( ok )
    *ok = _ok;

  QStringList result;

  for ( unsigned int i=0; i<list.count(); ++i )
    if ( dlg->listBox()->isSelected( i ) )
      result.append( dlg->listBox()->text( i ) );

  return result;
}

void KInputDialog::slotEditTextChanged( const QString &text )
{
  bool on;
  if ( lineEdit()->validator() ) {
    QString str = lineEdit()->text();
    int index = lineEdit()->cursorPosition();
    on = ( lineEdit()->validator()->validate( str, index )
      == QValidator::Acceptable );
  } else {
    on = !text.isEmpty();
  }

  enableButtonOK( on );

  updateClearButton( text );
}

void KInputDialog::updateClearButton( const QString &text )
{
  enableButton( User1, !text.isEmpty() );
}

KLineEdit *KInputDialog::lineEdit() const
{
  return d->m_lineEdit;
}

KIntSpinBox *KInputDialog::intSpinBox() const
{
  return d->m_intSpinBox;
}

KDoubleSpinBox *KInputDialog::doubleSpinBox() const
{
  return d->m_doubleSpinBox;
}

KComboBox *KInputDialog::comboBox() const
{
  return d->m_comboBox;
}

KListBox *KInputDialog::listBox() const
{
  return d->m_listBox;
}

#include "kinputdialog.moc"

/* vim: set ai et sw=2 ts=2
*/

["kinputdialog.h" (text/x-chdr)]

/*
  Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.
*/

#ifndef KINPUTDIALOG_H
#define KINPUTDIALOG_H

class QValidator;

class KLineEdit;
class KIntSpinBox;
class KDoubleSpinBox;
class KComboBox;
class KInputDialogPrivate;

#include <kdialogbase.h>

/**
 * The KInputDialog class provides a simple dialog to get a single value
 * from the user. The value can be a string, a number (either an integer or
 * a float) or an item from a list. This class is designed to be source
 * compatible with @ref QInputDialog.
 *
 * Four static convenience functions are provided: getText(), getInteger().
 * getFloat() and getItem().
 *
 * @author Nadeem Hasan <nhasan@kde.org>
 */
class KInputDialog : public KDialogBase
{
  Q_OBJECT

  private:

    /**
     * Constructor. This class is not designed to be instantiated except
     * from the static member functions.
     */
    KInputDialog( const QString &caption, const QString &label,
      const QString &value, QWidget *parent, const char *name,
      QValidator *validator );
    KInputDialog( const QString &caption, const QString &label, int value,
      int minValue, int maxValue, int step, int base, QWidget *parent,
      const char *name );
    KInputDialog( const QString &caption, const QString &label, double value,
      double minValue, double maxValue, double step, int decimals,
      QWidget *parent, const char *name );
    KInputDialog( const QString &caption, const QString &label,
      const QStringList &list, int current, bool editable, QWidget *parent,
      const char *name );
    KInputDialog( const QString &caption, const QString &label,
      const QStringList &list, const QStringList &select, bool editable,
      QWidget *parent, const char *name );

    ~KInputDialog();

    KLineEdit *lineEdit() const;
    KIntSpinBox *intSpinBox() const;
    KDoubleSpinBox *doubleSpinBox() const;
    KComboBox *comboBox() const;
    KListBox *listBox() const;

  private slots:

    void slotEditTextChanged( const QString& );
    void updateClearButton( const QString& );

  public:

    /**
     * Static convenience function to get a string from the user.
     *
     * caption is the text that is displayed in the title bar. label is the
     * text that appears as a label for the line edit. value is the initial
     * value of the 
     * line edit. ok will be set to true if user pressed Ok and false if
     * user pressed Cancel.
     *
     * If you provide a validator, the Ok button is disabled as long as
     * the validator doesn't return Acceptable. If there is no validator,
     * the Ok button is enabled whenever the line edit isn't empty. If you
     * want to accept empty input, create a trivial @ref QValidator that
     * always returns acceptable, e.g. @ref QRegExpValidator with a regexp
     * of ".*".
     *
     * @param caption   Caption of the dialog
     * @param label     Text of the label for the line edit
     * @param value     Initial value of the line edit
     * @param ok        This bool would be set to true if user pressed Ok
     * @param parent    Parent of the dialog widget
     * @param name      Name of the dialog widget
     * @param validator Validator to be associated with the line edit
     *
     * @return String user entered if Ok was pressed, else a null string
     */
    static QString getText( const QString &caption, const QString &label,
        const QString &value=QString::null, bool *ok=0, QWidget *parent=0,
        const char *name=0, QValidator *validator=0 );

    /**
     * Static convenience function to get an integer from the user.
     *
     * caption is the text that is displayed in the title bar. label is the
     * text that appears as the label for the spin box. value is the initial
     * value for the spin box. minValue and maxValue are the minimum and
     * maximum allowable values the user may choose. step is the amount by
     * which the value will change as the user presses the increment and
     * decrement buttons of the spin box.
     *
     * @param caption  Caption of the dialog
     * @param label    Text of the label for the spin box
     * @param value    Initial value of the spin box
     * @param minValue Minimum value user can input
     * @param maxValue Maximum value user can input
     * @param step     Amount by which value is incremented or decremented
     * @param ok       This bool would be set to true if user pressed Ok
     * @param parent   Parent of the dialog widget
     * @param name     Name of the dialog widget
     *
     * @return Number user entered if Ok was pressed, else 0
     */

    static int getInteger( const QString &caption, const QString &label,
        int value=0, int minValue=-2147483647, int maxValue=2147483647,
        int step=1, int base=10, bool *ok=0, QWidget *parent=0,
        const char *name=0 );

    /**
     * This is an overloaded convenience function. It behaves exactly same as
     * above except it assumes base to be 10, i.e. accepts decimal numbers.
     */
    static int getInteger( const QString &caption, const QString &label,
        int value=0, int minValue=-2147483647, int maxValue=2147483647,
        int step=1, bool *ok=0, QWidget *parent=0, const char *name=0 );

    /**
     * Static convenience function to get a floating point number from the user.
     *
     * caption is the text that is displayed in the title bar. label is the
     * text that appears as the label for the spin box. value is the initial
     * value for the spin box. minValue and maxValue are the minimum and
     * maximum allowable values the user may choose. step is the amount by
     * which the value will change as the user presses the increment and
     * decrement buttons of the spin box. Base is the base of the number.
     *
     * @param caption  Caption of the dialog
     * @param label    Text of the label for the spin box
     * @param value    Initial value of the spin box
     * @param minValue Minimum value user can input
     * @param maxValue Maximum value user can input
     * @param step     Amount by which value is incremented or decremented
     * @param base     Base of the number
     * @param ok       This bool would be set to true if user pressed Ok
     * @param parent   Parent of the dialog widget
     * @param name     Name of the dialog widget
     *
     * @return Number user entered if Ok was pressed, else 0
     */
    static double getDouble( const QString &caption, const QString &label,
        double value=0, double minValue=-2147483647, 
        double maxValue=2147483647, double step=0.1, int decimals=1,
        bool *ok=0, QWidget *parent=0, const char *name=0 );

    /**
     * This is an overloaded convenience function. It behaves exctly like
     * the above function.
     */
    static double getDouble( const QString &caption, const QString &label,
        double value=0, double minValue=-2147483647, 
        double maxValue=2147483647, int decimals=1, bool *ok=0,
        QWidget *parent=0, const char *name=0 );

    /**
     * Static convenience function to let the user select an item from a
     * combobox. caption is the text that is displayed in the title bar.
     * label is the text that appears as the label for the combobox. list
     * is the string list which is inserted into the combobox, and current
     * is the number of the item which should be the selected item. If 
     * editable is true, the user can enter their own text.
     *
     * @param caption  Caption of the dialog
     * @param label    Text of the label for the spin box
     * @param list     List of item for user to choose from
     * @param current  Index of the selected item
     * @param editable If true, user can enter the text in the combobox
     * @param ok       This bool would be set to true if user pressed Ok
     * @param parent   Parent of the dialog widget
     * @param name     Name of the dialog widget
     *
     * @return Text of the current item, or if @p editable is true, the 
     *         current text of the combobox.
     */
    static QString getItem( const QString &caption, const QString &label,
        const QStringList &list, int current=0, bool editable=false,
        bool *ok=0, QWidget *parent=0, const char *name=0 );

    /**
     * Static convenience function to let the user select one or more
     * items from a listbox. caption is the text that is displayed in the
     * title bar. label is the text that appears as the label for the listbox.
     * list is the string list which is inserted into the listbox, select
     * is the list of item(s) that should be the selected. If multiple is 
     * true, the user can select multiple items.
     *
     * @param caption  Caption of the dialog
     * @param label    Text of the label for the spin box
     * @param list     List of item for user to choose from
     * @param select   List of item(s) that should be selected
     * @param multiple If true, user can select multiple items
     * @param ok       This bool would be set to true if user pressed Ok
     * @param parent   Parent of the dialog widget
     * @param name     Name of the dialog widget
     *
     * @return List of selected items if multiple is true, else currently
     *         selected item as a @ref QStringList
     */
    static QStringList getItemList( const QString &caption,
        const QString &label, const QStringList &list=QStringList(),
        const QStringList &select=0, bool multiple=false, bool *ok=0,
        QWidget *parent=0, const char *name=0 );

  private:

    KInputDialogPrivate *d;
    friend class KInputDialogPrivate;
};

#endif // KINPUTDIALOG_H

/* vim: set ai et sw=2 ts=2
*/

["kinputdialogtest.cpp" (text/x-c__src)]

/*
 * Author:  Nadeem Hasan <nhasan@kde.org>
 * License: GPL V2
 */

#include <kapplication.h>
#include <kinputdialog.h>
#include <kdebug.h>

#include <qstring.h>
#include <qvalidator.h>

int main( int argc, char *argv[] )
{
  KApplication app( argc, argv, "kinputdialogtest" );

  bool ok;
  QString svalue;
  int ivalue;
  double dvalue;

  svalue = KInputDialog::getText( "_caption", "_label:", "_value", &ok );
  kdDebug() << "value1: " << svalue << ", ok: " << ok << endl;

  svalue = KInputDialog::getText( "_caption", "_label:", "_value", &ok, 0L, 0L,
    &QRegExpValidator( QRegExp( "[0-9]{3}\\-[0-9]{3}\\-[0-9]{4}" ), 0L ) );
  kdDebug() << "value2: " << svalue << ", ok: " << ok << endl;

  ivalue = KInputDialog::getInteger( "_caption", "_label:", 64, 0, 255,
    16, 16, &ok );
  kdDebug() << "value3: " << ivalue << ", ok: " << ok << endl;

  ivalue = KInputDialog::getInteger( "_caption", "_label:", 100, 0, 255,
    10, 10, &ok );
  kdDebug() << "value4: " << ivalue << ", ok: " << ok << endl;

  dvalue = KInputDialog::getDouble( "_caption", "_label:", 10, 0, 100, 0.1,
    2, &ok );
  kdDebug() << "value5: " << dvalue << ", ok: " << ok << endl;

  dvalue = KInputDialog::getDouble( "_caption", "_label:", 10, 0, 100, 2, &ok );
  kdDebug() << "value6: " << dvalue << ", ok: " << ok << endl;

  QStringList list, slvalue;
  list << "Item 1" << "Item 2" << "Item 3" << "Item 4" << "Item 5";
  svalue = KInputDialog::getItem( "_caption", "_label:", list, 1, false, &ok );
  kdDebug() << "value7: " << svalue << ", ok: " << ok << endl;

  svalue = KInputDialog::getItem( "_caption", "_label:", list, 1, true, &ok );
  kdDebug() << "value8: " << svalue << ", ok: " << ok << endl;

  QStringList select;
  select << "Item 3";
  list << "Item 6" << "Item 7" << "Item 8" << "Item 9" << "Item 10";
  slvalue = KInputDialog::getItemList( "_caption", "_label:", list, select,
    false, &ok );
  kdDebug() << "value9: " << slvalue << ", ok: " << ok << endl;

  select << "Item 5";
  slvalue = KInputDialog::getItemList( "_caption", "_label:", list, select,
    true, &ok );
  kdDebug() << "value10: " << slvalue << ", ok: " << ok << endl;
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic