/* -*- C++ -*-
 * This file declares a widget for navigating through sets of data.
 * 
 * the K Desktop Environment
 * copyright:  (C) Mirko Sucker, 1999
 * mail to:    Mirko Sucker <mirko.sucker@unibw-hamburg.de>
 * requires:   recent C++-compiler, at least Qt 1.4, STL
 
 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.
 
 * $Revision: 1.4 $
 */
#ifndef KDATANAVIGATOR_H
#define KDATANAVIGATOR_H

#include <qframe.h>
#include <qsize.h>

class QPushButton;
class QLineEdit;
class QSpinBox;
class QComboBox;
class QStringList;
class QGridLayout;

/** The class KDataNavigator provides a widget for navigating through
 *  sets of data. <BR>
 *  A KDataNavigator consists of six elements, some of them are
 *  displayed mandatory: <OL>
 *  <LI> A button displaying an icon for switching to the first element.
 *       If it is clicked, ::first() is emitted. </LI>
 *  <LI> A button displaying an icon for switching to the previous element.
 *       If it is clicked, ::previous() is emitted. </LI>
 *  <LI> A central element displaying a description of the current item.
 *       This element might be in either a lineedit, a combobox or a spinbox.
 *       The selected mode determines the type of the central element.
 *       The available modes are:
 *       <OL>
 *       <LI> The most simple mode is the \e manual mode. In this mode, the
 *       programmer that uses the class in his programs has to enable or disable
 *       the buttons when the first or the last element has been selected. The
 *       only help the class provides is the notification on button clicks since
 *       the program does not know about your first or last elements. The
 *       displayed text must be set using the ::setText() method. The central
 *       element is a non-editable lineedit.</LI>
 *       <LI> 
 *       The second mode is the \e index mode. In index mode, the central element
 *       is a spinbox showing
 *       an integer number that is the index of the current element, and that is
 *       automatically updated when one of the navigation buttons is clicked.
 *       Call ::setIndexMode() to enable this mode, giving the range of element
 *       indices and the current index. If the user enters a number in the
 *       lineedit, the signal ::itemSelected() is emitted. All input is
 *       automatically validated by the class. The buttons are enabled or
 *       disabled according to the position in the data set, that means that
 *       the \e previous and the \e first buttons are disabled when the first
 *       element is displayed. </LI>
 *       <LI>
 *       The third mode is called list mode. In list mode, you define a list
 *       of values that is displayed in a combobox (as the central element).
 *       The class allows the user to navigate through the elements in the list,
 *       thereby automatically enabling or disabling the buttons that are
 *       useless. <BR> </LI> </OL> </LI>
 *  <LI> A button displaying an icon for switching to the next element.
 *       If it is clicked, ::next() is emitted. </LI>
 *  <LI> A button displaying an icon for switching to the last element.
 *       If it is clicked, ::last() is emitted. </LI>
 *  <LI> A button displaying an icon for creating a new element.
 *       If it is clicked, ::newItem() is emitted. This button might be hidden
 *       using the method ::showButtonNew(). Make sure you update the range for
 *       the indizes if a new item is really added! </LI> </OL>
 *  The look of the widget heavily depends on the size of it. Thus you should
 *  respect its ::sizeHint() or at least the preferred height, since the central
 *  lineedit might be stretched horizontally. */

class KDataNavigator : public QFrame
{
  // ############################################################################
  Q_OBJECT
  // ----------------------------------------------------------------------------
public:
  /** The three possible operation modes. */
  enum Modes {
    Index, /**< Index mode. */
    List, /**< List mode. */
    Manual /**< Mode for manual insertion of text. */
  };
  /** The Qt standard constructor. */
  KDataNavigator(QWidget* parent=0, const char* name=0);
  ~KDataNavigator(); /**< The destructor. */
  // QSize sizeHint(); /**< The size hint. The button width is fixed to 20. */
  void setMode(Modes mode); /**< Select the mode the widget operates in. */
  /** Set the text of the central lineedit in text mode. If you call ::setText(),
   *  the index mode is disabled. */
  void setText(const char*);
  /** Set the list of strings displayed in the combobox in list mode. */
  void setList(QStringList*);
  /** Enable index mode, giving the range and the current elements index.
   *  If \e state is false, index mode is disabled. */
  void setIndexMode(int begin, int end, int current);
  /** Hide or show the button for creating a new item. */
  void showButtonNew(bool state);
  void enableButtonFirst(bool state); /**< Hide or show button \e first. */
  void enableButtonNext(bool state); /**< Hide or show button \e next. */
  void enableButtonPrevious(bool state); /**< Hide or show button \e previous. */
  void enableButtonLast(bool state); /**< Hide or show button \e last. */
  void enableButtonNew(bool state); /**< Hide or show button \e new. */
  // ----------------------------------------------------------------------------
signals:
  void first(); /**< Button \e first has been pressed. */
  void previous(); /**< Button \e previous has been pressed. */
  void next(); /**< Button \e next has been pressed. */
  void last(); /**< Button \e last has been pressed. */
  void newItem(); /**< Button \e new \e item has been pressed. */
  void itemSelected(int); /**< The item with the given index has been selected.*/
  void textChanged(const QString&); /**< Emitted in manual mode. */
  // ----------------------------------------------------------------------------
protected:
  // ----- events:
  // void resizeEvent(QResizeEvent*); /**< The resize event. */
  void setLayout(); /**< \internal */
  void enableButtons(); /**< \internal */
  // ----- members:
  QPushButton *buttonFirst; /**< The button for selecting the first element. */
  QPushButton *buttonPrevious; /**< The button for selecting the previous element. */
  QPushButton *buttonNext; /**< The button for selecting the next element. */
  QPushButton *buttonLast; /**< The button for selecting the last element. */
  QPushButton *buttonNew; /**< The button for inserting a new element. */
  QLineEdit *leIndex; /**< The lineedit displayed in manual mode. */
  QSpinBox *sbIndex; /**< The spin box displayed in index mode. */
  QComboBox *cbIndex; /**< The combobox display in list mode. */
  int min; /**< The smallest possible index. */
  int max; /**< The largest possible index. */
  int current; /**< The current index. */
  Modes mode; /**< The selected mode (default: Manual). */
  bool buttonNewVisible; /**< Wether the \e new button is displayed. */
  QGridLayout *layout; /**< Layout manager for this widget. */
  // ----------------------------------------------------------------------------
protected slots:
  void buttonFirstClicked(); /**< \internal */
  void buttonPreviousClicked(); /**< \internal */
  void buttonNextClicked(); /**< \internal */
  void buttonLastClicked(); /**< \internal */
  void buttonNewClicked(); /**< \internal */
  void leTextChanged(const QString&); /**< \internal */
  void sbValueChanged(int); /**< \internal */
  void cbItemSelected(int); /**< \internal */
  // ############################################################################
};

#endif // KDATANAVIGATOR_H
