// pageSize.h
//
// Part of KVIEWSHELL - A framework for multipage text/gfx viewers
//
// (C) 2002 Stefan Kebekus
// Distributed under the GPL

// Add header files alphabetically

#ifndef PAGESIZE_H
#define PAGESIZE_H

#include <qobject.h>

class QString;
class QStringList;

/** This class represents page sizes. It accepts page sizes in various
    formats, e.g. as a string "DIN A4", or by specifiying the page
    width and height. The class can handle several units (Inch,
    Millimeters, Centimeters), ensures that data is in a meaningful
    range and provides locale-depending defaults.

    @short Class for storing/retrieving a page size.
    @author Stefan Kebekus <kebekus@kde.org>
    @version 1.0 0
*/

class pageSize : public QObject
{
Q_OBJECT

public:
  /** Initializs the pageSize with a default which depends on the
      locale. */
  pageSize();

  /** Returns all possible names of known paper sizes. These can be
      used e.g. by a QComboBox to let the user choose known sizes. The
      returned list is also a list of all possible return values of
      the formatName() method explained below. If you call
      pageSizeNames(void) more than once, it is guaranteed that the
      same list of strings will be returned. */
  QStringList pageSizeNames(void);

  /** Set page size by name. If the name is not one of the strings
      returned by pageSizeNames(), and not of type "300x500" ,the
      input is silently ignored, and a default value (which depends on
      the locale) is used. In any case, if a value like "300x500" is
      accepted, the values will be trimmed so as not to exceed the
      minima/maxima. */
  void        setPageSize(QString name);

  /** Sets the page size to "width" and "heigt", given in the
      associated units. If a unit is not recognized, "mm" is siliently
      assumed. If width or height does not contain a number, the
      result is an undefined value. However, it is guaranteed in any
      case, that both width and heigt are between the minimal and
      maximal possible values. */
  void        setPageSize(QString width, QString widthUnits, QString height, QString heightUnits);

  /** Returns the name of the unit (currently one of "cm", "mm" or
      "in") which is most commonly used with the current page
      format. For instance, US Letter and US Legal are best given in
      inches, to avoid very odd numbers. If the page format is
      unknown, returns a guess based on the current locale. */
  QString     preferredUnit(void);

  /** Returns a string containing a number which gives the page width
      in the given unit. Here unit must be one of "cm", "mm" or
      "in". If the unit is not recognized, "mm" is siliently
      assumed. */
  QString     widthString(QString unit);

  /** Returns the page width in millimeters. */
  double       pageWidth_in_mm(void) {return pageWidth;};

  /** Analogue to the widthString() method. */
  QString     heightString(QString unit);

  /** Returns the page height in millimeters. */
  double       pageHeight_in_mm(void) {return pageHeight;};

  /** Returns a name for the current format, or QString::null, if the
      format does not have a name. If the result is not QString::null,
      it is guaranteed to be one of the strings returned by the
      pageSizeNames(void) method. */
  QString     formatName(void);

  /** Returns a number which describes the current format. If the
      number is non-negative, is points to the string with the same
      number outputted by the pageSizeNames(void) method. If it is -1,
      this means that the current format is not known by any
      name. Other values will never be returned. */
  int         formatNumber(void) {return currentSize;};

  /** Similar to the formatName() method, only that this method
      returns a string like "210x297" rather than QString::null, if
      the format does not have a proper name. The numbers are page
      width and height in millimeters. The setPageSize(QString) method
      will understand this output. */
  QString     serialize(void);

signals:
  /** emitted to indicate that the size changed. Not emitted
      immediately after construction, when the constructor sets the
      default size. */
  void sizeChanged(float width, float height);

private:
  /** Makes sure that pageWidth and pageHeight are in the permissible
      range and not, e.g., negative. */
  void        rectifySizes(void);

  /** Tries to find one of the known sizes which matches pageWidth and
      pageHeigt, with an error margin of 2 millimeters. If found, the
      value of currentsize is set to point to the known size, and
      pageWidth and pageHeight are set to the correct values for that
      size. Otherwise, currentSize is set to -1 to indicate "custom
      size". */
  void        reconstructCurrentSize(void);

  /** Gives a default value for currentSize, which depends on the
      locale. In countries with metric system, this will be "DIN A4",
      in countries with the imperial system, "US Letter". */
  int         defaultPageSize(void);

  /** Permissible range: 0--#Size_of_array staticList, or -1 to
      indicate a "user defined setting". Other values may lead to a
      segfault. */
  int currentSize;

  double pageWidth;  // in mm
  double pageHeight; // in mm
};

#endif
